知识点11:结构体与共用体

一,结构体

1,定义结构体类型:结构体名与成员表列

	struct Date   //结构体名(大写以突出)   
	{
    
    
		int month;
		int day;
		int year;  //成员表列 
	};//最后要有一个分号!! 
	//建立了一个结构体类型之后,Date就成为了一个新的变量类型
	struct Student
	{
    
    
		char name[20];
		float score;
		struct Date birthday;	//成员可以属于另一个结构体类型,即结构体可以嵌套(定义在先) 
	};		 

注意:变量类型 ≠ \not= = 变量
2,结构体变量的定义

	struct Student s1,s2;//定义结构体类型的变量(可以先声明再定义)
	/*也可以在声明类型的同时定义变量:
	struct Student
	{
		char name[20];
		float score;
		struct Date birthday;
	}s1,s2; 
	*/
	/*若该结构体类型只用一次,也可以不命名,直接定义
	struct
	{
		char name[20];
		float score;
		struct Date birthday;
	}s1,s2;
	*/ 	

3,结构体变量的初始化
可以在定义时或者定义之后对结构体初始化。一般情况下都是在定义的同时进行初始化,因为那样比较方便。如果定义之后再进行初始化,那就只能一个一个的对成员进行赋值(就如同数组一样,数组只能在定义的时候才可以一次性对所有元素进行初始化,如果定义之后再初始化就只能一个一个的赋值了),那样比较麻烦。

	struct Student s1 = {
    
    "shao", 100, {
    
    5, 17, 2002}};//方便
	/*或:
	struct Student s1;
	strcpy(s1.name, "shao");//注意:字符串不能直接赋值,要用strcpy函数
	s1.score = 100;
	s1.birthday.month = 5;//需要逐级找到最低级的成员才能使用
	...  */

4,结构体数组
每个元素都是一个结构体变量

struct employee
{
    
    
	int num;
	char name[20];
	float salary;
}emp[3] = {
    
    
	{
    
    001, "lemon", 2000},
	{
    
    002, "apple", 2300},
	{
    
    003, "peach", 2500}
	};

5,结构体变量作函数参数

#include <stdio.h>
struct Student
	{
    
    
		int num;
		float score[3];//结构体中存在数组成员 
		float aver;
	};
void input(struct Student stu[])
{
    
    
	int i;
	for (i = 0; i < 3; i ++)
	{
    
    
		scanf("%d %f %f %f", &stu[i].num, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);//数组成员的元素要一个一个单独输入	
		stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;//不用输入aver,因为该值是计算出来的 
	}
}
struct Student max(struct Student stu[])//函数的类型也要用结构体类型  
{
    
    										//函数运行的结果为一个结构体数组的元素
	int i, m = 0;
	for (i = 0; i < 3; i ++)
		if (stu[i].aver > stu[m].aver) 
			m = i;//用m来存放成绩最高的学生在数组中的序号 
	return (stu[m]);
}
void print(struct Student stud)//该函数的形参是一个变量而不是一个数组,直接将变量的信息传递过来而不是地址 
{
    
    
	printf("%d %lf %lf %lf", stud.num, stud.score[0], stud.score[1], stud.score[2]);
}

int main()
{
    
    
	struct Student stu[3];
	input(stu);
	print(max(stu));//简化主程序 
	return 0;
} 

在形参的位置使用结构体变量,在函数调用期间,形参也要占用内存。因此这种传递方式在空间和时间上开销都比较大。另外“值传递”使得若在函数内修改了变量的值,这种改变不会返回到主程序中。
6,结构体变量的指针作函数参数

#include <stdio.h>
struct Student
	{
    
    
		int num;
		float score[3]; 
		float aver;
	};
void input(struct Student *p)
{
    
    
	int i;
	for (i = 0; i < 3; i ++, p ++)
	{
    
    
		scanf("%d %f %f %f", &(*p).num, &(*p).score[0], &(*p).score[1], &(*p).score[2]);	
		p->aver = (p->score[0] + p->score[1] + p->score[2]) / 3.0; 
	}
}
struct Student max(struct Student stu[])//函数的类型也要用结构体类型  
{
    
    										//函数运行的结果为一个结构体数组的元素
	int i, m = 0;
	for (i = 0; i < 3; i ++)
		if (stu[i].aver > stu[m].aver) 
			m = i;//用m来存放成绩最高的学生在数组中的序号 
	return (stu[m]);
}
void print(struct Student stud)//该函数的形参是一个变量而不是一个数组,直接将变量的信息传递过来而不是地址 
{
    
    
	printf("%d %lf %lf %lf", stud.num, stud.score[0], stud.score[1], stud.score[2]);
}

int main()
{
    
    
	struct Student stu[3], *p = stu;
	input(p);
	print(max(p));
	return 0;
} 

二,共用体

共用体变量的定义方式与结构体变量很相似

union Data
{
    
    
	int i;
	char ch;
}a, b, c;

值得注意的是:结构体变量大小是所包含的成员所占字节数的总和,其中每个成员都有自己的内存单元;共用体的大小为所包含成员中的最大内存长度。
共用体变量的地址与各成员的地址都是同一地址。
尽管共用体内的各成员共用一段内存,但引用时只能引用成员而不能直接引用共用体变量。printf("%d", a);是错误的。
对共用体变量进行初始化时,只需一个初始化值就够了,其类型应与共用体内第一个成员的类型相同。
在共用体中只有一个成员起作用。

#include<stdio.h>
union Data
{
    
    
	int i;
	char ch;
}a;
int main()
{
    
    
	a.i = 97;//看按照什么形式来进行存储 
	printf("%d %c", a.i, a.ch);//根据内存单元中的信息来进行使用 
	union Data c = {
    
    1, 'a'};//初始化表中只能有一个常量,起作用的只是最后一次赋值的量,因为所有二进制位都会覆盖(取代) 
	printf("\n%d", a.i); //会输出97 
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Shao_yihao/article/details/113347487