深度解說C語言中整形型別在記憶體中的
資料型別在記憶體中的大小一般不變,與32位、64位平臺無關;只有指標與平臺有關。32位平臺下,所有指標型別均佔4個位元組。 一、void型別 void型別稱為空型別(無型別),一般作為函式的返回時使用。 那麼void能否定義變數呢? 答案是否定的。因為資料型別在定義變數時最主要的功能是在記憶體中開闢空間,但在VS32位平臺作業系統下,void在記憶體中佔0個位元組,不能開闢空間,即不能定義變數。在linux作業系統下,void佔1個位元組,但沒有實際意義**,只能說明linux和VS編譯系統對void定義不同,但均不可定義變數。** 那麼問題又來了,void * 可否定義變數呢? 答案是肯定的。因為在32位平臺下,所有指標型別都佔4個位元組,故void *可以定義變數,但不可解引用。
*void 可接受任何型別。
#include<stdio.h>
#include<stdlib.h>
int main()
{
void* x;
printf("%p\n", &x);
system("pause");
return 0;
}
二、指標 1.為什麼要有指標? 便於定位查詢。 2.指標是什麼? 指標就是地址,但不放置於開闢空間內,類似於宿舍門牌號。 3.定義指標、定義指標變數 兩個定義一樣,因為指標就是資料。 變數指標=變數地址
三、char型別 char型別佔1個位元組,signed char範圍為-128—127,unsigned char範圍為0—255。
unsigned char i;
//1111 1111--- 255
signed char n;
//1000 0001---- -127
//最高位為符號位,7個數值位
//0111 1111---- 127
-128是怎麼來的呢? 當二進位制為1000 0000時,理論上為-0,但數學上並未對-0有所定義。又因資料在CPU中進行運算,將其轉移至暫存器中,暫存器會擴大空間,即為1 1000 0000,因地址為一個位元組,返回地址為1000 0000,運算得-128。 即1000 0000為-128。
四、原碼、反碼、補碼 儲存: 在32位平臺下 任何整數均已補碼形式儲存於計算機內。 計算機儲存補碼的原因: 為了便於將符號位與數值位進行統一處理,加法減法同時進行,計算機中只有CPU可進行運算,且只有加法器。
int n = -10;
//1000 0000 0000 0000 0000 0000 0000 1010 原碼
//1111 1111 1111 1111 1111 1111 1111 0101 反碼
//1111 1111 1111 1111 1111 1111 1111 0110 補碼
// F F F F F F F 6
提取: 提取首先看二進位制符號位,再看數值位。 無符號整形(32個數值位)和有符號正數(符號位為0,31個數值位)均可直接二進位制轉十進位制提取。 有符號負數符(符號位為1,31個數值位),提取需補碼減1轉反碼再轉原碼,再進行二進位制轉十進位制提取。
數字儲存、提取均由計算機進行運算。
五、大小端問題 數字有權位,例如1234,1處於數字的最高位,4處於數字的最低位。 記憶體中開闢空間,地址有高地址位和低地址位之分。 以位元組為單位,若將數字儲存於計算機中,計算機中儲存的為數字的補碼,若數字的低位儲存於低地址一端,即你的電腦為小端;反之,若數字的低位儲存於高地址一端,即你的電腦為大端。 口訣:小小小 例如:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n = -10;
//1000 0000 0000 0000 0000 0000 0000 1010 原碼
//1111 1111 1111 1111 1111 1111 1111 0101 反碼
//1111 1111 1111 1111 1111 1111 1111 0110 補碼
// F F F F F F F 6
printf("%p\n", &n);
system("pause");
return 0;
}
計算機地址儲存從上到下依次遞增,資料低位儲存於計算機低地址處,故此電腦為小端。
六、聯合體儲存
union un {
char c;
int a ;
};
聯合體儲存時計算機至少開闢的空間和最大資料型別一致,char c和int a均可視為聯合體的第一個。 此時若想判斷計算機為大小端該怎麼辦? 即定義a=1,取出c的地址,若c=1即為小端。 例如:
#include<stdio.h>
#include<stdlib.h>
union un {
char c;
int a;
};
int main()
{
union un data;
data.a = 1;
printf("%p\n", data.c);
system("pause");
return 0;
}
我的電腦為小端,與上文相符合。