&&在c语言中表示什么

基本上,每一个C语言程序员都明白点运算符“.”和箭头运算符“->”可以用于访问结构体的成员,只不过箭头运算符“->”需要与结构体指针结合使用。事实上按照现在流行的C语言语法,通过结构体指针直接访问成员,也只能通过箭头运算符。

struct test *x;
x.member = 1; // 非法
x->member = 1; // 合法
&&在c语言中表示什么

C语言为何要有“->”运算符?

C语言为何要有“->”运算符?

抛开结构体不谈,C语言中的指针本身并无需要用到点运算符“.”的地方,因此结构体指针与点运算符“.”结合时,编译器把这种结合解释为访问结构体成员,按理说并不会产生歧义,C语言以语法简洁闻名,那为什么还要提供“多余”的“->”运算符呢?或者说,C语言中的箭头运算符“->”有什么历史渊源吗?

上述问题其实可以简化成两个子问题,一是为什么C语言要有“->”运算符,再就是为什么C语言中的“.”运算符不能与结构体指针结合访问成员。

C语言“->”运算符的历史

其实,在C语言的第一个版本(相关C参考手册(C Reference Manual,CRM)在1975年5月随第6版Unix一起发布)中,“->”运算符并不像今天一样与“.”运算符同义,而是另有一种特有的含义。

&&在c语言中表示什么

CRM 所描述的C语言在许多方面都与现代C语言有很大的不同

CRM 所描述的C语言在许多方面都与现代C语言有很大的不同,例如 CRM 的结构体成员实现了全局字节偏移的概念,没有类型限制,可以访问任意地址。也就是说,当时的C语言中,所有的结构体成员的名字都具有独立的全局含义,因此所有结构体的成员名都不能一样。

struct S {
 int a;
 int b;
};

上面这几行C语言代码定义了结构体 S,成员 a 代表 0 偏移,而成员 b 则代表 2 字节偏移(这里假设 int 变量占用 2 字节内存,也不考虑内存对齐)。

当时C语言做了这样的限制:所有结构体的所有成员,要么有唯一的名字,要么代表唯一的字节偏移量,例如:

struct X {
 int a;
 int x;
};

上述代码定义了结构体 X,它也包含成员 a,它的名字与结构体 S 中的成员 a 重复了,但是没有问题,因为它们都代表 0 偏移。下面这种定义就属于非法了:

struct Y {
 int b;
 int a;
};

因为结构体 Y 中的成员 a 与结构体 S 中的成员 a 重名,并且代表的字节偏移量也不相等。

&&在c语言中表示什么

早期箭头运算符“->”是用于确定偏移量的

在当时的C语言语法中,箭头运算符“->”就是用于确定偏移量的。既然每个结构体的成员代表的字节偏移量都是全局的,那么下面这样的语句也是合法的:

int i = 5;
i->b = 42;
100->a = 0;

上述几行C语言代码的意义很明确:i->b 表示以 5 为基准的 2 字节偏移处,因此 i->b=42; 的意思是将地址 7 处的 int 值设置为 42。同样的道理,100->a=0; 则表示将地址 100 处的 int 值设置为 0。

读者应注意,在当时版本的C语言中,箭头运算符“->”并不关心它的左表达式,因此哪怕 100->a 也是合法的。

&&在c语言中表示什么

箭头运算符“->”并不关心它的左表达式

这样利用结构体成员偏移量的做法对于“* ”和“.”运算符的组合是不可用的,例如

int i = 5;
(*i).b = 42;

*i 本身就是一个无效的表达式,“* ”是一个独立的运算符,因此对其操作数施加了更加严格的类型要求。当时 CRM 引入箭头运算符“->”就是用于解决这种限制带来的不便的。

后来,在 K&R 设计的C语言中,许多 CRM 中的功能被重新设计,“结构体成员作为全局偏移标识符”的设计被完全推翻,此后箭头运算符“->”的功能与“* ”和“.”运算符结合的功能完全相同。

为什么C语言不支持“.”运算符与结构体指针结合访问成员?

同样,在 CRM 描述的C语言中,“.”运算符的左操作数被要求必须是一个左值,这也是它与“->”运算符不同的原因,如上所述。请注意,CRM 不需要“.”运算符的左操作数是结构体类型的,它只要求左操作数是左值。

这里读者应该区分“左操作数”和“左值”。

&&在c语言中表示什么

应该区分“左操作数”和“左值”

这意味着在 CRM 版本的C语言中,程序员可以编写下面这样的代码:

struct S { int a, b; };
struct T { float x, y, z; };
struct T c;
c.b = 55;

读者应该注意到结构体 T 并没有成员 b,但是 c.b=55; 却仍然是合法的,这是因为编译器不关心变量 c 的类型,它只关心 c 是否一个左值:某种可写的内存块。因此 c.b=55; 的意义是将 55 写入名为 c 的连续内存块中字节偏移量 2 处的 int 值中。

因此,如果我们写了下面这样的C语言代码:

S *s;
...
s.b = 42;

