一.結構體類型windows
1.結構體變量的定義與使用數組
♦ 定義結構體變量的方式spa
• 先申明結構體類型再定義變量名指針
struct stu //stu:結構體類型名
code
{對象
成員列表blog
};排序
struct stu Lucy; //Lucy:結構體變量名內存
• 在聲明類型的同時定義變量input
struct stu //stu:結構體類型名
{
成員列表
}Lucy,Bob; //Lucy、Bob:結構體變量名
• 直接定義結構體類型變量(無類型名)
struct //無類型名
{
成員列表
}Lucy、Bob; //Lucy、Bob:結構體變量名
• 結構體類型名:指定了一個結構體類型,它至關於一個模型,但其中並沒有具體數據,系統對之也不分配實際的內存單元。
• 結構體變量名:實際分配空間——爲了能在結構體中使用結構體類型的數據,應當定義結構體類型的變量,並在其中存放具體的數據。
♦ 比較推薦的寫法
typedef struct stu
{
成員列表
}STU; //使用typedef從新定義一個結構體類型名
STU Lucy,Bob; //使用STU去定義相應的對象
類型與變量分開定義,當一個結構體類型有多個文件須要使用時,能夠將類型定義放在放在一個.h文件中,須要使用的文件包含相應的頭文件便可。
♦ 注意事項:
1.結構體變量成員必須單獨使用:結構體變量名.成員名
例如:Lucy.num = 101;
scanf("%c",&Lucy.sex);
printf("%s\n",Lucy.name);
2.具備相同類型的結構體變量能夠相互賦值,多用於結構體成員總體操做(排序等)
例如:Bob = Lucy;
3.結構體能夠在定義的時候進行初始化
例如:STU Lucy = {12,"hello",'m'};
4.容許嵌套定義結構體變量,成員引用多級引用
例如:Lucy.birthday.month = 12;
#include <stdio.h> typedef struct stu { int num; char name[10]; char sex; }STU; int main(int argc,char *argv[]) { STU boy1,boy2,girl = {15,"lucy",'w'}; printf("input boy2 num name sex:"); scanf("%d %s %c",&boy2.num,boy2.name,&boy2.sex); boy1 = boy2; printf("boy1.num = %d,boy1.name = %s,boy1.sex = %c\n",boy1.num,boy1.name,boy1.sex); printf("boy2.num = %d,boy2.name = %s,boy2.sex = %c\n",boy2.num,boy2.name,boy2.sex); printf("girl.num = %d,girl.name = %s,girl.sex = %c\n",girl.num,girl.name,girl.sex); return 0; }
2.結構體數組
♦ 結構體數組中每一個數組元素都是一個結構體類型的數據
♦ 直接定義結構體數組
struct student
{
int num;
char name[10];
int age;
}edu[2];
♦ 結構體數組的引用
edu[0].num = 10;
strcpy(edu[0].name,"Lucy");
edu[0].age = 24;
//定義一個結構體數組 #include <stdio.h> typedef struct stu { int num; char name[10]; float score; }STU; int main(int argc,char *argv[]) { STU msg[3] = { {15,"lucy",88.5}, {16,"peter",91.5}, {101,"bob",62.5} }; int i; float aver,sum = 0; for(i = 0;i < 3;i++) { sum = sum + msg[i].score; } aver = sum/3; printf("axer = %f\n",aver); return 0; }
3.結構體指針
指向結構體變量首地址的指針,經過結構體指針便可訪問該結構體變量
♦ 結構體指針變量定義:
struct 結構體名 *結構體指針變量 例如:struct student *p = &Lucy;
♦ 利用結構體指針變量訪問結構體變量的各個成員
1.Lucy.num = 101;
2.(*p).num = 101;
3.p->num = 101; //"->"稱爲指向運算符
4.(&Lucy)->num = 101;
♦ 結構體指針主要用於結構體變量傳參以及鏈表中
//利用結構體指針變量訪問結構體變量的成員 #include <stdio.h> typedef struct stu { int num; char name[10]; float score; }STU; int main(int argc,char *argv[]) { STU Lucy = {100,"Lucy",80}; STU *p = &Lucy; printf("num = %d,num = %d\n",Lucy.num,p->num); printf("name = %s,name = %s\n",Lucy.name,(*p).name); printf("score = %.2f,score = %.2f\n",Lucy.score,(&Lucy)->score); return 0; }
4.結構體的內存分配
♦ 結構體對其,默認對其原則
1.數據類型對其值:
char型數據自身對其值爲1,short爲2,int、float爲4,double(windows:8,Linux:4)
解釋:
char變量只要有一個空餘的字節便可存放
short要求首地址能被2整除
int、float、double同理
2.結構體的對其值:
其成員中自身對其值最大的那個值
解釋:
結構體最終對其按照數據成員中最長的類型的整數倍
3.分析如下結構體所佔空間大小
struct stu1 { char a; int b; short c; }STU1; //sizeof(STU1) = 12 struct stu2 { int b; char a; short c; }STU2; //sizeof(STU2) = 8 struct stu3 { char a; int b; }STU3; //sizeof(STU3) = 8
♦ 指定對其原則:使用#pragma pack改變默認對其原則
1.格式:#pragma pack(value) //value:指定對其值
• value只能是:1 2 4 8
• 指定類型值與數據類型對其值相比取較小值
例如:設爲1:則short、int、float等均爲1
設爲2:則char仍爲1,short爲2,int變爲2
2.分析一下結構體所佔空間大小
#pragma pack (1) struct stu { char a; int b; short c; }STU; //sizeof(STU) = 7 #pragma pack (8) struct stu1 { char a; int b; short c; }STU; //sizeof(STU) = 12
5.位段的使用
♦ 位段的定義
struct packed_data
{
unsigned int a:2;
unsigned int b:6;
unsigned int c:4;
unsigned int d:4;
unsigned int i;
}data; //其中a,b,c,d分別佔2位,6位,4位,4位,i爲整型佔字節(32位)
♦ 位段的使用
data.a = 2; //賦值時,不要超出位段定義的範圍;若是位段成員a定義爲2位,最大值爲3,即(11)2,因此data a = 5,就會取5的低兩位進行賦值
♦ 位段定義的重要說明
1.位段成員的類型必須指定爲整型或字符型,即char、short、int、long型,不能是浮點型,也不能定義位段數組。
2.一個位段必須存放在一個存儲單元中,不能跨兩個單元,即第一個單元空間不能容納下一個位段,則該空間不用,而從下一個單元起存放該位段
3.位段的長度不能大於存儲單元的長度。
4.若是一個位段要從下一個存儲單元開始,能夠定義:
unsigned a:1;
unsigned b:2;
unsigned :0; //長度爲0的位段,其做用是使下一個位段從下一個存儲單元開始存放,將a、b存儲在一個存儲單元中,c另存在下一個單元
unsignde c:3;(另外一個位段)
5.能夠定義無心義的位段,如:
unsigned int a: 1;
unsigned int : 2;
unsigned int b: 3;
#include <stdio.h> typedef struct { unsigned int a:1; unsigned int b:2; unsigned int c:3; }M; //sizeof(M) = 4 typedef struct b { unsigned int a:1; unsigned int b:2; unsigned int c:32; }B; //sizeof(B) = 8 int main(int argc,char *argv[]) { M k; k.a = 1; printf("k.a = %d\n",k.a); //k.a = 1 k.b = 1; printf("k.b = %d\n",k.b); //k.b = 1 // k.b = 4; // printf("k.b = %d\n",k.b); //k.b = 0 k.c = 4; printf("k.c = %d\n",k.c); //k.c = 4 // printf("k.a_len = %d\n",sizeof(k.a)); //錯誤,sizeof()是測字節長度,k.a是位段 printf("M_len = %d\n",sizeof(M)); //M = 4 printf("B_len = %d\n",sizeof(B)); //B = 12 return 0; }
二.共用體類型(聯合體類型)
♦ 共用體的定義
與結構體很是相似,有三種方式,推薦使用如下這種方式
typedef union data
{
short int num; //短整型2字節
char sex; //字符型1字節
float score; //浮點型4字節
}DATA;
DATA a,b;
♦ 共用體的引用
a.num(引用共用體變量中的整型變量num)
a.sex(引用共用體變量中的字符型變量sex)
a.score(引用共用體變量中的實型變量score)
♦ 共用體的特色
• 同一內存段能夠用來存放幾種不一樣類型的成員,但每一瞬時只能存放其中一個成員,只有一種起做用,而不是同時存放幾個。也就是說,在共用體變量中只能存放一個值。
• 共用體變量中起做用的成員是最後一次存放的成員,在存入一個新的成員後原有的成員的值會被覆蓋。
• 共用體變量的地址和它的各成員的地址都是同一地址。
• 共用體變量的初始化,但初始化表中只能有一個常量。
例如:union data a={123}; //初始化共用體爲第一個成員
• 共用體變量所佔的內存長度等於最長的成員的長度,而結構體變量所佔的內存長度是各成員佔的內存長度之和。
//共用體 #include <stdio.h> typedef union stu { char x; short int y; int z; double m; }STU; //sizeof(STU) = 8 int main(int argc,char *argv[]) { STU a={10}; union stu *p = &a; a.x = 5; a.y = 6; a.z = 15; printf("a.x+a.y = %d\n",a.x+a.y); //a.x+a.y=30,起做用的是最後一次存放的成員的值 printf("STU_len = %d\n",sizeof(STU)); //STU_len = 8,共用體變量所佔的內存長度等於最長的成員的長度 printf("p = %p\n",p); //p = 0xbfdd7c84,共用體變量的地址和它的各成員的地址都是同一地址 printf("p->x = %p\n",&(p->x)); //p->x = 0xbfdd7c84 printf("p->y = %p\n",&(p->y)); //p->y = 0xbfdd7c84 printf("p->z = %p\n",&(p->z)); //p->z = 0xbfdd7c84 printf("p->m = %p\n",&(p->m)); //p->m = 0xbfdd7c84 return 0; }
三.枚舉類型
將變量的值一一列舉出來,變量的值只限於列舉出來的值的範圍內。
♦ 枚舉類型的定義
enum 枚舉名
{
枚舉值表
};
• 在枚舉值表中應列出全部可用值,也稱爲枚舉元素。
• 枚舉變量僅能取枚舉值所列元素。
例如:enum week //week爲枚舉類型
{
sun,mon,tue,wed,thu,fri,sat //枚舉元素(枚舉常量)
};
enum week workday,weekday; //workday、weekday爲枚舉變量
• workday與weekday只能取sun……sat中的一個
例如:workday = mon; //正確
weekday = tue //正確
workday = abc //錯誤,枚舉之中沒有abc
♦ 枚舉類型的注意事項
1.枚舉值是常量,不能在程序中用賦值語句再對它賦值。
例如:sun = 5; mon = 2; thu = hel; //都是錯誤的
2.每個枚舉元素都表明一個整數,C語言在編譯時按定義時的順序默認它們的值爲0,1,2,3,……。
例如:在上面week的定義中,sun值爲0,mon值爲1,……,sat值爲6
3.能夠改變枚舉值的默認值。
例如:enum week
{
sun=3,mon,tue,wed,thu,fri,sat
}; //此時sun=3,mon=4,tue=5,……以此類推……,sat=9
4.枚舉元素能夠用來做判斷比較,枚舉元素的比較規則是按其在初始化時指定的整數來進行比較的。
例如:if(workday == mon) ......
if(workday > sun) ......
5.枚舉變量就是一整型變量。
6.枚舉也能夠定義數組。
例如:enum week a[10];
//共用體 #include <stdio.h> enum week { sun = 2,mon,tue,wed,thu,fri,sat //mon = 3,tue = 4,……,sat = 9 }a,b,c; enum bool { false,true //false = 0,true = 1 }bl; int main(int argc,char *argv[]) { a = sun; b = mon; c = tue; printf("a = %d\n",a); //a = 2 printf("b = %d\n",b); //b = 3 printf("c = %d\n",c); //c = 4 // sun = 100; //錯誤,枚舉值是常量,不可改 // printf("sun = %d\n",sun); a = 100; //枚舉變量能夠改 printf("a = %d\n",a); //a = 100 printf("a_len = %d\n",sizeof(a)); //a_len = 4,枚舉變量就是一整型變量 bl = true; if(bl == true) printf("bl爲真\n"); bl = 1; if(bl == true) //枚舉元素能夠用來做判斷比較 printf("bl爲真\n"); return 0; }