&&在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日

相关推荐

  • 圆周率手抄报(圆周率手抄报内容)

    参考《贪玩的人类》著作 科学,很可怕吗,只要你有一种坚持不懈的精神,就适合探索科学 遥想远古时代,几万年前,文明的在一个个远古时代人的头脑中生根发芽,当人类第一次使用火的时候,当人类开始发明工具的时候,当人类不使命运所屈服的时候,就注定了人类的不平凡 动物和人类的区别在于,屈服于命运我因为环境所改变,可人类呢,不屈服于命运,好奇探索一切事物,极限,对于我们来…

    2023年 5月 2日
  • 分期乐是正规借款平台吗(分期乐是正规借款平台吗会上征信吗)

    50659 李倩 现在人们为了减轻消费负担,在消费支付时大多都会选择分期或者借款,所以金融分期贷款产品如今很受人们的欢迎,但这类产品一多,人们在选择时难免就会产生困惑,不知道该选择哪一家好,比如说分期乐,就有些人想知道它好不好,以及在分期乐借款靠谱吗?>>进入大额分期口子大全,额度最高20万,最多可分60期! 想要知道更多的相关信息了解详情。 分…

    2022年 10月 11日
  • STARL币合约地址是多少?星链币合约地址介绍

    今天小编要为大家介绍的这一币种就是STARL币,它也是近期爆火的元宇宙项目之一。STARL币这一项目的核心理念就是以一种更加公平和可持续的方式来完成自己的目标,并且争取让每个参与此项目的人都能够受益。STARL的项目方希望用户可可以真正的在这个游戏中玩得开心,更加自由的互动,并通过在该游戏的活动来实现财务自由的机会。努力向在线互动发展的下一阶段前进。很多投资…

    2023年 3月 26日
  • 2021gdp省份排名中国(2021gdp城市排名中国)

    最近有很多朋友都想知道2021gdp省份排名中国是什么。今天小编特意为大家整理了相关知识来解答!还有其他网友想搞清楚2021gdp城市排名中国,句子百科(www.sws100.com)已经为你找到了相关问题的答案,接下来一起看看吧,希望能给大家带来帮助。 关于城市的建设发展,自古以来都是我们关注的热点话题,如何能够通过一组数据奇观地了解到一座城市,或者说一个…

    2022年 9月 5日
  • 高铁一等座跟二等座有什么区别(高铁一等座跟二等座有什么区别知乎)

    现在的高铁发展越来越好 已经成为我们生活中 必不可少的交通工具 很多小伙伴都很好奇 为什么高铁的不同舱位之间 价格相差如此之大 今天小智来给大家揭秘 不同的舱位之间 到底有何不同 ↓记得点赞收藏哦↓ 座位数量不同 商务座:商务座一般有10个,分别在高铁的首尾两个车厢,每个车厢里面设有5个座位,前排1+1布局两个座位,第二排1+2布局3个座位,空间会格外的宽敞…

    2023年 5月 22日

联系我们

在线咨询: QQ交谈

邮件:k37759@foxmail.com

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

关注微信