编译器将认为这样是有效的,因为 s 也是一个左值。最终得到的C语言程序将尝试将 42 写到指针变量 s 本身(而不是它指向的结构体)所在连续内存字节偏移量 2 处。不用说,这样的结果必定会产生预料之外的结果,很可能带来内存溢出,但是编程语言本身并不关心这些事情。

&&在c语言中表示什么

编程语言本身并不关心这些事情

也就是说,在那个版本的C语言中,对“.”运算符重载(使其支持通过结构体指针访问成员)根本就行不通,因为“.”运算符与指针结合时,已经具备自己的含义了(与左值结合,访问指定偏移量的内存)。虽然以今天的眼光来看,这样的设计很古怪,但是当时的确就是这样设计的。

当然了,这样的奇怪设计并不是“.”运算符不能与结构体指针结合使用访问成员的充足理由,但是后来 K&R 在重新设计C语言时没有考虑重载“.”运算符,应该是需要兼容之前版本的C语言,毕竟历史遗留下来的C语言代码也是需要得到支持的。

最后

可能也有读者认为,即使是今天的C语言,似乎“->”运算符也不是必须的,因为“* ”和“.”运算符结合就能轻易的代替它:

struct S *p;
p->b = 3;
// 完全可以使用下面这样的语句替换
(*p).b = 3;

既然简洁是C语言的特点,就应该做到极致,何必提供“多余的”箭头运算符“->”呢?的确如此,就功能性而言,“->”完全可以不要,但是在C语言程序开发中,我们还需要考虑程序员的感受,请看下面这两种写法:

(*(*(*a).b).c).d
a->b->c->d

它们的功能是一致的,但是第二种写法无论是书写,还是阅读,都要简洁的多。

&&在c语言中表示什么

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

未经许可,禁止转载。

免责声明: 文章源于会员发布,不作为任何投资建议

如有侵权请联系我们删除,本文链接:https://www.sws100.com/baike/332942.html

(0)
鸟叔鸟叔
上一篇 2023年 4月 9日
下一篇 2023年 4月 9日

相关推荐

  • 食品安全的重要性(幼儿园食品安全的重要性)

    不管是在实体店还是在网上购物,对于食品的安全性永远是需要重视的。食品的安全不仅是健康的保证,也是食品行业在未来的发展中能够形成秩序,让食品行业更加规范合理化。食品行业标识一般是食品生产厂家在外包装上喷印食品生产日期及保质期、生产批号等内容。标识是食品行业生产厂家对于消费者的一种承诺,消费者形成查看食品标识的习惯,能降低购买到变质食品的几率。 ?食品喷码机为食…

    2022年 10月 14日
  • 岁月神偷原唱(岁月神偷原唱金玟岐)

    [闽南网] 抖音上面好听的歌曲真的很多,而且总是让我们听到很多新鲜的歌曲,来看看抖音时间是让人猝不及防的东西什么歌? 抖音时间是让人猝不及防的东西什么歌: 《岁月神偷》,歌曲的原唱是金玟岐。 《岁月神偷》是音乐人金玟岐自主创作的音乐作品,该作品由金玟岐自行作词及作曲,薛琳可编曲。 岁月神偷歌词介绍: 词:金玟岐 曲:金玟岐 能够握紧的就别放了 能够拥抱的就别…

    社会百科 2023年 4月 25日
  • 龙腾虎跃的意思(龙腾虎跃的寓意及象征)

    这个寒假,央视少儿频道为大家准备了一档有趣又有料的节目——《赢在博物馆》。同时,央视少儿微信公众号也为小朋友们推出【看文物学成语】系列。今天我们给大家介绍一个很“威风”的成语,它涵盖了十二生肖中的两只动物,它就是: [lóng téng hǔ yuè] 龙腾虎跃 成语释义: 像龙在飞腾,虎在跳跃,形容威武雄壮,非常活跃。龙腾虎跃也比喻奋起行动,有所作为。 成…

    2023年 2月 24日
  • 梁山好汉排名108位(梁山好汉排名108位晁盖)

    水浒传108将排名: 1 天魁星 呼保义 宋江 2 天罡星 玉麒麟 卢俊义 3 天机星 智多星 吴用 4 天闲星 入云龙 公孙胜 5 天勇星 大刀 关胜 6 天雄星 豹子头 林冲 7 天猛星 霹雳火 秦明 8 天威星 双鞭 呼延灼 9 天英星 小李广 花荣 10 天贵星 小旋风 柴进 11 天富星 扑天雕 李应 12 天満星 美髯公 朱仝 13 天孤星 花和…

    2022年 11月 8日
  • 怎么退货给卖家淘宝(如何退货给卖家淘宝)

    随着网购的兴起,很多消费者选择在网上购物,但因为网购无法直观地感受到商品的质量和样式,商品到手之后,发现有些问题,于是就想要进行退货、退款,但又不知道该如何操作,本期文章就说说“商品在满足退货条件”的情况下,如何进行退货退款流程。 正常来讲,只要商品不影响二次销售,且没有出现人为损坏的情况下,是可以直接通过网购平台的聊天软件与商家沟通,商家同意退款后,直接在…

    2022年 8月 13日

联系我们

在线咨询: QQ交谈

邮件:k37759@foxmail.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信