1. 程式人生 > >C語言中整型的定義

C語言中整型的定義

使用C語言時,用sizeof運算int,long int,long long int時,得到的結果不盡相同。那麼這些型別長度與什麼有關?與機器?與編譯器(語言實現)?還是作業系統?我查閱了一些資料,將之總結下來,希望能有一些參考價值。也歡迎指正糾錯,共同學習!

C語言的實現一般由編譯器和標準庫開發者提供,而這部分開發者有很多,常見的編譯器有微軟的vc,GNU的gcc,Borland的TC,Intel也有自己的C編譯器。各個提供者都有自己的想法,都可能會往語言特性中加入一些新的擴充套件實現,比如一些關鍵字,一些標準沒有的標準庫函式,或是一些標準庫函式的返回值與其他的不一樣等等。但他們都會遵循C語言標準,即是我們常聽說的C99、C90/C89、C11等等。

一、C標準定義:

int型別是一個型別系列,在C語言中,基本的int 型別包括char,long,int,short,bool(_Bool關鍵字,C99)。C99標準中說明了,實現必須等於或大於<limits.h>的定義。

以下列出所有C標準中定義的型別(C99):


char: 機器上最小的地址單元。標頭檔案中對應CHAR_BIT,8 bits;

signed char:與char長度相同,範圍必須能承載至少[-127,+127],即8 bits大小,其中一位用作符號位;

unsigned char:與char長度相同,但無符號位,範圍大小為[0, 2^CHAR_BIT - 1],8 bits;

short

short int

signed short

signed short int:以上四種為帶符號的short型別,必須能承載至少[-32767, +32768]範圍,也即是至少16bits長度。

unsigned short

unsigned short int: 同short, 但無符號,長度至少16bits。

int

signed

signed int:基本的int,必須能至少承載[-32767, +32767]範圍,也即是說,至少16bits長度。

unsigned int

unsigned:同int,但無符號,長度至少16bits。

long

long int

signed long

