结构体

c语言中用struct来标识定义的结构体类型,结构体是一些值的集合,这里的值可以是不同内置类型的,这些值称为成员变量
内置类型**char ,short ,int ,long ,float ,double, long long。**
结构题是一种构造类型,其他构造类型:联合体,枚举。

例如这里定义一本书,需要包括名字,作者和价格
c语言中引用结构体成员可以用.或者->来引用成员变量

#include<stdio.h>
#include<stddef.h>
struct Book
{
	//成员变量
	char name[20];//书名
	char author[20];//作者名字
	short price;//价格
}b2,b3,b4;//每一本书的名字

int main()
{
	struct Book b1 = { "c语言程序设计", "谭浩强", 55 };//结构体的初始化
	printf("%s %s %d\n", b1.name, b1.author, b1.price);//打印结构体
	
	return 0;
}

结构体的声明

struct S
{
	member-list;//成员列表,如上文的书名,价格,作者等
}variable-list;//变量列表,如上文的b1,b2,b3

这里在结构体定义时创建了一个s,下方在使用这个结构体时可以不使用s,而是重新定义一个s2来使用。

struct S
{
	char c;
	int a;
	short s;
}s;
int main()
{
	struct S s2 = { 'a', 2, 1 };
	printf("%c %d %d", s2.c, s2.a, s2.s);
	return 0;
}

介绍一下匿名结构体类型,匿名结构体类型就是省略结构体的名字,因为没有名字,所以只能在定义的时候使用一次

struct//这里没有名字
{
	char c;
	int a;
	short s;
}s;//只能在这里用一次

struct
{
	char c;
	int a;
	short s;
}* ps;//在定义结构体时,就算俩结构体成员一样,也是单独的结构体
//所以,不能定义*ps操作s,编译器会提示类型不兼容
int main()
{
	ps = &s;//类型不算相同的类型,即使这俩的元素相同
	
	return 0;
}

结构体实现结点,也是结构体的自引用:

struct Node
{
	int data;//数据域
	struct Node* next;//指针域
};

结构体的嵌套初始化:

struct S
{
	int a;
	int b;
	double d;
};

struct B
{
	char c;
	struct S s;
	short ss;
};

int main()
{
	struct B b = { 'a', { 1 , 1, 1.1 }, 1 };
	printf("%lf\n", b.s.d);
	return 0;
}

结构体内存对齐
结构体内存对齐是什么:结构体在计算大小的时候会发生对齐
为什么要有结构体内存对齐:结构体的内存对齐是拿空间来换取时间的做法。可以提高程序的效率。数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。同样结构体内存对齐也能增加程序的可移植性
结构体内存对齐的规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
    VS中默认的值为8,Linux中的默认值为4
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

下面看几个结构体内存对齐的计算

`

#include<stdio.h>
struct S1
{
	char c1;//占用0-1
	int a;//1-2,2-3浪费,占用4-7
	char c2;//占用8-9,9-10,,10-11,11-12浪费
};//输出12

struct S2
{
	char c1;//占用0-1
	char c2;//占用1-2,/2-3,3-4浪费
	int i;//占用4-7,总计占用0-7,8个字节
};

struct S3
{
	double d;//0-7
	char c;//7-8
	char i;//8-9,/10-11,11-12,12-15浪费,总计十六个
};

struct S4
{
	char c1;//0-1
	struct S3 s3;//如果嵌套了结构体的情况,
	//嵌套的结构体对齐到自己的最大对齐数的整数倍处,
	//结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
	//这里对齐数为8,所以从8字节开始到23字节
	double d;//24-31
};

int main()
{
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	printf("%d\n", sizeof(struct S3));
	printf("%d\n", sizeof(struct S4));
	return 0;
}//结构体内存对齐是拿空间换时间,得到效率上的提升

输出的结果:
12
8
16
32
请按任意键继续. . 

注意:
使用结构体传参
最好是传地址,因为如果结构体较大,传值会有较大时间和空间上的系统开销,造成性能的下降

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值