C 语法 - 10_结构体、共用体、枚举

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
	int num;
	char name[32];
};

//结构体赋值
void test01()
{
	//结构体初始化赋值
	struct stu lucy = {100, "lucy"};	
	printf("%d %s\n", lucy.num, lucy.name);

	//结构体初始化清0
	memset(&lucy, 0, sizeof(struct stu));
	printf("%d %s\n", lucy.num, lucy.name);

	//结构体通过键盘赋值
	printf("请输入 num name\n");
	scanf("%d %s", &lucy.num, lucy.name);
	printf("%d %s\n", lucy.num, lucy.name);

	//结构体成员单独赋值
	lucy.num += lucy.num;
	strcpy(lucy.name, "bob");
	printf("%d %s\n", lucy.num, lucy.name);

}

//相同类型的结构体变量之间赋值
void test02()
{
	struct stu lucy = {10, "lucy"};

	//逐个成员赋值
	struct stu tom;
	tom.num = lucy.num;
	strcpy(tom.name, lucy.name);
	printf("%d %s\n", tom.num, tom.name);

	//结构体变量直接赋值
	struct stu bob = lucy;
	printf("%d %s\n", bob.num, bob.name);

	//内存拷贝
	struct stu hailun;
	memcpy(&hailun, &lucy, sizeof(lucy));
	printf("%d %s\n", hailun.num, hailun.name);

}

//结构体嵌套结构体
void test03()
{
	struct data
	{
		int fenshu;
		int nianning;	
	};

	struct student
	{
		int num;
		data da;		
	};

	struct student bob = {10, {90, 16}};
	printf("%d %d %d\n", bob.num, bob.da.fenshu, bob.da.nianning);

}

//结构体数组,本质是数组,每个元素是结构体。
void test04()
{
	struct stu arr[3] = {{10, "小明"}, {11, "小红"}, {12, "小王"}};

	int n = sizeof(arr)/ sizeof(arr[0]);
	for(int i=0; i<n; i++)
	{
		printf("学号:%d,姓名:%s\n", arr[i].num, arr[i].name);
	}

	memset(arr, 0, sizeof(arr));
	printf("请输入%d个学生信息:num name\n", n);
	for(int i=0; i<n; i++)
	{
		scanf("%d %s", &arr[i].num, arr[i].name);
	}
	for(int i=0; i<n; i++)
	{
		printf("学号:%d,姓名:%s\n", arr[i].num, arr[i].name);
	}

}

//结构体指针变量,本质是指针变量,保存的是结构体变量的地址。
void test05()
{
	struct stu lucy = {10, "lucy"};
	struct stu *p = &lucy;

	printf("%d %s\n", lucy.num, lucy.name);
	printf("%d %s\n", (*p).num, (*p).name);
	printf("%d %s\n", p->num, p->name);
	printf("%d %s\n", (&lucy)->num, (&lucy)->name);

}

//结构体数组元素的指针变量。
void input_stu_array(struct stu *arr, int n)
{
	printf("请输入%d个学生信息:num name\n", n);
	for (int i=0; i<n; i++)
	{
		scanf("%d %s", &(arr+i)->num, (arr+i)->name);
		//scanf("%d %s", &arr[i].num, arr[i].name);
	}
}
void sort_stu_array(struct stu *arr, int n)
{
	for (int i=0; i<n-1; i++)
	{
		int min = i;
		for (int j=min+1; j<n; j++)
		{
			if(arr[min].num > arr[j].num)
				min = j;
		}
		if(i != min)
		{
			struct stu tmp = arr[i];
			arr[i] = arr[min];
			arr[min] = tmp;
		}
	}
}
void printf_stu_array(struct stu *arr, int n)
{
	for (int i=0; i<n; i++)
	{
		printf("%d %s\n", arr[i].num, arr[i].name);
	}
}
void test06()
{
	struct stu bob[5];

	memset(bob, 0, sizeof(bob));

	int n = sizeof(bob)/sizeof(bob[0]);

	//获取键盘输入
	input_stu_array(bob, n);

	//对结构体数组排序
	sort_stu_array(bob, n);

	//打印数组
	printf_stu_array(bob, n);

}

//结构体的指针成员
void test07()
{
	struct stu1
	{
		int num1;
		char* name1;
	};

	//指针成员保存栈区、全局区地址
	struct stu1 bob1 = {10, "bob1"};
	printf("%d %s\n", bob1.num1, bob1.name1);
	printf("%c\n", bob1.name1[1]);

	//指针成员申请堆区空间地址
	bob1.num1 = 20;
	bob1.name1 = (char*)calloc(1, 128);
	strcpy(bob1.name1, "hello world");
	printf("%d %s\n", bob1.num1, bob1.name1);

	bob1.name1[6] = 'W';
	printf("%s\n", bob1.name1);

	//释放堆区空间
	if(bob1.name1 != NULL)
	{
		free(bob1.name1);
		bob1.name1 = NULL;
	}

}

