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的空間
//申請堆空間
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)存對齊而存在的
};
/*
1. 位域的大小不能超出本來數(shù)據(jù)類型大小。
2. 位域的名稱可以省略掉,為了空間內(nèi)存對齊而存在的
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)存對齊
9.1 示例1: 計(jì)算結(jié)構(gòu)體內(nèi)存對齊
#include
struct app
{
int a1;
char a2;
char a3;
char a4;
char a5;
char a6;
char a7;
};
/*
目前32位系統(tǒng)里,使用的是gcc編譯器。
開空間的對齊原理:以結(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)存對齊
#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編譯器。
開空間的對齊原理:以結(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)體變量成員的地址,查看空間對齊情況
#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;
//輸出地址 查看空間對齊原理
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 對齊結(jié)構(gòu)體進(jìn)行強(qiáng)制對齊
#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;
//輸出地址 查看空間對齊原理
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;
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報(bào)投訴
-
C語言
+關(guān)注
關(guān)注
183文章
7644瀏覽量
145643 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
131瀏覽量
11374
發(fā)布評論請先 登錄
相關(guān)推薦
熱點(diǎn)推薦
位域解讀
只用1個(gè)bit就能夠放完,而一個(gè)整型卻是4個(gè)字節(jié),也就是32bit。這就造成了內(nèi)存的浪費(fèi)。
好在,C語言為我們提供了一種數(shù)據(jù)結(jié)構(gòu),稱為「位域
發(fā)表于 12-05 06:45
什么是位域
有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié), 而只需占幾個(gè)或一個(gè)二進(jìn)制位。
例如在存放一個(gè)開關(guān)量時(shí),只有0和1 兩種狀態(tài), 用一位二進(jìn)位即可。為了節(jié)省存儲(chǔ)空間,并使處理簡便,C語言
發(fā)表于 12-15 08:07
用C語言的結(jié)構(gòu)體實(shí)現(xiàn)字節(jié)、位操作
用C語言的結(jié)構(gòu)體實(shí)現(xiàn)字節(jié)、位操作結(jié)構(gòu)化程序設(shè)計(jì)是編寫清晰、正確和易于修改的程序。而對于大多數(shù)編程
發(fā)表于 09-21 09:25
430編程C語言常識(shí)(IAR)之結(jié)構(gòu)體與聯(lián)合體
z4 : 4; }; z = 0xFFFF; a = z1; b = z2; c = z3; 復(fù)制代碼結(jié)果:a = 1, b = 3, c = 7; (4)結(jié)構(gòu)體中的
發(fā)表于 11-22 15:43
C結(jié)構(gòu)體之位域位段
有些信息在存儲(chǔ)時(shí),并不需要占用一個(gè)完整的字節(jié), 而只需占幾個(gè)或一個(gè)二進(jìn)制位。例如在存放一個(gè)開關(guān)量時(shí),只有0和1 兩種狀態(tài), 用一位二進(jìn)位即可。為了節(jié)省存儲(chǔ)空間,并使處理簡便,C語言又提
發(fā)表于 12-10 20:35
漫談C語言結(jié)構(gòu)體
相信大家對于結(jié)構(gòu)體都不陌生。在此,分享出本人對c語言結(jié)構(gòu)體的學(xué)習(xí)心得。如果你發(fā)現(xiàn)這個(gè)總結(jié)中有
發(fā)表于 11-15 15:59
位域是怎樣去定義的
一、位域描述存放一個(gè)開關(guān)量或者其他開關(guān)狀態(tài)時(shí),用一位二進(jìn)位即可。為了減少嵌入式內(nèi)存資源的開銷,可以使用位域進(jìn)行定義,
發(fā)表于 12-15 07:47
在c語言中的位域(位段)是如何去定義的?有哪些限制呢
在c語言中提供一個(gè)一種叫 “位域” 或者 “位段” 的數(shù)據(jù)結(jié)構(gòu)。它的存在是為了更加的節(jié)省空間。因
發(fā)表于 07-01 15:52
C語言結(jié)構(gòu)體之位域位段
所謂"位域"是把一個(gè)字節(jié)中的二進(jìn)位劃分為幾個(gè)不同的區(qū)域,并說明每個(gè)區(qū)域的位數(shù)。每個(gè)域有一個(gè)域名,允許在程序中按域名進(jìn)行操作。這樣就可以把幾個(gè)不同的對象用一個(gè)字節(jié)的二進(jìn)制位
C語言中的位域是什么?
位域是什么? 有些數(shù)據(jù)在存儲(chǔ)時(shí)并不需要占用一個(gè)完整的字節(jié),只需要占用一個(gè)或幾個(gè)二進(jìn)制位即可。例如開關(guān)只有通電和斷電兩種狀態(tài),用 0 和 1 表示足以,也就是用一個(gè)二進(jìn)位。正是基于這種考慮,C
C語言之位域使用
在單片機(jī)的編程中,會(huì)使用到一些IC里面的寄存器,而有些寄存器并不是每一位都是有效的,例如:這里的1-3位則是保留的,不可以被操作的。所以在對一些寄存器進(jìn)行操作時(shí),可以利用C語言的
發(fā)表于 01-12 20:47
?6次下載
C語言入門之結(jié)構(gòu)體指針
在C語言中,指向結(jié)構(gòu)體對象的指針變量既可以指向結(jié)構(gòu)體變量,也可指向
C語言-結(jié)構(gòu)體與位域
評論