11.C语言结构体

结构体的定义

struct 结构体名

{

结构体成员列表

};

struct student
{
	int num;
	char name[16];
	float score;
};

结构体的使用

struct 结构体名 变量名;

struct 结构体名 变量名 = {

​ 成员1,

​ 成员2,

​ …

};

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
struct stu {
	char name[16];
	int age;
	float score;
};

int main() {
	//赋值方式一
	struct stu s;
	strcpy(s.name, "zs");
	s.age = 18;
	s.score = 60;
	printf("name = %s,age = %d,score = %.1f\n", s.name, s.age, s.score);
	赋值方式二
	struct stu s2 = { "ls",18,78 };
	printf("name = %s,age = %d,score = %.1f\n", s2.name, s2.age, s2.score);
	return 0;
}

结构体数组

定义:

struct 结构体名

{

结构体成员列表

}变量名[N];

或者在使用时:

struct 结构体名 变量名[N];

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

struct stu
{
	char name[16];
	int age;
	float score;
} s[3];

int main()
{
	struct stu* p = &s;

	strcpy(p->name, "zs");
	p->age = 18;
	p->score = 60.5;
	p++;

	strcpy(p->name, "ls");
	p->age = 20;
	p->score = 78;

	p++;
	strcpy(p->name, "ww");
	p->age = 19;
	p->score = 90.0;
	p = &s;
	int i;
	for (i = 0; i < sizeof(s) / sizeof(struct stu); i++)
	{
		printf("name = %s,age = %d,score = %.1f\n", p->name, p->age, p->score);
		p++;
	}
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

//定义结构体
struct student
{
	int num;
	char name[16];
	float score;
};

int main()
{
	struct student stu[3] = { {1000, "zs", 99}, {1001, "lisi", 89}, {1003, "ww", 79} };//赋值方式一
	struct student stu1[3];
	//赋值方式二
	stu1[0].num = 2000;
	strcpy(stu1[0].name, "lh");
	stu1[0].score = 100;
	printf("num = %d, name = %s, score = %f\n", stu1[0].num, stu1[0].name, stu1[0].score);

	int i;
	for (i = 0; i < 3; i++)
	{
		printf("num = %d, name = %s, score = %f\n", stu[i].num, stu[i].name, stu[i].score);
	}

	return 0;
}

结构体指针

使用:

struct 结构体名 * 变量 = &变量名(结构体);

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

//定义结构体
struct student
{
	int num;
	char name[16];
	float score;
};

int main()
{
	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 结构体名 成员名;

};

#define _CRT_SECURE_NO_WARNINGS
#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()
{
	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, "18674074000");

	printf("name = %s,age = %d, sex = %c, score = %s\n", t.tea.name, t.tea.age, t.tea.sex, t.phone);

	return 0;
}

结构体大小

结构体的大小计算遵循结构体的对齐规则:

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

注:VS中的默认对齐数为8,不是所有编译器都有默认对齐数,当编译器没有默认对齐数的时候,成员变量的大小就是该成员的对齐数。

#define _CRT_SECURE_NO_WARNINGS
#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;
};
struct D {
	char a;
	double b;
	struct C c;
	char d;
	char e;
};
int main()
{
	printf("int = %d,  %d\n", sizeof(int), sizeof(struct A)); //1,4,1,1 -> 4,4,4
	printf("short = %d,  %d\n", sizeof(short), sizeof(struct B));//1,2,1,1 -> 2,2,2
	printf("double = %d,  %d\n", sizeof(double), sizeof(struct C));//1,8,1,1 -> 8,8,8
	printf("struct C = %d,  %d\n", sizeof(struct C), sizeof(struct D));//1,8,24,1,1 -> 8,8,24,8
	/*
		int = 4,  12
		short = 2,  6
		double = 8,  24
		struct C = 24,  48
	*/
	return 0;
}

位域

定义:

所谓的“位域”是把一个字节中的二进制位分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。

struct 位域结构体名

{

​ 位域列表;

};

其中位域列表的形式为:

类型说明符 位域名:位域长度;

位域变量说明:

struct 位域结构体名 变量名;

struct 位域结构体名 变量名 = {值1,值2…};

定义位域结构体时定义变量;

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

struct s1 {
	unsigned int a : 8;
	unsigned int b : 16;
	unsigned int c : 8;
};
struct s2 {
	unsigned char a : 1;
	unsigned char b : 8;//不能超过8
	unsigned char c : 5;
};
int main() {
	printf("%d\n", sizeof(struct s1));//4 ,8+16+8 <32 所有占4个字节
	printf("%d\n", sizeof(struct s2));//3   ,8+8+8 
	return 0;
}


位域的位数赋值:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
struct data_t {
	unsigned int value : 34;//编译器不允许
	unsigned int value : 0;//编译器不允许
};
int main() {
	struct data_t data;
	data.value = 10;
	printf("value = %d", data.value);
	return 0;
}

位域对齐:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
struct data_t1 {
	unsigned char flag1 : 1;
	unsigned int flag2 : 16;
	unsigned char flag3 : 1;

};
struct data_t2 {
	unsigned char flag1 : 1;
	unsigned int flag2 : 16;
	unsigned int flag3 : 1;

};
int main() {
	printf("size : %d\r\n", sizeof(struct data_t1));//Windows下 = 12,Linux下 = 4
	printf("size : %d\r\n", sizeof(struct data_t2));//Windows下 =8,Linux下 = 4
	//字节对齐规则(编译器),编译器可能会在flag2前后插入填充字节以满足对齐要求
	return 0;
}

位域的位级别操作:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
union data_u
{
	struct {
		unsigned char flag1 : 1;
		unsigned char flag2 : 1;
		unsigned char flag3 : 1;
		unsigned char flag4 : 1;
	}bits;
	unsigned char byte;
};

int main() {
	union data_u data;
	data.bits.flag1 = 1;
	data.bits.flag2 = 0;
	data.bits.flag3 = 1;
	data.bits.flag4 = 1;
	printf("byte : %d\r\n", data.byte);//13
	printf("bits size : %d\r\n", sizeof(data.bits));//1

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值