簡體   English   中英

C“ int”的大小是2個字節還是4個字節?

[英]Is the size of C “int” 2 bytes or 4 bytes?

C中的Integer變量占用2個字節還是4個字節? 它取決於哪些因素?

大多數教科書都說整數變量占用2個字節。 但是,當我運行一個程序打印整數數組的連續地址時,它顯示出4的差。

我知道它等於sizeof(int) 一個int的大小實際上取決於編譯器。 過去,當處理器為16位時, int為2字節。 如今,在32位和64位系統上,通常為4字節。

盡管如此,對於要在其上執行程序的特定系統,使用sizeof(int)是獲取整數大小的最佳方法。

編輯:修復了在大多數64位系統上int為8字節的錯誤語句。 例如,在64位GCC上為4字節。

這是C語言中一開始可能會造成混淆的要點之一,但是C標准僅指定了保證可以支持的整數類型的最小范圍 保證int能夠容納-32767到32767,這需要16位。 在這種情況下, int是2個字節。 但是,實現可以自由地超出該最小值,因為您會看到許多現代編譯器將int 32位(這也意味着4字節無處不在)。

您的書說2個字節的原因很可能是因為它太舊了。 曾經這是常態。 通常,如果需要找出正在使用的平台上的字節數,則應始終使用sizeof運算符。

為了解決這個問題,C99添加了新的類型,您可以在其中明確要求特定大小的整數,例如int16_tint32_t 在此之前,沒有通用的方法來獲取特定寬度的整數(盡管大多數平台在每個平台上都提供相似的類型)。

沒有具體答案。 這取決於平台。 它是實現定義的。 它可以是2、4或其他。

int背后的想法是,它應該與給定平台上的自然“字”大小匹配:在16位平台上為16位,在32位平台上為32位,在64位平台上為64位, 。 但是,出於向后兼容的目的,某些編譯器甚至在64位平台上也傾向於使用32位int

除非您正在使用某些具有16位字長的嵌入式平台,否則2字節int的時間已經很久了(16位平台?)。 您的教科書可能很舊。

該問題的答案取決於您使用的平台。
但是無論平台如何,都可以可靠地假定以下類型:

 [8-bit] signed char: -127 to 127
 [8-bit] unsigned char: 0 to 255
 [16-bit]signed short: -32767 to 32767
 [16-bit]unsigned short: 0 to 65535
 [32-bit]signed long: -2147483647 to 2147483647
 [32-bit]unsigned long: 0 to 4294967295
 [64-bit]signed long long: -9223372036854775807 to 9223372036854775807
 [64-bit]unsigned long long: 0 to 18446744073709551615

C中的Integer變量占用2個字節還是4個字節?

這取決於您使用的平台以及編譯器的配置方式。 唯一的權威答案是使用sizeof運算符來查看特定情況下整數的大小。


它取決於哪些因素?

最好考慮范圍 ,而不是大小 兩種方法在實踐中都會有所不同,盡管我們會看到,按范圍選擇變量類型比選擇大小要容易得多。 還需要注意的是,該標准鼓勵我們考慮基於范圍而不是大小來選擇整數類型,但現在讓我們忽略標准做法 ,並讓我們好奇地探索sizeof ,字節和CHAR_BIT以及整數表示...讓我們鑽進兔子洞,親眼看看...


sizeof ,字節和CHAR_BIT

以下聲明取自C標准(鏈接至上文),以我認為無法改進的語言來描述。

sizeof運算符產生其操作數的大小(以字節為單位),該操作數可以是表達式或類型的括號名稱。 大小由操作數的類型確定。

假定您有一個清晰的認識,將使我們進入有關字節的討論。 通常假設一個字節為八位,而實際上CHAR_BIT告訴您一個字節中有多少位 那只是在談論常見的兩個(或四個)字節整數時不考慮的細微差別之一。

到目前為止,讓我們總結一下:

  • sizeof =>大小(以字節為單位),以及
  • CHAR_BIT =>字節中的位數

因此,根據您的系統, sizeof (unsigned int)可以是大於零的任何值(不只是2或4),就像CHAR_BIT為16一樣,則單個(十六位)字節中有足夠的位來表示標准描述的16位整數(如下所述)。 那不一定是有用的信息,是嗎? 讓我們深入研究...


整數表示

