欢迎点击「算法与编程之美」↑关注我们!
本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列博客。
1 问题描述
在学习C语言的时候,我们都会频繁的接触到结构体,使用结构体定义新的数据类型,从而更加方便的存储数据。但是在使用结构体的时候,有些问题会经常会困扰我们,如下所示:
第一种结构体定义:
struct school{
char address[100];
char name[30];
};
第二种结构体定义:
struct school_other{
char *address;
char *name;
};
以上两种结构体的定义有什么区别?我们在使用的时候需要注意什么?
本文将和大家一起来深入的探讨这个问题。
2 分析问题
很多时候对于大家来说,最重要的不是得到问题的答案,而是学会别人是如何分析问题的,这种解决问题的思路对于大家来说才是最重要的,也是最精彩的地方。
C语言中定义的任何一个变量,最终都会从你的内存条上拿走相应的内存空间,如定义了一个int a;那么四个字节的空间就给a这个变量了。既然如此,我们很好奇,上述两种类型的结构体,分别占用了多大的内存空间呢?为了解决这个问题,我们编写了以下的程序:
这个程序应该很简单,相信各位同学都能看懂,首先定义了两个结构体类型struct school和struct school_other,然后在main函数中定义了两个变量,最后使用sizeof()函数获得变量的内存空间大小。
程序的输出结果如下:
这种输出结果不知是大家意料之中还是意料之外呢?无论是哪种情况,我们一起来分析分析。
如果要我们去计算第一个结构体的内存占用空间,你该如何去计算?
struct school{
char address[100];
char name[30];
};
由于sizeof(char)==1得到每一个字符型数据占用的空间大小是一个字节,因此上述结构体占用的空间应该是:1 Byte * 100 + 1 Byte * 30 = 130 Byte,这个答案和输出的结果是一致的。
按照同样的方式我们去计算另外一个结构体的内存占用空间:
struct school_other{
char *address;
char *name;
};
由于sizeof(char *) == 8得到每一个指针类型的数据占用的空间是八个字节,因此上述结构体占用的空间应该是:8 Byte * 1 + 8 Byte * 1 = 16 Byte,这个答案也和输出结果一致。
为什么要花这么多的篇幅去介绍结构体类型空间大小呢?
貌似和主题无关,其实正是深入理解主题的核心所在。本文定义一个school结构体的目的在于通过school结构体能够保存某个学校的地址和名称,而地址和名称都是字符数组类型,这种类型可以保存多个字符。
struct school这种结构体类型为其成员变量address和name分配了大小分别为100和30的内存空间,有了内存空间,因此可以直接使用。
而struct school_other这种结构体类型并没有为其成员变量分配内存空间,因此在使用之前必须对其分配,才可以为其赋值。
上述问题,其实可以进一步简化成:
char address[100];
char* address_other;
这两种变量大家在使用时,应该注意什么?
address变量已经有了100个字节的内存空间,因此可以直接对其进行赋值,而address_other只是一个指针即只是一个内存地址,而这个地址是多少并未知晓,因此在使用之前,务必要分配内存空间,然后才能使用。
3 总结
本文介绍了结构体指针类型的成员变量和数组类型的成员变量的区别,以及在使用时应该注意的问题,帮助大家更好的理解内存分配。
更多精彩文章:
来源:oschina
链接:https://my.oschina.net/u/271937/blog/1790127