C语言结构体内数组成员与指针成员有何区别?

目录

1.结构体中的成员

2.结构体里的数组名

3.数组名与指针的区别


1.结构体中的成员

要明白结构体内数组成员与指针成员有何区别,我们首先要知道结构体内 成员们是如何存储的,

当我们要访问它们时,是怎样找到它们的。

首先我们需要知道——所谓变量,其实是内存地址的一个抽像名字罢了。在静态编译的程序中,所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字的,只知道地址。

有了上面这个基础,我们来看一下结构体中的成员的地址是什么?

有如下代码方便我们分析:

可以看见:1.成员a的地址和结构体的地址是一样的 2.b的地址就是结构体地址0加上b与结构体地址的偏移量4;c也一样如此。

可以得出 不管结构体的实例是什么——访问其成员其实就是加成员的偏移量。类似于数组成员的访问,只是结构体中元素的直接的距离(结构体需要对齐)是不一样的。

2.结构体里的数组名

在以上基础上,我们可以想想 那结构体中数组成员的数组名代表什么呢?

我们知道在通常情况下(在结构体之外)数组名的内容为其首元素的地址,如图:

那么其实在结构体中也一样 ,结构体地址+数组起始地址与结构体起始地址的偏移量。如图:

 

其实并没有一块真正的内存空间来存放数组名的值,数组名只是这个这个数组所在内存空间的一个地址代号而已,于变量名一个道理。

 

3.结构体里的数组名与指针的区别

1.基于以上  “其实并没有一块真正的内存空间来存放数组名的值,数组名只是这个这个数组所在内存空间的一个地址代号而已”  的理解 ,无论结构体是否初始化,只要知道结构体类型,数组名的内容都是不变的。他的内容始终为结构体地址+数组起始地址与结构体起始地址的偏移量

2. 而指针就不一样了
指针的内容是有一块具体的内存空间来存储的,当结构体没有初始化时,这个内存空间就是非法访问的。

4 总结

基于这篇文章,很多人心中的 "数组名==指向数组首元素地址的指针"自然是站不住脚跟的,虽然,在多数情况下可以这样歪曲的解释,但在某些时候肯定是会吃瘪的。

比如当我们遇到下面这个问题时:

问题来源 C语言结构体里的成员数组和指针 | 酷 壳 - CoolShellicon-default.png?t=M0H8https://coolshell.cn/articles/11377.html

问:为什么程序走到第13行不崩,14行崩掉了?

如果你仔细阅读了这篇博客,你会很容易得出答案:

1.为什么第13行不报错

第13行拿到数组名,基于以上  “其实并没有一块真正的内存空间来存放数组名的值,数组名只是这个这个数组所在内存空间的一个地址代号而已”  的理解 ,无论结构体是否初始化,只要知道结构体类型,数组名的内容都是不变的。他的内容始终为结构体地址+数组起始地址与结构体起始地址的偏移量,因为第12行将结构体指针初始化为0,那么它所指向的结构体地址就为0,再根据结构体类型得出数组与结构体的偏移量为4,所以这里数组名也就是f.a->s的值就是0+4==4,为真。

2.为什么第14行报错

指针的内容是有一块具体的内存空间来存储的,那当程序走到第14行,这个结构体并没有被初始化,这个内存空间就是非法访问的。自然会报错。

希望这篇博客能对你有帮助!可以的话顺手点赞收藏一波。

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值