signed long int:long 型的整數,必須能承載至少[-2147483647, +2147483647]範圍,也就是至少32bits長度。(注:只有一個long

unsigned long

unsigned long int:同long,但無符號位。

long long

long long int

signed long long

signed long long int:long long 型別,必須至少能承載[-9223372036854775807, +9223372036854775807],也就是至少64bits長度。

unsigned long long

unsigned long long int:同long long型別,沒有符號位。

二、C99的固定寬度int型別定義:

為更好的做到各個平臺相容,也給嵌入式環境更方便,從C99開始規定了<stdint.h>檔案,固定各個型別的長度,可以直接include這個標頭檔案使用這些型別

(注:貌似vc沒有這個標頭檔案,我一般到網上下,但最好還是看看vc編譯器文件,以它為準,自己寫一個。):

Type category Signed types Unsigned types
Type Minimum value Maximum value Type Minimum value Maximum value
Exact width intN_t INTN_MIN INTN_MAX uintN_t 0 UINTN_MAX
Least width int_leastN_t INT_LEASTN_MIN INT_LEASTN_MAX uint_leastN_t 0 UINT_LEASTN_MAX
Fastest int_fastN_t INT_FASTN_MIN INT_FASTN_MAX uint_fastN_t 0 UINT_FASTN_MAX
Pointer intptr_t INTPTR_MIN INTPTR_MAX uintptr_t 0 UINTPTR_MAX
Maximum width intmax_t INTMAX_MIN INTMAX_MAX uintmax_t 0 UINTMAX_MAX

三、GCC編譯器int 限制:

GCC不支援C99和C11中定義的擴充套件integer型別。除此之外其他基本型別都支援的很好。

根據C99標準中說明的:

5種標準signed integer type:signed char, short int, int, long int, long long int;

5種標準unsigned integer type:unsigned char, unsigned short int, unsigned int, unsigned long int, unsigned long long int;

四、GCC編譯器支援的各種硬體架構:

常見的架構

x86-64,或x64, AMD64(64bits);    

IA-64,Intel Itanium 64;  

ARM(32-bits,64-bits);   

SPARC(64bits);  

PowerPC(32bits,64bits);

GCC支援很多架構,而其中也有很多嵌入式系統架構。16bits、32bits或者64bits架構,那麼要實現C標準的各種int型別,首先可能需要處理器的支援,假設32bits處理器不支援64bits整形運算(很多指令集都支援),為實現C原始碼中的運算,可能需要編譯器編譯成目的碼時完成大於機器字整形資料的運算拼裝,若支援,直接編譯成相應的指令即可。

五、總結:

根據查到的這些資料,應該這麼描述,C語言中的整型與目標機器指令集有關,也與編譯器有關。但編譯器是比硬體架構更高層的東西,沒有這些指令集,也可以用一些實現來完成大於機器字長度的運算,更何況,要是編譯器在某個架構上無法實現這些運算,直接在編譯器使用者手冊上說清楚,不支援這個硬體架構即可了。整型的長度,與機器有一定關係,但主要與編譯器在當前硬體架構上的實現有關係。

六、程式碼測試:

#include <stdio.h>
#include <unistd.h>
#	define println(__S) printf ("%s\n", __S)

int main (int argc, char* argv []) {

	printf (
			"  char size = %d\n"
			"  short size = %d\n"
			"  int size = %d\n"
			"  long int size = %d\n"
			"  long size = %d\n"
			"  long long size = %d\n"
			"  long long int size = %d\n"
			"  float size = %d\n"
			"  double size = %d\n"
			"  long double size = %d\n",
			sizeof (char),
			sizeof (short),
			sizeof (int),
			sizeof (long int),
			sizeof (long),
			sizeof (long long),
			sizeof (long long int),
			sizeof (float),
			sizeof (double),
			sizeof (long double)
			);
	return 0;
}

以下是在兩種機器上執行相同C程式碼的輸出:

(1)x86_64(AMD64):

(2)AMD32:

引用出處:

GNU GCC 4.9.3 Manual :https://gcc.gnu.org/onlinedocs/gcc-4.9.3/gcc/index.html#toc_G_002b_002b-and-GCC

C標準:

(1) ANSI C standard (X3.159-1989), 釋出於 1990,之後成為ISO/IEC 9899:1990標準,C89或C90.

(2) ISO/IEC 9899:1990修正版,於1995年釋出,C94或C95

(3) ISO/IEC 9899:1999,一個新版本標準,於1999年釋出,C99

(4) ISO/IEC 9899:2011,新版本標準,於2011年釋出,C11,目前最新標準。

相關推薦

C語言定義

使用C語言時,用sizeof運算int,long int,long long int時,得到的結果不盡相同。那麼這些型別長度與什麼有關?與機器?與編譯器(語言實現)?還是作業系統?我查閱了一些資料,將之總結下來,希望能有一些參考價值。也歡迎指正糾錯,共同學習! C語言的實

10 c語言int,long,long long範圍及原碼補碼錶示

 以2位元組為例來說:對於無符號的數值(原碼及補碼都一樣),最小值是0,最大值是1111  1111  1111  1111=216-1=65535,共有216個編碼。對於有符號的來說較為複雜:1)原碼

C語言在計算機的儲存

一 . 整型的表示       1.字面值後面加上L(l)表示long長整型       2.字面值後面加上U(u)表示usigned整型值       3.十進位制123  ...       4.

C語言常量的表達方式

在C語言中,整型常量可用以下三種形式表示:1. 十進位制整數,即按日常接觸的數字形式正常表達。如123、-120;2. 八進位制整數,以0開頭的數字進行表達。如0123表示八進位制數123,即(123)

c語言實現變數內容互換

對於給定的兩個整形變數的值,將兩個值的內容進行交換的問題,從兩個方面設計解決方案,下面為具體的演算法分析及程式。 演算法一:先建立兩個整形變數,並進行初始化。同時建立一個臨時變數,通過臨時變數,從而達到交換兩個整形變數內容的目的。 #include<stdio.h> #i

C語言溢位問題 int、long、long long取值範圍 最大最小值

《C和指標》中寫過:long與int:標準只規定long不小於int的長度,int不小於short的長度。 double與int型別的儲存機制不同,long int的8個位元組全部都是資料位,而double是以尾數,底數,指數的形式表示的,類似科學計數法,因此double比i

C語言宣告和定義詳解

