十分钟看明白C语言结构体(定义,使用,销毁)

发现很多初学C语言编程的朋友搞不懂结构体的用法,于是简单介绍一下,以后就不用反复教了,预计十分钟你就可以学会。

文章目录

  • 首先看一看结构体怎么定义
  • 然后看一看结构体怎么使用
  • typedef + 结构体
  • 结构体数组的定义
  • 结构体的复制
  • 结构体的销毁

首先看一看结构体怎么定义

结构体其实很简单,就是把多个变量打了个包,可以一起定义,一起使用。
比如一个学生有学号id,姓名name,性别男女,本来我们一个学生需要定义三个变量,但这里可以定义一个结构体,把这三个属性都包含进去,这样编程思路更清晰。

// 定义一个类型为struct Student的结构体
struct Student{
	int id;
	char name[20];
	bool gender; //true代表男性,false代表女性 
};

然后看一看结构体怎么使用

在主函数中,在定义的时候需要用大括号括住其中的值来初始化。也可以先定义,再用变量名加点加属性名的方式来赋值。使用的时候,和赋值的方法完全一样,可以用变量名加点加属性名的方式来获取到值。

int main(int argc, char** argv) {
	struct Student s1 = {1001, "xiaoming", true};
	struct Student s2;
	s2.id = 1002;
	strcpy(s2.name,"xiaohong");
	s2.gender = false; 
	printf("s1.id:%d s2.id:%d\n", s1.id, s2.id);
	return 0;
}

typedef + 结构体

在定义结构体的时候,可以用typedef关键字同时对结构体进行重命名。因为定义出来的结构体默认类型前面需要加struct,使用不方便,所以可以这样:

// 定义一个类型为struct Student的结构体
typedef struct Student{
	int id;
	char name[20];
	bool gender; //true代表男性,false代表女性 
}Student;

这样使用的时候就可以直接用Student了。

int main(int argc, char** argv) {
	Student s1 = {1001, "xiaoming", true};
	Student s2;
	s2.id = 1002;
	strcpy(s2.name,"xiaohong");
	s2.gender = false; 
	printf("s1.id:%d s2.id:%d\n", s1.id, s2.id);
	return 0;
}

结构体数组的定义

有了上面对Student的定义,我们可以创建一个结构体数组。和普通的类型一样,类型名+变量名+中括号和数字即可,初始化的时候可以把结构体初始化和数组初始化结合起来,用双重大括号

Student students[20] = {
	{1001, "xiaoming", true}, 
	{1002, "xiaohong", false}, 
	{1003, "xiaolan", false}, 
	{1004, "xiaogang", true}, 
	{1005, "xiaomei", false}
};

结构体的复制

如果结构体中包含有指针类型,那么复制就有两种:

  1. 浅复制:直接用等号,效果是把结构体数组直接包含的一切值都复制过来,指针的指向的地址也复制过来,但并不会把地址中的内容也复制一份,换言之,复制出来的结构体变量的指针依然指向之前动态分配的空间。

浅复制代码。

char *aname = (char*)malloc(10*sizeof(char));
strcpy(aname, "test1");
Student a = {1001, aname, true};

Student b;
b = a;

浅复制效果。

test1.name:test1 test2.name:test1
test1.name ptr:0000000000736AB0 test2.name ptr:0000000000736AB0
  1. 深复制:先把指针指向的空间中的内容,找一块新空间复制一下,然后再复制结构体变量,并且指针指向新的空间。这时,他们的指针指向的地址不同,但空间中的内容相同。
    可以把上面结构体的name改成char*类型,看看效果。

深复制代码。

char *aname = (char*)malloc(10*sizeof(char));
strcpy(aname, "test1");
Student a = {1001, aname, true};

Student b;
b = a;
b.name = (char*)malloc(10*sizeof(char));
strcpy(b.name, a.name);

深复制效果(看地址的倒数第二位,是不同的)。

test1.name:test1 test2.name:test1
test1.name ptr:0000000000BD6AB0 test2.name ptr:0000000000BD6AD0

结构体的销毁

和常规变量一样,当出了作用域之后,结构体的变量和数组会被自动销毁,但是,注意,结构体指针指向的空间,和结构体成员变量中的指针指向的空间,都不会被自动释放,需要手动释放。

手动释放结构体成员变量中指针指向的空间(尤其注意不要忘记数组,需要一个一个释放)。

char *aname = (char*)malloc(10*sizeof(char));
strcpy(aname, "test1");
Student a = {1001, aname, true};
... ...
free(a.name);

手动释放结构体指针指向的空间,记得先把内部包含的指针指向的空间释放掉。

Student *aptr; 
aptr = (Student* )malloc(sizeof(Student));
... ...
free(aptr->name);
free(aptr);

总之,结构体只要会创建,会使用,会释放,你就已经掌握一大半了。更为复杂的情况是和指针结合,之后考虑再写文章详细讲解。

你可能感兴趣的