C標准在此處為所有標准整數類型(以及CHAR_BIT ,也稱為fwiw)指定最小精度/范圍。 由此,我們可以得出需要多少位來存儲的價值 最低 ,但我們可能也只是選擇基於范圍我們的變量。 但是,此答案所需的大部分細節都位於此處。 例如,標准unsigned int需要(至少)十六位存儲以下內容:

 UINT_MAX 65535 // 2¹⁶ - 1 

因此,我們可以看到unsigned int需要( 至少 )16位 ,這是您獲得兩個字節的地方 (假設CHAR_BIT為8)……后來,當該限制增加到2³² - 1 ,人們則改為聲明4個字節。 這解釋了您觀察到的現象:

大多數教科書都說整數變量占用2個字節。 但是,當我運行一個程序打印整數數組的連續地址時,它顯示出4的差。

您使用的是古老的教科書和編譯器,它在教您非便攜式C語言; 編寫您的教科書的作者甚至可能都不知道CHAR_BIT 應該升級您的教科書(和編譯器),並努力記住IT是一個不斷發展的領域,您需要在競爭中保持領先地位 讓我們看看這些底層整數字節還存儲了其他哪些非便攜式機密...

值位是常見的誤解似乎正在計數的內容。 上面的示例使用了一個unsigned整數類型,該類型通常僅包含值位,因此很容易在細節上漏掉魔鬼。

符號位 ...在上面的示例中,我引用UINT_MAX作為unsigned int上限,因為這是從注釋中提取值16的簡單示例。 對於有符號類型,為了區分正值和負值(即符號),我們還需要包括符號位。

 INT_MIN -32768 // -(2¹⁵) INT_MAX +32767 // 2¹⁵ - 1 

填充位 ...雖然遇到整數填充位整數的計算機並不常見,但C標准允許這種情況發生。 一些機器(例如, 台機器)通過將兩個較小的(帶符號的)整數值組合在一起來實現較大的整數類型……當您組合帶符號的整數時,會浪費符號位。 在C中,該浪費的位被認為是填充 。填充位的其他示例可能包括奇偶校驗位和陷阱位


如您所見,該標准似乎鼓勵選擇整數類型時考慮INT_MIN .. INT_MAX類的范圍以及該標准中的其他最小/最大值 ,並且不鼓勵依賴於大小,因為還有可能INT_MAX其他細微的因素,例如CHAR_BIT和可能影響sizeof (int)值的填充位(即,對兩字節和四字節整數的常見誤解忽略了這些細節)。

C99 N1256標准草案

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

int的大小和所有其他整數類型是實現定義的,C99僅指定:

  • 最小尺寸保證
  • 類型之間的相對大小

5.2.4.2.1“整數類型<limits.h>的大小”給出了最小大小:

1 [...]其實現定義的值的大小(絕對值)應等於或大於所顯示的值。

  • UCHAR_MAX 255 // 2 8 − 1
  • USHRT_MAX 65535 // 2 16 − 1
  • UINT_MAX 65535 // 2 16 − 1
  • ULONG_MAX 4294967295 // 2 32 − 1
  • ULLONG_MAX 18446744073709551615 // 2 64 − 1

6.2.5“類型”然后說:

8對於具有相同符號和不同整數轉換等級的任何兩個整數類型(請參見6.3.1.1),具有較小整數轉換等級的類型的值的范圍是另一種類型的值的子范圍。

6.3.1.1“布爾值,字符和整數”確定相對轉換等級:

1每個整數類型都有一個整數轉換等級,定義如下:

  • long long int的等級應大於long int的等級,后者應大於int的等級,后者應大於short int的等級,后者應大於有符號字符的等級。
  • 任何無符號整數類型的等級應等於相應的有符號整數類型的等級(如果有)。
  • 對於所有整數類型T1,T2和T3,如果T1的等級高於T2,並且T2的等級高於T3,則T1的等級高於T3

唯一的保證是char必須至少為 8位寬, shortint必須至少為 16位寬, long必須至少為 32位寬,並且sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long) sizeof (int) sizeof (long)對於那些類型的無符號版本也是如此)。

根據平台的不同, int寬度可能在16到64位之間。

通常它取決於您使用的平台。它取決於編譯器。現在,在大多數編譯器中, int4個字節 如果要檢查編譯器在使用什么,可以使用sizeof(int)

main()
{
    printf("%d",sizeof(int));
    printf("%d",sizeof(short));
    printf("%d",sizeof(long));
}

C編譯器唯一保證的是short的大小必須等於或小於int,long的大小必須等於或大於int。因此,如果int的大小為4,則short的大小可能為2或4,但不能更大不僅如此,長期以來也是如此。 它還說,短和長的大小不能相同。

