简介
C 数组允许定义可存储相同类型数据项的变量,结构体是 C 编程中另一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。
结构体的一般形式为:
struct 结构体名
{
成员列表,可以是任何数据类型
};
声明了一个结构体相当于构建了一个新的结构体类型,但系统并不为其分配空间,只有定义结构体变量时才分配内存。
定义结构体变量时,一般形式为:
结构体名 变量名。 例如
struct apple a;
struct 为定义结构体变量的关键字.
三种定义结构体方法
1,
struct person 声明了结构体名字
{
char name[20];
int age;
char sex;
char phone[15];
}p1,p2; 同时定义了两个结构体变量
2,
struct
{
char name[20];
int age;
char sex;
char phone[15];
}p1,p2; 这个只是定义了两个结构图变量,但是没有声明结构体的名字
3,
嵌套结构体
struct date
{
int year;
int monyh;
int day;
};
struct person
{
char name[20];
int age;
char sex;
char phone[15];
struct date brithday;
char *string;
}
总结:定义在前面的是结构体名字,在后面的是变量名字
引用和初始化结构体变量
一般的形式是:结构图变量.成员名
例子:strcpy(p1.name,“John”);
p1.age=24;
.的作用:.是成员运算符,用于取得结构体中的成员,他在所有的运算符中 优先级最高
结构体数组
结构体数据就是指数组中的每一个元素都是结构体
#include <stdio.h>
struct test{
int num ;
float value;
char ch;
};
int main()
{
struct test testArr[3]={ {1,1,2},{3,3,4},{5,5,6} };
for(int i = 0; i<3 ; i++)
{
printf("testArr[%d].num=%d\n",i,testArr[i].num);
printf("testArr[%d].value=%f\n",i,testArr[i].value);
printf("testArr[%d].ch=%d\n",i,testArr[i].ch);
}
return 0;
}
结构体指针
当一个指针变量指向结构体时,称为结构体指针
struct 结构体名 *变量名;
结构体变量名与数组名不一样,数组名在表达式中会被转换成数组指针,而结构体变量名不会,无论在任何表达式中标表示的都是整个结构体本身,要活的结构体变量的地址,则必须使用取地址符&
#include <stdio.h>
struct test{
int num;
char ch;
double doub;
}t1;
int main()
{
struct test t1 = {5,'A',5.6};
struct test *ptr = &t1;
//解引用和点运算符
printf("type1:(*ptr).num=%d\n",(*ptr).num);//.的优先级比*高,所以要上括号
//指针
printf("type2: ptr->ch=%c\n",ptr->ch);
return 0;
}
字节对齐
结构体中存在内存对齐,作用就是加快系统的访问效率。因为当你定义结构体成员时,由于数据类型的不同,申请的空间大小也不一样。
struct A
{
int a;//4字节
short b;//2字节
int c;//4字节
char d;//1字节
};
所以结构体原本所占字节是11字节,但是由于存在字节对齐,所以最后应该是16字节。
字节对齐规则
#pragma pack (n)//按照指定n字节对齐规则
- 结构体内部任何K字节的基本数据类型相对于结构体首地址的偏移,必须是K的整数倍
- 结构体变量的首地址能够被其最大基本类型成员的大小所整除
- 结构体的总大小为结构体最宽基本类型成员大小的整数倍
struct A
{
int a;//4字节
short b;//2字节
char d;//1字节
int c;//4字节
};
在以上结构体中,所占字节最大的数据类型为int,刚开始a申请了4字节空间,到b的时候,其偏移量4刚好是2的整数倍,到d的时候,其偏移量为4+2 = 7,为1的整数倍,到c的时候,其偏移量7不是4的整数倍,所以要加1使其偏移量为8,能够被4整除。至此,结构体实际内存因该是4+2+1+1(多加的,使偏移量刚好为4的整数倍)+4 = 12字节。
字节对齐原因
1,提高结构体成员的访问效率
2,不是所有平台支持随机内存访问
结构体位段
struct person
{
char num:3 //指定空间中n个比特位,多个位段可以合并使用一个存储空间
};
多个位段使用同一块空间,从低字节到高字节,比特位不够申请新的空间
数据过大,会产生截断
person person ;person.num = 9;9为1001,但num只有3比特,所以产生截断,从低位截断001