變數宣告和變數定義 變數定義:用於為變數分配儲存空間,還可為變數指定初始值。程式中,變數有且僅有一個定義。 變數宣告:用於向程式表明變數的型別和名字。 定義也是宣告,extern宣告不是定義 定義也是宣告:當定義變數時我們聲明瞭它的型別和

C語言宣告、定義和初始化的區別

函式和變數(全域性變數)都有宣告和定義, 對於函式而言: 同一檔案內,如果函式fun_1呼叫fun_2時,如果fun_2在fun_1之後定義,則需在fun_1之前對fun_2進行宣告,如下: void fun_2();// 宣告 void fun_1() { ... fu

C語言相乘

思路 用陣列strA,strB儲存數字,將兩個大數對應位置(i、j)上的數相乘,乘積直接放在陣列strC的第(i+j)位,待所有位置上的數都相乘後,對strC進行進位。 #include<io

C語言溢位問題

整型溢位有點老生常談了,bla, bla, bla… 但似乎沒有引起多少人的重視。整型溢位會有可能導致緩衝區溢位,緩衝區溢位會導致各種黑客攻擊,比如最近OpenSSL的heartbleed事件,就是一個buffer overread的事件。在這裡寫下這篇文章,希望大家都瞭解

c語言常量的定義(備忘錄)

A:多個編譯單元或模組公用 方法一: 在某個公用標頭檔案中將符號常量定義為static並初始化,例如: //commondef.h static const int MAX_LENGTH=1024

C語言(long long)64位耗時問題

C語言的long long型整型效能很差 今天刷OJ時偶然發現C語言long long整型資料居然耗時超過好幾百毫秒,這對於時間敏感的程式設計題是無法忍受的,故記錄此坑,留作紀念。 一.先上圖 1

C語言關於巨集定義的一點總結

1、常見的巨集定義語句有不帶引數的巨集定義和帶引數的巨集定義兩種 2、帶引數的巨集定義,在比較複雜時,往往通過\字元進行換行分割,來使其更加清晰。 比如: #include <stdio.h> #include <string.h> #defi

C語言宣告和定義的區別——分析extern關鍵詞。

一直很迷惑C語言中的宣告和定義的有些實踐中的用法,說迷惑實踐是因為宣告和定義的概念上的區別是很明確的。 定義和宣告的區別(主要針對變數): 定義是要為變數分配儲存空間,還可以在定義的時候為變數指定初始值。在一個程式中,變數有且僅有一次定義。 宣告用於向程式表明變數的型別和名

C語言結構體定義

question tps 定義類 typedef 兩個 spa c語言 ida 類型 struct test { int a; }; /* 定義一個結構體,名字是test,這樣就可以使用struct test 來定義變量。比如 struct tes

C語言溢位和移位溢位

1 整型溢位 原文連結:https://coolshell.cn/articles/11466.html     1.1 無符號整型溢位和有符號整型溢位    對於unsigned整型溢位,C的規範是有定義的——“溢位後的數會以2^(8*sizeof(type))作模運

C語言各種型別所佔位元組數

平臺: 64位編譯器+LINUX+Gcc #include<stdio.h> main() { char a; char* b; short int c; int d; unsigned int e

理解C#語言的類轉換----初學者的理解,請大神指教

寫代碼 需要 con c# 初學 har 3.1 parse 範圍 一下都是在視頻教學中學到後的理解,如果說錯了請大神指教 C#語言中的類型轉換,就是將某個數據要轉換成另一個類型的數據。 c#語言中的數據類型主要有: char類型(字符類型); string類型(字符串類型

C語言的作用域,鏈接屬性和存儲類

硬件 變量的存儲 bsp 文件的 tro 們的 沒有 聲明 一個 作用域 當變量在程序的某個部分被聲明的時候,他只有在程序的一定漁區才能被訪問,編譯器可以確認4種不同類型的作用域:文件作用域,函數作用域,代碼塊作用域和原型作用域 1.代碼塊作用域:位於一對花括號之間的所

c#語言的類轉換

寫代碼 字符串 時間 編碼 3.1 表示 編寫 需要 string 類 在使用C#用語言編寫代碼的時候,經常要切換各種數據類型。這個時候就需要用到各種數字類型之間的切換。希望這篇隨筆可以有些幫助。 常用的數據類型轉換。例如,很多時候把用戶輸入的string 類