C语言-结构体

结构体是什么 ?

结构体是一种构造数据类型,把不同的数据类型整合起来成为一个自定义的数据类型 类似于Java中的类

写法1

struct Man{
	char* name;
	int age;
	char nationality[50];
	int(*func)();
};

void main(){
	//初始化结构体变量

	//形式1 只能在变量声明时赋值
	//struct Man m1 = { "Jack", 21 };

	//形式2
	struct Man m1;
	m1.age = 25;
	m1.name = "Heiko";
	strcpy(m1.nationality, "China"); //char nationality[50];需要以这种方式赋值
	printf("%s,%d\n", m1.name, m1.age);

	struct Man m2 = m1;

	getchar();
}  

写法2

m3代表一个结构体变量的名称, 全局变量,在整个文件都可以使用

struct Man2{
	char* name;
	int age;
}m3;   

void main(){
	m3.name = "Hello";
	printf("%s,%d\n", m3.name, m3.age);
	getchar();
}  

写法3

全局变量,在整个文件都可以使用

struct Man3{
	char* name;
	int age;
}m4, m5 = {"jack",20};  

写法4 匿名结构体

作用: 控制结构体变量的个数 (限量版) ,相当于单例

struct {
	char* name;
	int age;
} m6;  

结构体的嵌套

struct Teacher{
	char* name;
	int age;
};

struct Student{
	char* name;
	int age;
	struct Teacher t;
};

void main(){
	struct Student s1 = { "jack", 21, { "Jason" ,50} };


	struct Teacher t2;
	t2.name = "Jason2";
	t2.age = 51;
	struct Student s2;
	s2.age = 22;
	s2.name = "jack2";
	s2.t = t2;

	printf("学生s2 %s,%d\n",s2.name,s2.age);
	printf("老师t2 %s,%d\n", s2.t.name, s2.t.age);
	getchar();
}  

结构体和指针

struct Man4{
	char* name;
	int age;
};

void main(){
	struct Man4 m1 = { "Jack", 30 };
	//结构体指针
	struct Man4 *p = &m1;
	printf("%s,%d\n", m1.name, m1.age);
	printf("%s,%d\n", (*p).name, (*p).age);
	//-> (箭头)是"(*p)."的简写
	printf("%s,%d\n", p->name, p->age);
}  

指针与结构体数组

struct Man5{
	char* name;
	int age;
};  

void main(){
	struct Man5 mans[] = { { "A", 20 }, "B", 19 };
	//遍历数组

	//方式1
	struct Man5 *p = mans;
	for (; p<mans+2; p++)	{
		printf("%s,%d\n", p->name, p->age);
	}

	//方式2
	int i = 0;
	for (; i<sizeof(mans)/sizeof(struct Man5); i++)	{
		printf("%s,%d\n", mans[i].name, mans[i].age);
	}
}  

结构体大小

结构体变量的大小,必须是最宽基本数据类型的整数倍 (提升读取效率)
比如以下 int 4字节,double8字节,共12字节,不够,会填充字节,占用16字节

struct Man6{
	int age;
	double weight;
};

void main(){
	struct Man6 m1 = {20,89.0};
	printf("%#x,%d\n", &m1, sizeof(m1)); //输出结果: 0x6ffd8c,16
	getchar();
}  

结构体和内存分配

void main(){
	struct Man *m_p = (struct Man*)malloc(sizeof(struct Man) * 10);
	struct Man *p = m_p;
	//赋值
	p->name = "Jack";
	p->age = 20;
	p++;
	p->name = "Rose";
	p->age = 20;
	struct Man *loop_p = m_p;
	for (; loop_p < m_p+2; loop_p++)
	{
		printf("%s,%d\n", loop_p->name, loop_p->age);
	}
	free(m_p);
	getchar();
}   

结构体函数指针成员

可以把结构作为函数参数,传参方式与其他类型的变量或指针类似,这样可以动态执行需要的函数。

struct Girl{
	char* name;
	int age;
	//函数指针
	void(*sayHi)(char*);
};

typedef struct Girl* GirlP;

void sayHi(char* text){
	MessageBoxA(0,text,"title",0);
}

void renameGirlName(GirlP gp1){
	gp1->name = "Lily";
}

void main(){
	struct  Girl g1;
	g1.name = "Lucy";
	g1.age = 18;
	g1.sayHi = sayHi;

	g1.sayHi("hello");

	GirlP gp = &g1;
	renameGirlName(gp);
	gp->sayHi("Good");
	getchar();
}

结构体存储原则

  • 结构体变量中成员的偏移量必须是成员大小的整数倍 (0被认为是任何数的整数倍)
  • 结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数

内存对齐 (为了效率)
对齐跟数据再内存中的位置有关。
如果一个变量的内存地址正好位于它长度的整数倍,他就被称作自然对齐。
比如32位CPU下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

氦客

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值