目录
1.结构体中的成员
要明白结构体内数组成员与指针成员有何区别,我们首先要知道结构体内 成员们是如何存储的,
当我们要访问它们时,是怎样找到它们的。
首先我们需要知道——所谓变量,其实是内存地址的一个抽像名字罢了。在静态编译的程序中,所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字的,只知道地址。
有了上面这个基础,我们来看一下结构体中的成员的地址是什么?
有如下代码方便我们分析:
可以看见:1.成员a的地址和结构体的地址是一样的 2.b的地址就是结构体地址0加上b与结构体地址的偏移量4;c也一样如此。
可以得出 不管结构体的实例是什么——访问其成员其实就是加成员的偏移量。类似于数组成员的访问,只是结构体中元素的直接的距离(结构体需要对齐)是不一样的。
2.结构体里的数组名
在以上基础上,我们可以想想 那结构体中数组成员的数组名代表什么呢?
我们知道在通常情况下(在结构体之外)数组名的内容为其首元素的地址,如图:
那么其实在结构体中也一样 ,结构体地址+数组起始地址与结构体起始地址的偏移量。如图:
其实并没有一块真正的内存空间来存放数组名的值,数组名只是这个这个数组所在内存空间的一个地址代号而已,于变量名一个道理。
3.结构体里的数组名与指针的区别
1.基于以上 “其实并没有一块真正的内存空间来存放数组名的值,数组名只是这个这个数组所在内存空间的一个地址代号而已” 的理解 ,无论结构体是否初始化,只要知道结构体类型,数组名的内容都是不变的。他的内容始终为结构体地址+数组起始地址与结构体起始地址的偏移量
2. 而指针就不一样了
指针的内容是有一块具体的内存空间来存储的,当结构体没有初始化时,这个内存空间就是非法访问的。
4 总结
基于这篇文章,很多人心中的 "数组名==指向数组首元素地址的指针"自然是站不住脚跟的,虽然,在多数情况下可以这样歪曲的解释,但在某些时候肯定是会吃瘪的。
比如当我们遇到下面这个问题时:
问题来源 C语言结构体里的成员数组和指针 | 酷 壳 - CoolShellhttps://coolshell.cn/articles/11377.html
问:为什么程序走到第13行不崩,14行崩掉了?
如果你仔细阅读了这篇博客,你会很容易得出答案:
1.为什么第13行不报错
第13行拿到数组名,基于以上 “其实并没有一块真正的内存空间来存放数组名的值,数组名只是这个这个数组所在内存空间的一个地址代号而已” 的理解 ,无论结构体是否初始化,只要知道结构体类型,数组名的内容都是不变的。他的内容始终为结构体地址+数组起始地址与结构体起始地址的偏移量,因为第12行将结构体指针初始化为0,那么它所指向的结构体地址就为0,再根据结构体类型得出数组与结构体的偏移量为4,所以这里数组名也就是f.a->s的值就是0+4==4,为真。
2.为什么第14行报错
指针的内容是有一块具体的内存空间来存储的,那当程序走到第14行,这个结构体并没有被初始化,这个内存空间就是非法访问的。自然会报错。
希望这篇博客能对你有帮助!可以的话顺手点赞收藏一波。