1. 結(jié)構(gòu)體介紹
C語言里的結(jié)構(gòu)體是可以包含不同數(shù)據(jù)類型和相同數(shù)據(jù)類型的一個(gè)有序集合,屬于構(gòu)造類型,可以自己任意組合,并且結(jié)構(gòu)體里也可以使用結(jié)構(gòu)體類型作為成員。
結(jié)構(gòu)體在項(xiàng)目開發(fā)中使用非常多,無處不在,有了結(jié)構(gòu)體類型就可以設(shè)計(jì)很多框架,模型,方便數(shù)據(jù)傳輸,存儲(chǔ)等等。
結(jié)構(gòu)體定義語法
struct 結(jié)構(gòu)體名稱
{
數(shù)據(jù)類型1 成員名1;
數(shù)據(jù)類型2 成員名2;
數(shù)據(jù)類型3 成員名3;
.....
};
結(jié)構(gòu)體的名稱命名規(guī)則: 和普通變量命名規(guī)則一樣—遵循C語言變量命名標(biāo)準(zhǔn)。
‘A’~‘Z’ ‘a(chǎn)’~ ’z’ ‘0’~’9’ _
示例代碼:
struct app
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
};
上面這一塊代碼表示定義(聲明)一個(gè)新的結(jié)構(gòu)體類型。 數(shù)據(jù)類型名稱:struct app
2. 如何使用結(jié)構(gòu)體定義變量?
結(jié)構(gòu)體定義變量有3種形式:
#include
//第一種形式:在定義結(jié)構(gòu)體類型的時(shí)候同時(shí)定義變量
struct app1
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
}a1,a2,a3; //a1 a2 a3就是定義的結(jié)構(gòu)體變量
//第二種形式
struct app2
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
};
//第三種形式: 匿名方式定義結(jié)構(gòu)體
struct
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
}c1,c2,c3; //c1 c2 c3就是定義的結(jié)構(gòu)體變量
int main()
{
//使用結(jié)構(gòu)體類型定義變量
struct app2 b1;
struct app2 b2;
struct app2 b3;
return 0;
}
3. 結(jié)構(gòu)體的賦值
結(jié)構(gòu)體變量的賦值語法:
結(jié)構(gòu)體變量名.成員名=xxx;
結(jié)構(gòu)體初始化賦值說明:
結(jié)構(gòu)體只能在(定義結(jié)構(gòu)體變量的時(shí)候)初始化的時(shí)候支持整體賦值,之后就只能按照成員單個(gè)賦值。
注意:結(jié)構(gòu)體變量之間支持直接賦值。
#include
#include
//第一種形式:在定義結(jié)構(gòu)體類型的時(shí)候同時(shí)定義變量
struct app1
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
}a1={23,"小白",5678},a2,a3={12,"小明",1234}; //a1 a2 a3就是定義的結(jié)構(gòu)體變量
//第二種形式
struct app2
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
};
int main()
{
//使用結(jié)構(gòu)體類型定義變量
struct app2 b1={15,"小李",6878};
struct app2 b2;
struct app2 b3;
//單個(gè)修改結(jié)構(gòu)體成員變量的值
b1.age=18;
//b1.name="555";
strcpy(b1.name,"小麗");
printf("b1:%d\n",b1.age);
printf("b1:%s\n",b1.name);
printf("a1:%d\n",a1.age);
printf("a1:%s\n",a1.name);
//結(jié)構(gòu)體變量之間支持直接賦值 (要保證變量的類型要一致)。
//int a=100;
//int b;
//b=a;
b2=b1; //將b1結(jié)構(gòu)體變量賦值給b2結(jié)構(gòu)體變量
printf("b2:%d\n",b2.age);
printf("b2:%s\n",b2.name);
return 0;
}
4. 結(jié)構(gòu)體指針定義與使用
示例代碼:
#include
#include
#include
struct app
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
};
int main()
{
struct app a1; //定義一個(gè)結(jié)構(gòu)體變量
struct app *p1; //定義一個(gè)結(jié)構(gòu)體指針
struct app *p2; //定義一個(gè)結(jié)構(gòu)體指針
p1=&a1; //地址賦值 p1指向a1的空間
//申請(qǐng)堆空間
p2=malloc(sizeof(struct app));
//通過指針訪問成員
p1->age=20;
strcpy(p1->name,"小紅");
p1->number=1234;
//輸出數(shù)據(jù)
printf("姓名:%s\n",p1->name);
printf("學(xué)號(hào):%d\n",p1->number);
printf("年齡:%d\n",p1->age);
//通過指針訪問成員
p2->age=13;
strcpy(p2->name,"小李");
p2->number=5678;
//輸出數(shù)據(jù)
printf("姓名:%s\n",p2->name);
printf("學(xué)號(hào):%d\n",p2->number);
printf("年齡:%d\n",p2->age);
//釋放空間
free(p2);
return 0;
}
5. 結(jié)構(gòu)體數(shù)組定義與使用
示例代碼:
#include
#include
#include
struct app
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
};
int main()
{
//定義一個(gè)結(jié)構(gòu)體數(shù)組
struct app buff[10]; //一次定義了10個(gè)結(jié)構(gòu)體變量
struct app *p=buff; //定義一個(gè)結(jié)構(gòu)體指針
//訪問成員
buff[0].age=10;
strcpy(buff[0].name,"小米");
buff[0].number=1234;
//打印數(shù)據(jù)
printf("姓名:%s\n",buff[0].name);
printf("學(xué)號(hào):%d\n",buff[0].number);
printf("年齡:%d\n",buff[0].age);
printf("姓名:%s\n",p[0].name);
printf("學(xué)號(hào):%d\n",p[0].number);
printf("年齡:%d\n",p[0].age);
return 0;
}
6. 結(jié)構(gòu)體當(dāng)做函數(shù)的形參和返回值
示例代碼:
#include
#include
#include
struct app
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
};
struct app *func_stu(struct app *p);
int main()
{
//定義一個(gè)結(jié)構(gòu)體數(shù)組
struct app buff[10]; //一次定義了10個(gè)結(jié)構(gòu)體變量
//調(diào)用函數(shù)
func_stu(&buff[0]);
//打印數(shù)據(jù)
printf("姓名:%s\n",buff[0].name);
printf("學(xué)號(hào):%d\n",buff[0].number);
printf("年齡:%d\n",buff[0].age);
return 0;
}
//定義函數(shù)
struct app *func_stu(struct app *p)
{
//訪問成員
p->age=10;
strcpy(p->name,"小米");
p->number=1234;
return p;
}
7. typedef關(guān)鍵字在結(jié)構(gòu)體里使用方法
#include
#include
#include
typedef struct app
{
int age; //年齡
char name[100]; //姓名
int number; //學(xué)號(hào)
}STU; //STU叫結(jié)構(gòu)體類型,相當(dāng)于struct app的別名。 struct app == STU
STU *func_stu(STU *p);
int main()
{
//定義一個(gè)結(jié)構(gòu)體數(shù)組
STU buff[10]; //一次定義了10個(gè)結(jié)構(gòu)體變量
//調(diào)用函數(shù)
func_stu(&buff[0]);
//打印數(shù)據(jù)
printf("姓名:%s\n",buff[0].name);
printf("學(xué)號(hào):%d\n",buff[0].number);
printf("年齡:%d\n",buff[0].age);
return 0;
}
//定義函數(shù)
STU *func_stu(STU *p)
{
//訪問成員
p->age=10;
strcpy(p->name,"小米");
p->number=1234;
return p;
}
8. 結(jié)構(gòu)體位域
位域用的不多,但是也有地方使用,主要是節(jié)省空間。
#include
struct app
{
unsigned int a:12; //定義位域,指定位寬 12的單位是位
unsigned int b:16;
unsigned char c:1; //定義空間存儲(chǔ)1位的數(shù)據(jù)。 1和0
unsigned int :5; //位域的名稱可以省略掉,為了空間內(nèi)存對(duì)齊而存在的
};
/*
1. 位域的大小不能超出本來數(shù)據(jù)類型大小。
2. 位域的名稱可以省略掉,為了空間內(nèi)存對(duì)齊而存在的
3. 位域的成員無法取地址操作
*/
int main()
{
struct app data;
//data.c=2; 錯(cuò)誤 超出范圍 只能存放0~1
//data.b=65535; 錯(cuò)誤 超出范圍 只能存放0~65535
// data.a=4096; 錯(cuò)誤 超出范圍 只能存放0~65535
//printf("%d\n",data.c);
// printf("%d\n",data.b);
//printf("%d\n",data.a);
//printf("%d\n",&data.a); //錯(cuò)誤 位域的成員無法取地址操作
data.c=1;
data.b=555; //只能存放0~65535
data.a=888; //只能存放0~65535
printf("%d\n",data.c);
printf("%d\n",data.b);
printf("%d\n",data.a);
return 0;
}
9. 結(jié)構(gòu)體的內(nèi)存對(duì)齊
9.1 示例1: 計(jì)算結(jié)構(gòu)體內(nèi)存對(duì)齊
#include
struct app
{
int a1;
char a2;
char a3;
char a4;
char a5;
char a6;
char a7;
};
/*
目前32位系統(tǒng)里,使用的是gcc編譯器。
開空間的對(duì)齊原理:以結(jié)構(gòu)體里出現(xiàn)的最大數(shù)據(jù)類型的倍數(shù)開空間,最大是4個(gè)字節(jié)。
*/
int main()
{
struct app data;
printf("空間大小:%d 字節(jié)\n",sizeof(struct app)); //8
return 0;
}
//func("1",1123,45,"45",123.45,'A');
void func(char *p,...)
{
}
9.2 示例2: 計(jì)算結(jié)構(gòu)體內(nèi)存對(duì)齊
#include
#if 0
struct app
{
char a1; //1
short a2; //2
};
最終占用空間大小4個(gè)字節(jié)
#endif
#if 0
struct app
{
int a1[10]; //4*10=40
char a2[10]; //12
int a3; //4
float a4; //4
char a5; //4
};
//最終占用空間大小64個(gè)字節(jié)
#endif
#if 1
struct app
{
int a1;
double a2;
};
//最終占用空間大小64個(gè)字節(jié)
#endif
/*
目前32位系統(tǒng)里,使用的是gcc編譯器。
開空間的對(duì)齊原理:以結(jié)構(gòu)體里出現(xiàn)的最大數(shù)據(jù)類型的倍數(shù)開空間,最大是4個(gè)字節(jié)。
*/
int main()
{
struct app data;
printf("空間大小:%d 字節(jié)\n",sizeof(struct app)); //8
return 0;
}
//func("1",1123,45,"45",123.45,'A');
void func(char *p,...)
{
}
9.3 輸出結(jié)構(gòu)體變量成員的地址,查看空間對(duì)齊情況
#include
struct app
{
int a1[10]; //4*10=40
char a2[10]; //12
int a3; //4
float a4; //4
char a5; //4
};
//最終占用空間大小64個(gè)字節(jié)
int main()
{
struct app data;
//輸出地址 查看空間對(duì)齊原理
printf("%#x\n",data.a1);
printf("%#x\n",data.a2);
printf("%#x\n",&data.a3);
printf("%#x\n",&data.a4);
printf("%#x\n",&data.a5);
return 0;
}
9.4 對(duì)齊結(jié)構(gòu)體進(jìn)行強(qiáng)制對(duì)齊
#include
#pragma pack(1) //1 2 4 8
struct app
{
int a1[10]; //4*10=40
char a2[10]; //1*10=10
int a3; //4
float a4; //4
char a5; //1
};
int main()
{
struct app data;
//輸出地址 查看空間對(duì)齊原理
printf("%#x\n",data.a1);
printf("%#x\n",data.a2);
printf("%#x\n",&data.a3);
printf("%#x\n",&data.a4);
printf("%#x\n",&data.a5);
printf("%d\n",sizeof(struct app));
return 0;
}
-
C語言
+關(guān)注
關(guān)注
180文章
7614瀏覽量
137800 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
130瀏覽量
10872
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
C語言中數(shù)組和結(jié)構(gòu)體的內(nèi)存表示和布局
用C語言的結(jié)構(gòu)體實(shí)現(xiàn)字節(jié)、位操作
430編程C語言常識(shí)(IAR)之結(jié)構(gòu)體與聯(lián)合體
【武漢華嵌】結(jié)構(gòu)體的sizeof問題
C結(jié)構(gòu)體之位域位段
漫談C語言結(jié)構(gòu)體
位域是怎樣去定義的
在c語言中的位域(位段)是如何去定義的?有哪些限制呢
C語言結(jié)構(gòu)體之位域位段
C語言中的位域是什么?
C語言之位域使用
![<b class='flag-5'>C</b><b class='flag-5'>語言</b>之<b class='flag-5'>位</b><b class='flag-5'>域</b>使用](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評(píng)論