1.結(jié)構(gòu)體內(nèi)存分析
- 1.結(jié)構(gòu)體存儲(chǔ)原理
- 內(nèi)存是以字節(jié)為單位編號(hào),但一些硬件平臺(tái)對(duì)某些特定類型的數(shù)據(jù)只能從某些特定地址開(kāi)始, 比如從偶地址開(kāi)始。若不按照適合其平臺(tái)的要求對(duì)數(shù)據(jù)存放進(jìn)行對(duì)齊,會(huì)影響到效率。 因此,在內(nèi)存中,各類型的數(shù)據(jù)是按照一定的規(guī)則在內(nèi)存中存放的,這就是對(duì)齊問(wèn)題。
- 結(jié)構(gòu)體占用的內(nèi)存空間是每個(gè)成員占用的字節(jié)數(shù)之和(考慮對(duì)齊問(wèn)題)
- 2.結(jié)構(gòu)體變量占用存儲(chǔ)空間大小
注:定義結(jié)構(gòu)體類型不分配存儲(chǔ)空間,定義變量時(shí)才分配存儲(chǔ)空間
- 規(guī)則一:找到結(jié)構(gòu)體中占用字節(jié)數(shù)最大的類型,假設(shè)其占用的字節(jié)數(shù)為8,每次開(kāi)辟新的存儲(chǔ)空間都增加8.
- 規(guī)則二:結(jié)構(gòu)體中每條數(shù)據(jù)按定義類型時(shí)的順序存儲(chǔ),一條數(shù)據(jù)能存的下就往里存,存不下就開(kāi)辟新的內(nèi)存空間
??:
#include <stdio.h>
int main(int argc, const char * argv[]) {
//定義結(jié)構(gòu)體類型,這里的結(jié)構(gòu)體類型Person中,占用字節(jié)數(shù)最大的數(shù)據(jù)類型為double(64位編譯器下占用8個(gè)字節(jié)),在存儲(chǔ)score、height、age時(shí),存儲(chǔ)空間不夠的情況下,每次都會(huì)新開(kāi)辟8個(gè)字節(jié).
/*
struct Person {
short score;
int age;
double height;
};
//定義結(jié)構(gòu)體變量
struct Person sp = {99,18,178.0};
printf("調(diào)整順序前------%lu\n",sizeof(sp));
*/
//調(diào)整結(jié)構(gòu)體類型數(shù)據(jù)的順序
struct Person {
short score;
double height;
int age;
};
struct Person sp = {99,178.0,18};
printf("調(diào)整順序后------%lu\n",sizeof(sp));
return 0;
}
//輸出:
調(diào)整順序前------16
調(diào)整順序后------24
存儲(chǔ)空間大小不同的原因與結(jié)構(gòu)體數(shù)據(jù)的順序有關(guān),例子中,最關(guān)鍵的是第二個(gè)數(shù)據(jù)的存儲(chǔ),調(diào)整前第二個(gè)數(shù)據(jù)為int類型,由于變量存儲(chǔ)時(shí)一次開(kāi)辟sizeof(double) = 8;short占用了其中的兩個(gè)字節(jié),剩余的6個(gè)字節(jié)能夠存儲(chǔ)int的4個(gè)字節(jié),所以不會(huì)開(kāi)辟新的存儲(chǔ)空間,而調(diào)整后第二個(gè)數(shù)據(jù)為double,剩余的6個(gè)字節(jié)不夠存儲(chǔ)double,所以開(kāi)辟了新的存儲(chǔ)空間8個(gè)字節(jié).所以調(diào)整前存儲(chǔ)一個(gè)結(jié)構(gòu)體變量需要16個(gè)字節(jié),而調(diào)整后需要24個(gè)字節(jié)
2.指向結(jié)構(gòu)體變量的指針
// 定義一個(gè)結(jié)構(gòu)體類型
struct Student {
char *name;
int age;
};
// 定義一個(gè)結(jié)構(gòu)體變量
struct Student stu = {“sj", 25};
// 定義一個(gè)指向結(jié)構(gòu)體的指針變量
struct Student *p;
// 指向結(jié)構(gòu)體變量stu
p = &stu;
/*
這時(shí)候可以用3種方式訪問(wèn)結(jié)構(gòu)體的成員
*/
// 方式1:結(jié)構(gòu)體變量名.成員名
printf("name=%s, age = %d \n", stu.name, stu.age);
// 方式2:(*指針變量名).成員名
printf("name=%s, age = %d \n", (*p).name, (*p).age);
// 方式3:指針變量名->成員名
printf("name=%s, age = %d \n", p->name, p->age);
return 0;
}