为什么 C 有 -> 之间的区别?和 .? [英] Why does C have a distinction between -> and .?

查看:13
本文介绍了为什么 C 有 -> 之间的区别?和 .?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,这不是什么严重的后果,但它一直困扰着我while:->. 运算符之间的区别是否有原因?

OK, this is of no serious consequence, but it's been bugging me for a while: Is there a reason for the distinction between the -> and . operators?

当然,目前的规则是 . 作用于结构体,而 -> 作用于指向结构(或联合)的指针.但这是它在实践中的工作方式.让 s 是一个包含元素 x 的结构,让 ps 是一个指向相同形式结构的指针.

Of course, the current rule is that . acts on a struct, and -> acts on a pointer-to-struct (or union). But here's how it works in practice. Let s be a struct incuding an element x, and let ps be a pointer to a struct of the same form.

如果你写

s->x

编译器会以这种方式吐出警告

the compiler will spit out a warning in the way of

你的意思是 s.x.请重新输入并重新编译.

You meant s.x. Please retype that and recompile.

如果你写

ps.x

编译器会以这种方式吐出警告

the compiler will spit out a warning in the way of

你的意思是 ps->x.请重新输入并重新编译.

You meant ps->x. Please retype that and recompile.

因为编译器在编译时知道 sps 的类型,所以它拥有解释正确操作符所需的所有信息.我怀疑这不像其他警告(比如缺少分号),因为正确修复没有歧义.

Because the compiler knows the type of both s and ps at compile time, it has all the information it needs to interpret what the correct operator would be. I suspect that this isn't like other warnings (like a missing semicolon), in that there is no ambiguity about the correct fix.

这里是给 C1x 标准委员会的假设性提案(永远不会考虑,因为 ISO 处于保守的状态):

So here's a hypothetical proposal to the C1x standards committee (that would never be considered, because the ISO is on a conservative streak):

给定表达式 lhs.rhs,如果 lhs 是结构或联合类型,那么表达式应引用名为 rhs 的 lhs 元素.如果 lhs 是指向结构的指针或 -union 的类型,那么这应该是解释为 (*lhs).rhs.

Given the expression lhs.rhs, if lhs is a struct or union type, then the expression shall refer to the element of lhs named rhs. If lhs is of type pointer-to-struct or -union, then this shall be interpreted as (*lhs).rhs.

这肯定会节省我们所有的时间,并使人们更容易学习 C [而且我已经教了足够多的 C 来权威地说学习者发现 -> 的东西要么是令人困惑或烦人.]

This would certainly save us all time, and make it easier for people to learn C [and I've taught enough C to say with authority that learners find the -> thing to be either confusing or annoying.]

甚至有先例,C 做了一些类似的事情.例如,出于实现的原因,函数声明总是被强制转换为指向函数的指针,所以 f(x,y)(*f)(x,y) 将无论 f 是被声明为函数还是函数指针,两者都可以工作.

There's even precedent, where C does a handful of similar things. E.g., for implementation reasons, function declarations are always cast to pointer-to-function, so f(x,y) and (*f)(x,y) will both work regardless of whether f was declared as a function or a pointer to function.

那么,我的问题是:这个提议有什么问题?你能想出在 ps.xs.x 之间存在致命歧义的例子,或者为什么保持强制性区别是有用的?

So, my question: what's wrong with this proposal? Can you think of examples where there would be fatal ambiguity between ps.x and s.x, or why keeping the mandatory distinction is otherwise useful?

推荐答案

好吧,如果你真的想把那种功能引入到 C 语言的规范中,那么为了使它与其余的融合"语言 合乎逻辑的做法是将衰减到指针"的概念扩展到结构类型.您自己制作了一个带有函数和函数指针的示例.它以这种方式工作的原因是因为 C 中的函数类型在所有上下文中都会衰减为指针类型,除了 sizeof 和一元 & 运算符.(同样的事情发生在数组上,顺便说一句.)

Well, if you really wanted to introduce that kind of functionality into the specification of C language, then in order to make it "blend" with the rest of the language the logical thing to do would be to extend the concept of "decay to pointer" to struct types. You yourself made an example with a function and a function pointer. The reason it works that way is because function type in C decays to pointer type in all contexts, except for sizeof and unary & operators. (The same thing happens to arrays, BTW.)

因此,为了实现类似于您建议的内容,我们可以引入结构到指针衰减"的概念,它的工作方式与 C 中的所有其他衰减"完全相同(即,数组到指针衰减和函数到指针衰减)工作:当在表达式中使用 T 类型的结构对象时,其类型立即衰减为类型 T* - 指向结构对象开头的指针 - 除非它是 sizeof 或一元 & 的操作数.一旦为结构引入了这样的衰减规则,您就可以使用 -> 运算符来访问结构元素,而不管左侧是指向结构的指针还是结构本身.在这种情况下,运算符 . 将变得完全没有必要(除非我遗漏了一些东西),你总是使用 -> 并且只使用 ->代码>.

So, in order to implement something similar to what you suggest, we could introduce the concept of "struct-to-pointer decay", which would work in exactly the same way as all other "decays" in C (namely, array-to-pointer decay and function-to-pointer decay) work: when a struct object of type T is used in an expression, its type immediately decays to type T* - pointer to the beginning of the struct object - except when it's an operand of sizeof or unary &. Once such a decay rule is introduced for structs, you could use -> operator to access struct elements regardless of whether you have a pointer to struct or the struct itself on the left-hand side. Operator . would become completely unnecessary in this case (unless I'm missing something), you'd always use -> and only ->.

以上,再一次,在我看来,如果本着C语言的精神来实现,这个特性会是什么样子.

The above, once again, what this feature would look like, in my opinion, if it was implemented in the spirit of C language.

但我想说(同意 Charles 所说的)在处理指向结构的指针的代码和处理结构本身的代码之间失去视觉区别并不是完全可取的.

But I'd say (agreeing with what Charles said) that the loss of visual distinction between the code that works with pointers to structs and the code that works with structs themselves is not exactly desirable.

附言这种结构衰减规则的一个明显负面后果是,除了当前的新手大军无私地相信数组只是常量指针"之外,我们还会有一大群新手无私地相信结构对象只是常量指针".Chris Torek 的数组 FAQ 必须大 1.5-2 倍才能涵盖结构:)

P.S. An obvious negative consequence of such a decay rule for structs would be that besides the current army of newbies selflessly believing that "arrays are just constant pointers", we'd have an army of newbies selflessly believing that "struct objects are just constant pointers". And Chris Torek's array FAQ would have to be about 1.5-2x larger to cover structs as well :)

这篇关于为什么 C 有 -> 之间的区别?和 .?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