一、结构体指针
作用:通过指针访问结构体中的成员
语法:struct 结构体名 *指针名;
利用操作符->可以通过结构体指针访问结构体属性
#include <stdio.h>
#include <string.h>
//定义结构体
struct student
{
int num;
char name[16];
float score;
};
int main(int argc, const char *argv[])
{
struct student stu;
struct student *p = &stu;
/*
* 通过结构体变量去赋值
stu.num = 1000;
strcpy(stu.name, "lisi");
stu.score = 90;
*/
//通过结构体指针去赋值
p->num = 1000;
strcpy(p->name, "lisi");
p->score = 90;
printf("num = %d, name = %s, score = %f\n", stu.num, p->name, p->score);
return 0;
}
结构体指针点(.)和箭头(->)的区别
点(.)是用于结构体变量访问成员,箭头(->)是用于结构体指针访问成员。
访问结构成员的运算符有两种,一种是结构成员运算符“·”,也称为“圆点运算符”,另一种是结构指针运算符“->”,也称“箭头运算符”。
圆点运算符是比较古老的写法,不能访问结构体指针变量成员,现在都推荐使用箭头运算符,即->
二、结构体嵌套结构体
含义:结构体中的成员可以是另一个结构体
语法
struct 结构体名
{
struct 结构体名 成员名;
};
#include <stdio.h>
#include <string.h>
struct person
{
char name[16];
int age;
char sex;
};
struct student
{
struct person stu;
float score;
};
struct teacher
{
struct person tea;
char phone[12];
};
int main(int argc, const char *argv[])
{
struct student s;
strcpy (s.stu.name,"zhangsan");
s.stu.age = 12;
s.stu.sex = 'm';
s.score = 98;
printf("name = %s,age = %d, sex = %c, score = %f\n", s.stu.name, s.stu.age, s.stu.sex, s.score);
struct teacher t;
struct teacher *p = &t;
strcpy (p->tea.name, "lisi");
p->tea.age = 54;
p->tea.sex = 'w';
strcpy (p->phone, "13112341234");
printf("name = %s,age = %d, sex = %c, score = %s\n", t.tea.name, t.tea.age, t.tea.sex, t.phone);
return 0;
}
三、结构体的大小
字节对齐含义:字节对齐主要是针对结构体而言的,通常编译器会自动对其成员变量进行对齐,以提高数据存取的效率;
字节对齐作用:
平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
性能原因: 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
结构体大小的计算方法:自身对齐、默认对齐、有效对齐。
#include <stdio.h>
struct A
{
char a;
int b;
char c;
char d;
};
struct B
{
char a;
short b;
char c;
char d;
};
struct C
{
char a;
double b;
char c;
char d;
};
int main(int argc, const char *argv[])
{
printf("int = %d, %d\n",sizeof(int), sizeof(struct A));
printf("short = %d, %d\n",sizeof(short), sizeof(struct B));
printf("double = %d, %d\n",sizeof(double), sizeof(struct C));
return 0;
}
四、位域
所谓的“位域”是把一个字节中的二进制位分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。
位域的一般形式:
struct 位域结构体名
{
位域列表;
};
其中位域列表的形式为:类型说明符 位域名:位域长度
位域变量的说明:
struct 位域结构体名 变量名
struct 位域结构体名 变量名 = {成员1值,成员2值..}
定义位域结构体时顺便创建变量
#include <stdio.h>
struct A
{
unsigned char a:2;
unsigned char b:3;
unsigned char c:3;
}t2 = {2, 3, 1}; //3.定义位域时定义变量
int main(int argc, const char *argv[])
{
printf("%d\n",sizeof(struct A));
//1.先定义变量再赋值
struct A t;
t.a = 1;
t.b = 2;
t.c = 3;
printf("%d %d %d\n",t.a, t.b, t.c);
//2.定义变量时进行赋值
struct A t1 = {2, 1, 3};
printf("%d %d %d\n",t1.a, t1.b, t1.c);
t2.a = 3;
t2.b = 1;
t2.c = 2;
printf("%d %d %d\n",t2.a, t2.b, t2.c);
return 0;
}