1. 程式人生 > >深度解說C語言中整形型別在記憶體中的

深度解說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可進行運算,且只有加法器。

資料型別預設為有符號。 無符號整形(unsigned int)和有符號正數(signed int)原碼、反碼、補碼一樣。 有符號負數儲存時需原碼轉反碼+1轉補碼。

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;
 }

我的電腦為小端,與上文相符合。