今天在將一個4字節大小的宏(#define (unsigned long)0x0000FFFF)強制類型轉化爲8個字節;spa
而後再左移4個字節(<<32)後;再加上這個宏自己,賦值給一個8字節的變量。產生了一些錯誤,比較典型,但願你們注意一下。指針
先貼出正確代碼:code
#include <stdlib.h> #include <string.h> #define NUM (unsigned long)0x0000FFFF int main(void) { unsigned char *Flag = NULL; int i = 0; unsigned long long ll = 0; ll = (((unsigned long long)NUM)<<32)+NUM; /*打印變量ll的內存,在打印時,能夠將變量ll的地址強制轉化爲字符指針, 而後獲取其指針指向的內存(一個字符的內存),獲取後指針++,移動一個字節*/ Flag = (unsigned char *)≪ for(i=0 ;i< 8; i++) { printf("%x ",*Flag++); } return 0; }
輸出結果:內存
ff ff 0 0 ff ff 0 0 低地址——>高地址編譯器
輸入分析:由於是運行在inter系統上,是小字節序,輸出結果順序依次是從低地址到高地址,因此其實際的數值爲 0x 00 00 FF FF 00 00 FF FFstring
犯的錯誤1:忘記「+」號優先級高於"<<"左移優先級,以下代碼,編譯
ll = ((unsigned long long)NUM)<<32 + NUM 輸出結果:0 0 0 0 0 0 0 0變量
犯的錯誤2:對數據類型的強制轉換了解不深,致使理解不了產生結果的緣由。原理
過後,對代碼進行總結與你們分享:數據類型
一、咱們若是想要打印某個內存連續的內存值(!!!!!重要)
a 首先咱們獲取內存的首地址,將其強制類型轉化爲字符指針
b 而後對指針間接引用,獲取指針指向內存的值(此時獲取的就是一個字節的內存)
c 對指針加加(++),對指針間接引用,獲取指針指向內存的值
若是想一下獲取兩個字節的內存,將內存首地址強制類型轉化爲兩個字節的指針,N個字節亦如此。
原理:指針的數據類型是告訴編譯器,我這個指針指向的內存數據時什麼數據類型,你在對我星號(*)間接取值時,就取這個數據類型大小的內存。
二、數據類型的轉化
轉化規則:位數多的數據類型-->位數少的數據類型 保留低位,捨去高位
位數少的數據類型-->位數多的數據類型 值不變
在類型轉換時,只是將內存中讀取到的值進行轉換,不會對內存的值進行修改,是臨時的(很重要)
#include <stdlib.h> #include <string.h> int main(void) { unsigned short s1 = 0; unsigned short s2 = 0; unsigned int i1 = 0; unsigned int i2 = 0; s1 = 256*256-1; i1 = s1; printf("s1= %x i1= %x \n",s1,i1); /* 輸出 s1= ffff i1= ffff*/ i2 = 256*256*256*256-1; s2 = i2; printf("i2= %x s2= %x\n",i2,s2); /* 輸出 i2= ffffffff s2= ffff 能夠明顯看出i2 (四個字節)被截成了s2(兩個字節)保留低位,捨去高位 */ }
三、基本數據類型取值範圍
整型 [signed]int -2147483648~+2147483648
無符號整型unsigned[int] 0~4294967295
短整型 short [int] -32768~32768
無符號短整型unsigned short[int] 0~65535
長整型 Long int -2147483648~+2147483648
無符號長整型unsigned [int] 0~4294967295
字符型[signed] char -128~+127
無符號字符型 unsigned char 0~255
單精度 float 3.4 x 10^(-38)~ 3.4 x 10^(+38)
雙精度double 1.7 x 10^(-308)~ 1.7 x 10^(+308)
長雙精度 long double 1.7 x 10^(-308)~ 1.7 x 10^(+308)
但願對你們有所幫助。