這個問題在這里已經有了答案: 為什么 C 不運行 unsigned int 與負值的比較? (4 個回答) 11 小時前關閉。
#include <stdio.h>
int main()
{
int size = sizeof(int);
printf("%d\n", size);
if(sizeof(int) > -1)
printf("True\n");
else
printf("False\n");
return 0;
}
這段代碼給了我輸出False。但這應該是真的,因為我們都知道整數的大小是 4。
但是當我運行相同的代碼只是將sizeof(int)in 型別轉換為整數時,它給了我輸出True。
給我正確輸出的代碼:
#include <stdio.h>
int main()
{
int size = sizeof(int);
printf("%d\n", size);
if((int)(sizeof(int)) > -1)
printf("True\n");
else
printf("False\n");
return 0;
}
為什么會發生這種行為?
你能解釋一下嗎?
uj5u.com熱心網友回復:
運算子的結果sizeof型別size_t為無符號型別,因此運算式sizeof(int) > -1將有符號整數與無符號整數進行比較。
在這種情況下,兩個運算元被轉換為一個通用型別。特別是,假設 asize_t至少與 an 一樣大int(這是運算式-1的型別,有符號運算元將轉換為無符號運算元的型別。這意味著該值-1將轉換為可以存盤在a size_t,所以比較是錯誤的。
這些轉換規則稱為通常的算術轉換,在C 標準的第 6.3.1.8p1 節中有詳細說明(相關段落以粗體顯示):
許多期望算術型別的運算元的運算子會以類似的方式導致轉換和產生結果型別。目的是確定運算元和結果的通用實數型別。對于指定的運算元,每個運算元都在不改變型別域的情況下轉換為對應的實數型別是公共實數型別的型別。除非另有明確說明,否則公共實數型別也是結果的對應實數型別,如果它們相同,則其型別域是運算元的型別域,否則為復數。這種模式稱為通常的算術轉換:
- 首先,如果任一運算元的對應實數型別為 long double,則將另一個運算元轉換為對應實數型別為 long double 的型別,而不改變型別域。
- 否則,如果任一運算元的對應實數型別為雙精度,則將另一個運算元轉換為對應實數型別為雙精度的型別,而不改變型別域。
- 否則,如果任一運算元的對應實數型別為浮點數,則將另一個運算元轉換為對應實數型別為浮點數的型別,而不改變型別域。
- 否則,對兩個運算元都執行整數提升。然后將以下規則應用于提升的運算元:
- 如果兩個運算元具有相同的型別,則不需要進一步轉換。
- 否則,如果兩個運算元都具有有符號整數型別或都具有無符號整數型別,則具有較小整數轉換等級的型別的運算元將轉換為具有較高等級的運算元的型別。
- 否則,如果無符號整數型別的運算元的等級大于或等于另一個運算元型別的等級,則將有符號整數型別的運算元轉換為無符號整數型別的運算元的型別。
- 否則,如果有符號整數型別的運算元的型別可以表示無符號整數型別的運算元型別的所有值,則將無符號整數型別的運算元轉換為有符號整數型別的運算元的型別。
- 否則,兩個運算元都轉換為與帶符號整數型別的運算元型別對應的無符號整數型別。
轉換發生的機制在第 6.3.1.3p2 節中有詳細說明:
否則,如果新型別是無符號的,則通過在新型別中可以表示的最大值的基礎上反復加減一,直到該值在新型別的范圍內。
uj5u.com熱心網友回復:
由于通常的算術轉換,如果在運算式中一個運算元具有無符號整數型別而另一個具有有符號整數型別,并且無符號整數型別的等級大于或等于有符號整數型別的等級,則運算元具有有符號整數型別轉換為無符號整數型別。
在這個 if 陳述句的條件下
if(sizeof(int) > -1)
運算式sizeof( int )具有無符號型別size_t(通常對應于 type unsigned long int),其等級大于int作為整數常量型別的型別的等級-1;
因此,運算式通過傳播符號位-1被轉換為型別size_t,結果被轉換為一個非常大的無符號整數值。
這是一個演示程式
#include <stdio.h>
int main( void )
{
printf( "( int )-1 = %d\n", -1 );
printf( "( size_t )-1 = %zu\n", ( size_t )-1 );
}
程式輸出為
( int )-1 = -1
( size_t )-1 = 18446744073709551615
在第二個 if 陳述句的條件下
if((int)(sizeof(int)) > -1)
int由于將第一個運算元顯式轉換為type ,因此兩個運算元都具有帶符號的型別int。所以不會發生轉換并且運算元-1具有負值-1。
注意有細微差別。在一些實作中,無符號型別unsigned long int(或 的size_t)的大小等于有符號型別的大小signed long long int。
In 表示該型別signed long long int的物件無法表示該型別的所有值unsigned long int。
signed long long int因此,在具有型別和型別的操作數的運算式中,由于相同的常用算術轉換unsigned long int,兩個運算元都再次轉換為型別。unsigned long long int如果你會寫例如
if ( sizeof(int) > -1ll)
其中使用了型別的運算元-1ll,signed long long int其等級大于該型別的運算元的等級,size_t但是條件將再次被評估,false因為運算元-1ll將被轉換為型別unsigned long long int。
uj5u.com熱心網友回復:
您需要轉換它,因為 sizeof() 回傳位元組數,但回傳型別是無符號的,并且您試圖將其存盤在 int 型別變數中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/507324.html
上一篇:C中結構的未宣告識別符號錯誤
下一篇:如何計算可以形成的三角形的數量
