首页 > 再识C中的结构体

再识C中的结构体

  在前面认识C中的结构体中我介绍了结构体的基础知识,下面通过这段代码来回顾一下:

 1 #include
 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
",s.name,s.address,s.age);
20     printf("p->name = %s,p->address = %s,p->age = %d
",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
 2 #include<string.h>
 3 #include
 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
",s1.name);
21 }

  上面代码是正确的,我们用malloc()函数分配存储空间,然后把字符串复制到新分配的空间。这里要理解的是:name字符串不是被存储在结构中,而是被保存在由malloc()函数管理的内存中。结构中仅仅是保存了name字符串的地址而已。还有一点要记得的是:我们使用malloc()函数分配内存之后要调用free()函数,不然可能会引起"内存泄露"。

转载于:https://www.cnblogs.com/zhouxuanyu/p/4514754.html

更多相关:

  • 一.  结构的基本知识 聚合数据类型能够存储多个数据,C语言提供了两种类型的聚合数据类型,数组和结构。数组是相同的数据,结构是不同类型的数据聚合。结构也是一些值得集合,这些值成为它的成员,每个结构都有它的名字,他们是通过名字来访问的。 1.      结构声明 在结构声明时,必须列出它包含的所有成员,这个列表包括每个成员的类型和...

  • Hibernate 配置参数hibernate.hbm2ddl.auto  Hibernate中的配置文件:              参数说明:   valid...

  • 一、一对多 以班级Classes和学生Student为例: 回忆sql语句: //内链接,两种方式效果一样,查询的是两边都有的数据SELECT c.*,s.* FROM classes c,student s WHERE s.cid=c.cid;SELECT c.cname,s.sname FROM classes c INNER...

  • 一、 Hibernate介绍     Hibernate是基于对象/关系映射(ORM,Object/Relational Mapping)的一个解决方案。ORM方案的思想是将对象模型表示的对象映射到关系型数据库中,或者反之。Hibernate目前是ORM思想在Java中最成功、最强大的实现。它于2001年的年末发布第一个版本,立即引...

  • char* Reverse(char* s) {//将q指向字符串最后一个字符char* q = s ;while( *q++ ) ;q -= 2 ; //分配空间,存储逆序后的字符串。char* p = newchar[sizeof(char) * (q - s + 2)] ; char* r = p ;// 逆序存储whil...

  • 二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {"abc", "def", "ghi"}; 这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char *...

  • 今天在弄一下啊小小程序的时候。报错,出现了问题。先看代码 int main(int argc, char* argv[]) {char *filename = "interface_ipset_1_1.json";char* split1 = "_";char* split2 = ".";char splitfile1[4][...

  • wchar_t*,wchar_t,wchat_t数组,char,char*,char数组,std::string,std::wstring,CString....#include // 使用CString必须使用MFC,并且不可包含#define _AFXDLL#include us...

  • 问题的提出:设计一个用于管理朋友信息的程序。将朋友信息(年龄、姓名、电话)存放在MyFrd.dat中,从文件读出这些信息并显示,并能按姓名(要求可简化输入,如只输入姓氏便可查询)进行查询,将查询信息输出屏幕。 1 #include 2 #include 3 #include<...