自定義型別:結構體
阿新 • • 發佈:2019-02-20
一、 結構體宣告
struct tag//結構體型別名稱
{
member-list;//成員變數
}variable-list;//結構體變數
- 省略結構體型別名稱(匿名結構體型別)
當省略掉結構體型別名稱時,就不能省略掉結構體變數,這樣是不合理的,所以一般我們不建議省略結構體型別名
struct
{
int a;
int b;
}x,y;//全域性變數
struct
{
int a;
int b;
}a[20],*p;
int main()
{
p=&x;//不合法程式碼
return 0;
}
注意:對於結構體而言,即使兩個結構體成員完全一樣,但依然是兩種型別,其定義的變數不能互相指向
注意:一個結構體只能指向自身結構體型別所定義的變數
2.省略結構體變數
完全可以,如下段程式碼:
struct A
{
int a;
int b;
};
int main()
{
struct A s;
retuurn 0;//區域性變數
}
二.結構體成員
結構體成員可以是變數、陣列、指標、甚至其他結構體成員
- 結構體成員訪問
結構體變數訪問成員 通過點操作符(.)訪問
結構體指標訪問成員通過指向操作符(->)訪問
struct A
{
char name[10];
int b;
};
int main()
{
struct A x;
struct A *p;
p=&x;
x.a=10;
(*P).a=20;
p->name[1]='a';
return 0;
}
三、結構體的自引用
如下段程式碼,這樣的結構體自引用是錯誤的,因為定義一個變數必先開闢空間,而我們不知道struct A的空間大小
struct A
{
char name[10];
int b;
struct A obj;
};
如果我們非要自己應用自己呢?
如下段程式碼,是正確的結構體自引用方式,要自引用就必須引用自身變數的指標(因為指標不管是什麼型別都佔四個位元組大小的空間)
struct A
{
char name[10];
int b;
struct A *obj;
};
注意,如下程式碼
typedef關鍵字是定義一個新的型別。
當typedef定義結構體時,結構體被定義後才能使用,如下兩段程式碼(第一段錯誤程式碼,第二段正確程式碼):
typedef struct
{
char name[10];
int b;
node *obj;
}node;
typedef struct node
{
char name[10];
int b;
node *obj;
}node;//node代表一種型別
四、結構的不完整宣告
struct B;//不完整宣告
struct A
{
int a;
struct B *pb;
};
struct B
{
int b;
struct A *pb;
};
五、結構體變數的定義和初始化
結構體變數的初始化和陣列的初始化是一樣的只允許集體初始化,但是不允許集體賦值
#include<stdio.h>
struct Point
{
int x;
int y;
}p1;//宣告型別的時候同時定義變數p1
struct Node
{
int data;
struct Point p;
struct Node *next;
};
int main()
{
struct Point p2;//定義結構體變數p2
struct Point p3 = { 1, 2 };//初始化:定義變數的同時賦值
struct Node n1 = { 20, { 5, 6 }, NULL };//結構體巢狀初始化
struct Node n2;
//n2 = { 20, { 5, 7 }, NULL };//錯誤程式碼(結構體不可以被整體賦值)
system("pause");
return 0;
}
六、結構體記憶體對齊
對結構體瞭解到這裡,你一定很好奇怎麼計算結構體的大小,這個時候出現了結構體記憶體對齊問題,為什麼會出現記憶體對齊呢?感興趣的同學可以自己百度瞭解一下,下來我們來看一看。
結構體對齊規則:
- 第一個成員在與結構體變數偏移量為0的地址處
- 其他成員變數要對齊到某個數字(對齊數)的整數倍的地址處。對齊數=編譯器預設的一個對齊數和成員大小中的較小值。(vs中預設值為8,Linux預設值為4)
- 結構體總大小為最大對齊數(每個成員都有一個對齊數)的整數倍
- 如果嵌套了結構體的情況,巢狀的結構體對齊到自己的最大對齊數的整數被處,結構體的整數大小就是所有最大對齊數(含巢狀結構體的對齊數)的整數倍。
#include<stdio.h>
#pragma pack(8)//設定預設對齊數
struct S1
{
char c1;
int i;
char c2;
};
int main()
{
printf("%d\n", sizeof(struct S1));
system("pause");
return 0;
}
#include<stdio.h>
#pragma pack(8)//設定預設對齊數
struct S1
{
double d;
char c;
int i;
};
struct S2
{
char c1;
struct S1 s1;//最大對齊數是8
double d;
};
int main()
{
printf("%d\n", sizeof(struct S2));
system("pause");
return 0;
}