1、c語言中定義一個字符串: char a[6]={'l','i','n','u','x','\0'}; '\0'的字符編碼為0就是NULL;也就是說內(nèi)存中遇到0,,翻譯成字符是就是'\0',或這是NULL; char a[6]='linux'; char *p='linux'; 2,、sizeof(a)=6是運算符,其意思是所占空間大小,,包括字符串后面的‘\0',strlen(a)=5是一個函數(shù),,其意思是字符串的長度。strlen( p),;其中p只有是字符指針變量才有意義,, 它的形參是數(shù)組變量是沒有意義的,因為strlen是根據(jù)什么時候遇到 '\0',才結(jié)束測試字符串的長度,,就算數(shù)組不初始化也是有長度的,。 char *p='linux'; sizeof(p)永遠等于4,,因為p是指針變量,存的是地址,。所以總結(jié):sizeof()是拿來測數(shù)組的大小,,strlen()是拿來測試字符串的長度。 3,、結(jié)構(gòu)體用 . 或者是 ->訪問內(nèi)部變量,,其實質(zhì)是用的指針訪問。如 struct student { int a; double b; char c; }s1; 則s1.a =12;實質(zhì)就是int *p=(int *) &s1,;*p=12 首先a是int 型,,所以是強制類型 int * ,其次是就是算地址,,然后強制類型,,地址應該是int 型然后加減,不然的話,,系統(tǒng) s1.b=12.2;實質(zhì)就是double *p= (double *) ((int)&s1+4),*p=12.2; 不知道是以int 型加減還是以float型加減,,還是以char型加減,所以 應當 (int)&s1; 而且因為地址是 s1.c=c;實質(zhì)就是 char *p=(char *) ((int)&s1+12); *p=c; 4字節(jié)的,,所以必須是int型,。 加群466572167(群內(nèi)有各類型學習資料) 4、對齊方式: (1)猜測如果是32位系統(tǒng),,那么編譯器默認是4字節(jié)對齊,,64位系統(tǒng),那么編譯器默認是8字節(jié)對齊,,因為32位或64位一次性訪問效率是最高的,。 (2)<1>結(jié)構(gòu)體首地址對齊(編譯器自身幫我們保證,會給它分配一個對齊的地址,,因為結(jié)構(gòu)體自身已經(jīng)對齊了,,那么第一個變量也就自然對齊,所以我們才可以想象成第一個變量從0地址存放),; <2>結(jié)構(gòu)體內(nèi)部的各個變量要對齊,。 <3>整個結(jié)構(gòu)體要對齊,因為定義結(jié)構(gòu)體變量s1時,,再定義變量s2時,,如果s1沒有對齊,就坑了s2,所以也要保證整個結(jié)構(gòu)體對齊,。 無論是按照幾字節(jié)對齊,,我們都可以聯(lián)想到內(nèi)存實際的安排。1字節(jié)對齊那么不管int float double 類型,在每4個格子的內(nèi)存挨著存放,。2字節(jié)對齊,,也是一樣的 想法,舉一個列子,,如果第一個變量是char 型,,第二個變量是int型,那么0地址存放char型,,1地址空著,,2地址存放int型地址部分,3地址存放int型地址部分,,然后 上排最右4,、5地址存放int型高址部分。4字節(jié)對齊,,如果第一個變量是char型,第二個變量是int型,,那么0地址存放char型,,1,2,,3地址空著,,從4地址開始存放int, 最后給變量分配完內(nèi)存空間后,,必須要保證整個結(jié)構(gòu)體對齊,,下一個結(jié)構(gòu)體的存放起始地址是n字節(jié)對齊整數(shù)倍,如是4字節(jié)對齊,,那么最后short算成4字節(jié) 以保證整個結(jié)構(gòu)體對齊,。 整個結(jié)構(gòu)體對齊,如2字節(jié)對齊(2的整數(shù)倍),,只要是0,、2、4地址就行了,,如果是4字節(jié)對齊(4的整數(shù)倍),,就必須是0、4地址,。8字節(jié)對齊(8的整數(shù)倍) (3)猜測4字節(jié)/8字節(jié)其實是針對int型/double型的,,比如0地址是char型,那么4字節(jié)對齊,,int型,、float型就必須從4地址開始存放,那么8字節(jié)對齊,int型就必須從4地址存放,,double型就必須從8地址開始存放.小于幾字節(jié)對齊的那些,,如char型和short型只要能按照規(guī)則存放就行了。 (4)對齊命令:<1>需要#prgama pack(n)開頭,,以#pragma pack()結(jié)尾,,定義一個區(qū)間,這個區(qū)間內(nèi)的對齊參數(shù)就是n,。(不建議使用) 加群466572167(群內(nèi)有各類型學習資料) 如:s1占5個字節(jié),,s2占8字節(jié)(默認) #pragma pack(1) struct stu1 { (結(jié)構(gòu)體本身以及變量) 對齊規(guī)則:2字節(jié)對齊(2的整數(shù)倍),只要是0,、2,、4地址就行了, 4字節(jié)對齊(4的整數(shù)倍),,就必須是0,、4地址, 8字節(jié)對齊(8的整數(shù)倍),,就必須是0,、8、16 char c; int a; //short d; }s1; struct stu2 { char c; int a; //short d; }s2; <2>gcc推薦的對齊指令__attribute__((packed)) __attribute__((aligned(n))),,在VC中就不行,,沒有定義這個命令 (1)__attribute__((packed))使用時直接放在要進行內(nèi)存對齊的類型定義的后面,然后它起作用的范圍只有加了這個東西的這一個類型,。packed的作用就是取消對齊訪問,。 (2)__attribute__((aligned(n)))使用時直接放在要進行內(nèi)存對齊的類型定義的后面,然后它起作用的范圍只有加了這個東西的這一個類型,。它的作用是讓整個結(jié)構(gòu)體變量 整體進行n字節(jié)對齊(注意是結(jié)構(gòu)體變量整體n字節(jié)對齊,,而不是結(jié)構(gòu)體內(nèi)各元素也要n字節(jié)對齊,內(nèi)部元素按照默認對齊方式) 5,、枚舉類型(int型): 這樣寫默認從第一個常量開始是0,,1,2,,3,,4......... 也可以自己賦值,但是每一個值是不一樣的,否則邏輯上出錯,。 typedef enum workday { MON, // MON = 1; TUE, WEN, THU, FRI, }DAY; typedef enum weekend { SAT, SUN, }DAY; */ / /錯誤2,,枚舉成員重名,編譯時報錯:redeclaration of enumerator ‘MON’ typedef enum workday { MON, // MON = 1; TUE, WEN, THU, FRI, }workday; typedef enum weekend { MON, SAT, SUN, }weekend; 2>1>3>2>1> |
|