C“ int”的大小是2個字節還是4個字節?

答案是“是” /“否” /“也許” /“也許不是”。

C編程語言指定以下內容:最小的可尋址單元,由char已知,也稱為“字節” ,恰好是CHAR_BIT位寬,其中CHAR_BIT至少為8。

因此,C中的一個字節不一定是八位字節 ,即8位。 在過去,第一個運行C代碼(和Unix)的平台具有4字節的int ,但是int總共有36位,因為CHAR_BIT為9!

對於平台范圍至少為-32767 ... 32767的平台, int應該是自然整數大小。 您可以使用sizeof(int)獲得平台字節中int的大小; 當將此值乘以CHAR_BIT您將知道它的位數。


盡管36位計算機大多數情況下都死定了,但仍有一些平台使用非8位字節。 就在昨天, 有關一個具有16位字節的Texas Instruments MCU的問題,該MCU具有 C99,C11兼容編譯器。

TMS320C28x上charshortint似乎都是 16位寬,因此是一個字節。 long int是2個字節, long long int是4個字節。 C的美麗之處在於,人們仍然可以為這樣的平台編寫高效的程序,甚至可以以可移植的方式完成它!

這取決於實現,但是通常取決於x86和其他流行的體系結構(如ARM int占用4個字節。 您始終可以在編譯時使用sizeof(int)或要檢查的任何其他類型進行檢查。

如果要確保使用特定大小的類型,請使用<stdint.h>的類型

#include <stdio.h>

int main(void) {
    printf("size of int: %d", (int)sizeof(int));
    return 0;
}

返回4,但可能與機器有關。

C“ int”的大小是2個字節還是4個字節?

C中的Integer變量占用2個字節還是4個字節?

C允許“字節”不是每個“字節” 8位。

CHAR_BIT不是位字段的最小對象的位數(字節)C11dr§5.2.4.2.11

大於8的值越來越少見。 為了獲得最大的可移植性,使用CHAR_BIT而不是8的的大小int在C sizeof(int) * CHAR_BIT

#include <limits.h>
printf("(int) Bit size %zu\n", sizeof(int) * CHAR_BIT);

它取決於哪些因素?

int位的大小通常為32或16位。 C指定的最小范圍

int類型INT_MIN -32767的對象的INT_MIN
int INT_MAX +32767類型的對象的INT_MAX
C11dr§5.2.4.2.11

int最小范圍 int位大小至少為 16-即使處理器為“ 8位”。 在專用處理器中可以看到類似64位的大小。 其他值(例如18、24、36等)已經出現在歷史平台上,或者至少在理論上是可能的。 現代編碼很少擔心非2次冪int位大小。

計算機的處理器和體系結構驅動int位大小的選擇。

但是即使使用64位處理器,出於兼容性原因,編譯器的int大小也可能是32位,因為大型代碼庫取決於int是32位(或32/16)。

這是回答此問題的良好來源。

但是這個問題總是回答“是的,兩者都是”。

這取決於您的體系結構。 如果要在16位以下的計算機上工作,則不能為4字節(= 32位)。 如果您使用的是32位或更高版本的計算機,則其長度為32位。

為了弄清楚,讓您的程序准備好輸出可讀的內容並使用“ sizeof”功能。 這將返回聲明的數據類型的大小(以字節為單位)。 但是要對數組使用此技巧。

如果您要聲明int t[12]; 它將返回12 * 4字節。 要獲得此數組的長度,只需使用sizeof(t)/sizeof(t[0]) 如果要構建一個函數,該函數應該計算發送數組的大小,請記住,如果

typedef int array[12];
int function(array t){
    int size_of_t = sizeof(t)/sizeof(t[0]);
    return size_of_t;
}
void main(){
    array t = {1,1,1};  //remember: t= [1,1,1,0,...,0]
    int a = function(t);    //remember: sending t is just a pointer and equal to int* t
   print(a);   // output will be 1, since t will be interpreted as an int itselve. 
}

因此,這甚至不會返回不同的東西。 如果定義數組,然后嘗試獲取長度,請使用sizeof。 如果將數組發送給函數,請記住發送值只是第一個元素上的指針。 但是,在第一種情況下,您始終知道陣列的大小。 可以通過定義兩個函數來找出情況二,而會損失一些性能。 定義函數(數組t)和函數2(數組t,int size_of_t)。 調用“ function(t)”通過一些復制工作來測量長度,然后將結果發送到function2,您可以在其中對可變數組大小執行任何操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM