C结构和联合复习
C语言结构和联合复习
定义
聚合数据类型能够同时存储一个以上的单独数据类型,C语言提供了两种类型的聚合数据类型,即数组和结构,数组存储的是相同类型元素的集合,而结构则可以是不同元素的集合,但与数组不同,结构体不能通过下标访问,这是因为数组各元素长度相同,而结构体各元素长度不等,结构体类型属于标量类型
标签声明、typedef
一个结构的成员的名字可以和其他结构的成员的名字相同
结构体成员的直接访问,结构体变量的成员是通过点操作符(.)访问的,点结合符的结合性自左向右,下标引用和点操作符优先级相同,结合性上都是自左向右
结构体成员的间接访问,因为点操作符的优先级高于间接访问操作符,所以必须在表达式中使用括号,当然也可以使用->操作符访问
结构体的自引用
结构体内不能包含自身结构体变量,因为这会导致结构体不断被调用,但是程序允许结构体指针的存在,因为当结构体长度确定时,指针的长度就已经确定下来
typedef struct{ int a; short b[2]; }ex2; typedef struct ex{ int a; char b[3]; ex2 c; struct ex *d; }ex;
结构体、指针、成员
以下为一个例子:
1 ex x={10,"Hi",{5,{-1,25}},0} 2 ex *px=&x; 3 4 px//指针变量 5 //px的右值表示px的值,即结构变量x的地址值 6 //px的左值表示px的内存位置,因为px并非地址常量,所以px可以被赋值 7 *px//间接访问px所指内存 8 //*px的左值表示为px所指结构体的值,其可以修改 9 //*px的右值表示为px所指结构体的值,其可以进行赋值、访问 10 //*px+1是非法的,因为没有规定结构体加整型值的运算 11 //*(px+1)也是非法的,x是一个标量 12 px->a//箭头操作符,执行间接访问操作 13 //a是结构体的第一个成员,其地址值与px的地址值一样 14 //但是两者类型不同,前者是整型,后者是指向结构体的指针 15 //->操作符的优先级比&操作符高 16 //int *pi=&px->a 17 //px->b为指针常量 18 px->c//访问嵌套结构 19 *px->c.b//访问结构体c内数组b的首元素
结构体的内存分配:
结构体的大小由结构体成员内内存最大的成员来确定,因为其对内存边界要求最高,以下举三种情况:
1 typedef struct { 2 char a; 3 int b; 4 char f; 5 }c;//sizeof(c)为12字节,因为a和f需要各自独占4字节来保证b的地址能被4整除 6 typedef struct { 7 int b; 8 char a; 9 char f; 10 }c;//sizeof(c)为8字节,以为a和f共享4字节,然后b独占4字节 11 typedef struct { 12 int b; 13 char a; 14 char f; 15 }c;//与上文理由相同
作为函数参数的结构:
由于结构体的内存分配,结构体作为函数参数时字节数会相对较大,因此可以采用指针的方式进行传参,然后在函数内进行间接访问操作,但这样的缺点是会对调用程序的结构体造成影响,不过可以加上const来改善此问题,
位段:
关于结构还有一种应用,那就是位段,位段的声明与结构体类似,但它的成员是一个或多个位的字段
位段的声明与普通结构体声明类似,但有两个区别:首先位段的成员的类型为int、signed int、unsigned int之一,其次是位段成员后面需要加冒号和整数值,整数值表示该位段所占用的位的数目
位段能够把长度为奇数的数据包装在一起,节省存储空间
使用位段只是基于方便的目的,任何可以用位段实现的任务都可以用移位和屏蔽来实现,
联合
联合的声明和结构体类似,但是联合的所有成员引用的是内存中的相同位置,联合的内存长度取决于联合体中字节最大的成员
变体记录:
内存中某个特定的区域将在不同的时刻储存不同类型的值