//结构体的浅拷贝
void test08()
{
	struct stu1
	{
		int num1;
		char* name1;
	};

	struct stu1 bob1;

	//指针成员申请堆区空间地址
	bob1.num1 = 20;
	bob1.name1 = (char*)calloc(1, 128);
	strcpy(bob1.name1, "hello world");
	printf("%d %s\n", bob1.num1, bob1.name1);

	//浅拷贝
	struct stu1 tom1 = bob1;
	printf("%d %s\n", tom1.num1, tom1.name1);

	//释放堆区空间
	if(bob1.name1 != NULL)
	{
		free(bob1.name1);
		bob1.name1 = NULL;
	}

	if(tom1.name1 != NULL)
	{
		//free(tom1.name1);
		tom1.name1 = NULL;
	}

}

//结构体的深拷贝
void test09()
{
	struct stu1
	{
		int num1;
		char* name1;
	};

	struct stu1 bob1;

	//指针成员申请堆区空间地址
	bob1.num1 = 20;
	bob1.name1 = (char*)calloc(1, 128);
	strcpy(bob1.name1, "hello world");
	printf("%d %s\n", bob1.num1, bob1.name1);

	//深拷贝
	struct stu1 tom1;
	tom1.num1 = bob1.num1;
	tom1.name1 = (char*)calloc(1, 128);
	strcpy(tom1.name1, bob1.name1);
	printf("%d %s\n", tom1.num1, tom1.name1);

	//释放堆区空间
	if(bob1.name1 != NULL)
	{
		free(bob1.name1);
		bob1.name1 = NULL;
	}

	if(tom1.name1 != NULL)
	{
		free(tom1.name1);
		tom1.name1 = NULL;
	}

}

//结构体在堆区,结构体指针成员在堆区
void test10()
{
	struct stu1
	{
		int num1;
		char* name1;
	};

	struct stu1* p = NULL;
	p = (struct stu1*)calloc(1, sizeof(struct stu1));

	p->name1 = (char*)calloc(1, 128);
	strcpy(p->name1, "小明");
	//p->name1 = "你好";

	p->num1 = 16;
	printf("%d %s\n", p->num1, p->name1);

	//先释放成员空间
	if(p->name1 != NULL)
	{
		free(p->name1);
		p->name1 = NULL;
	}

	//再释放结构体空间
	if(p != NULL)
	{
		free(p);
		p = NULL;
	}

}

//结构体指针数组在堆区,结构体在堆区,结构体指针成员在堆区
void test11()
{
	struct stu1
	{
		int num1;
		char* name1;
	};

	//给结构体指针数组申请堆区空间
	struct stu1* *arr = NULL; 
	arr = (struct stu1**)calloc(5, sizeof(struct stu1*));

	for(int i=0; i<5; i++)
	{
		//给结构体指针数组每个元素,申请结构体堆区空间,即给结构体变量开辟空间
		*(arr+i) = (struct stu1*)calloc(1, sizeof(struct stu1));

		//给每个结构体指针成员申请堆区空间
		(*(arr+i))->name1 = (char*)calloc(1, 128);

		//结构体成员赋值
		(**(arr+i)).num1 = 10 + i;
		sprintf((*(arr+i))->name1, "%d 小红", i);
	}

	//遍历
	for(int i=0; i<5; i++)
	{
		printf("%d %s\n", (**(arr+i)).num1, (*(arr+i))->name1);
	}

	//释放堆区空间
	for(int i=0; i<5; i++)
	{
		if(arr[i]->name1 != NULL)
		{
			free(arr[i]->name1);
			arr[i]->name1 = NULL;
		}

		if(arr[i] != NULL)
		{
			free(arr[i]);
			arr[i] = NULL;
		}
	}

	if(arr != NULL)
	{
		free(arr);
		arr = NULL;
	}

}

//结构体的位域
void test12()
{
	struct pack_data
	{
		unsigned int wei01:2;
		unsigned int wei02:2;   //相邻位域
		unsigned int :0;        //另起一个存储单元
		unsigned int wei03:10;
		unsigned int :2;        //2位无意义位段
		unsigned int wei04:10;
	};
	struct pack_data data;
	data.wei01 = 30;
	printf("%d\n", sizeof(data));
	printf("%d\n", data.wei01);

	struct REG
	{
		unsigned char addr:2;
		unsigned char :1;
		unsigned char opt:2;
		unsigned char :1;
		unsigned char datas:2;
	};
	struct REG reg;
	//11 10 01
	reg.opt = 2;
	reg.addr = 3;
	reg.datas = 1;
	printf("%#x\n", reg);

}

//union 共用体
void test13()
{
	union data
	{
		char a;
		short b;
		int c;
	};
	union data ob;
	ob.a = 10;
	ob.b = 20;
	ob.c = 30;
	printf("%d\n", ob.a + ob.b + ob.c);

	union data ob2;
	ob2.c = 0x01020304;
	ob2.b = 0x0102;
	ob2.a = 0x01;
	printf("%#x\n", ob2.a);
	printf("%#x\n", ob2.b);
	printf("%#x\n", ob2.c);

}

//enum 枚举
void test14()
{
	enum POKER_COLOR{HONGTAO, HEITAO = 10, FANGKUAI, MEIHUA};

	enum POKER_COLOR poker = FANGKUAI;

	printf("%d %d %d %d %d\n", poker, HONGTAO, HEITAO, FANGKUAI, MEIHUA);

}

int main(int argc, char const* argv[])
{
	test14();

	return 0;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值