再识C中的结构体
在前面认识C中的结构体中我介绍了结构体的基础知识,下面通过这段代码来回顾一下:
1 #include<stdio.h> 2 #define LEN 20 3 4 struct Student{ //定义结构体 5 char name[LEN]; 6 char address[LEN]; 7 int age; 8 }; 9 10 int main(int argc, char* argv[]) 11 { 12 struct Student s = { //初始化 13 "bluemsun","NENU",25 14 }; 15 16 struct Student * p; //定义一个指向结构体的指针 17 p = &s; //为指针赋值 18 19 printf("s.name = %s,s.address = %s,s.age = %d\n",s.name,s.address,s.age); 20 printf("p->name = %s,p->address = %s,p->age = %d\n",p->name,p->address,p->age); 21 }
这是一个比较简单的例子程序,在结构体Student中我们定义两个char数组,现在来考虑这样一个问题。我们在平时需要使用数组的时候都是可以用指针代替数组作为参数使用,那么在上面的程序中能否用下面这段代码代替结构体的定义呢?
1 struct new_Student{ //定义结构体 2 char * name; 3 char * address; 4 int age; 5 };
答案是肯定的,但是可能会遇到一些麻烦。考虑下面一段代码:
1 struct new_Student s1 = {"zhouxy","EFGH",25}; 2 struct Student s2 = {"bluemsun","ABCD",26};
这段代码是正确的。但是想想其中的字符串存储在哪里?对于struct Student变量s2来说,字符串存储在结构内部,这个结构总共分配了40个字节来存储两个字符串。然而对于new_Student变量s1来说,字符串是存放在编译器存储字符串常量的任何地方。new_Student结构中仅仅是存放了两个地址而已。所以如果需要一个结构来存放字符串,请使用字符数组成员。那么是不是采用指针的方式就真的不能完成内存的分配呢?答案是否定的。在这里我讲解了关于C中的函数malloc(),这个函数是可以在运行期动态分配内存的。所以如果能结合在这里来使用,那就达到了我们的设想了。考虑下面这段代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 5 struct new_Student{ //定义结构体 6 char * name; 7 char * address; 8 int age; 9 }; 10 11 int main(int argc, char* argv[]) 12 { 13 char str[] = "zhouxy"; 14 struct new_Student s1; 15 //分配用来存放名字的内存 16 s1.name = (char*)malloc(strlen(str)+1); 17 //把名字复制到已分配的内存中 18 strcpy(s1.name,str); 19 20 printf("s1.name = %s\n",s1.name); 21 }
上面代码是正确的,我们用malloc()函数分配存储空间,然后把字符串复制到新分配的空间。这里要理解的是:name字符串不是被存储在结构中,而是被保存在由malloc()函数管理的内存中。结构中仅仅是保存了name字符串的地址而已。还有一点要记得的是:我们使用malloc()函数分配内存之后要调用free()函数,不然可能会引起"内存泄露"。