简体   繁体   English

为什么我们在定义指针时使用“type * var”而不是“type & var”?

[英]Why do we use “type * var” instead of “type & var” when defining a pointer?

I'm relatively new to C++ (about one year of experience, on and off).我对 C++ 比较陌生(大约一年的经验,断断续续)。 I'm curious about what led to the decision of type * name as the syntax for defining pointers.我很好奇是什么导致决定将type * name作为定义指针的语法。 It seems to me that the syntax should be type & name as the & symbol is used everywhere else in code to refer to the variable's memory address.在我看来,语法应该是type & name因为&符号在代码中的其他任何地方都用于引用变量的内存地址。 So, to use the traditional example of int pointers:因此,要使用int指针的传统示例:

int a = 1;
int * b = &a;

would become会成为

int a = 1;
int & b = &a

I'm sure there's some reason for this that I'm just not seeing, and I'd love to hear some input from C++ veterans.我确信这有一些我没有看到的原因,我很想听听 C++ 老手的一些意见。

Thanks, -S谢谢,-S

C++ adopts the C syntax. C++ 采用 C 语法。 As revealed in " The Development of the C Language " (by Dennis Ritchie) C uses * for pointers in type declarations because it was decided that type syntax should follow use.正如“ The Development of the C Language ”(Dennis Ritchie 着)中所揭示的,C 使用*作为类型声明中的指针,因为它决定类型语法应该遵循使用。

For each object of [a compound type], there was already a way to mention the underlying object: index the array, call the function, use the indirection operator [ * ] on the pointer.对于[复合类型]的每个对象,已经有一种提及底层对象的方法:索引数组,调用函数,在指针上使用间接运算符[ * ]。 Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear.类比推理导致名称的声明语法与名称通常出现的表达式语法的声明语法相同。 Thus,因此,

 int i, *pi, **ppi;

declare an integer, a pointer to an integer, a pointer to a pointer to an integer.声明一个整数,一个指向整数的指针,一个指向整数指针的指针。 The syntax of these declarations reflects the observation that i, *pi, and **ppi all yield an int type when used in an expression.这些声明的语法反映了当在表达式中使用时 i、*pi 和 **ppi 都产生 int 类型的观察结果。

Here's a more complex example:这是一个更复杂的例子:

int *(*foo)[4][];

This declaration means an expression *(*foo)[4][0] has type int , and from that (and that [] has higher precedence than unary * ) you can decode the type: foo is a pointer to an array of size 4 of array of pointers to ints.这个声明意味着一个表达式*(*foo)[4][0]具有类型int ,并且从那个(并且[]具有比一元*更高的优先级)你可以解码类型: foo 是一个指向大小数组的指针4 个指向整数的指针数组。

This syntax was adopted in C++ for compatibility with C. Also, don't forget that C++ has a use for & in declarations.这种语法在 C++ 中被采用是为了与 C 兼容。另外,不要忘记 C++ 在声明中使用了 &。

int & b = a;

The above line means a reference variable refering to another variable of type int .上面这行表示引用另一个int类型变量的引用变量。 The difference between a reference and pointer roughly is that references are initialized only, and you can not change where they point, and finally they are always dereferenced automatically.引用和指针的大致区别在于,引用只是初始化,不能改变指向的位置,最后总是自动解引用。

int x = 5, y = 10;
int& r = x;

int sum = r + y; // you do not need to say '*r' automatically dereferenced.

r = y; // WRONG, 'r' can only have one thing pointing at during its life, only at its infancy ;)

I think that Dennis Ritchie answered this in The Development of the C Language :我认为 Dennis Ritchie 在The Development of the C Language 中回答了这个问题:

For each object of such a composed type, there was already a way to mention the underlying object: index the array, call the function, use the indirection operator on the pointer.对于这种组合类型的每个对象,已经有一种方法可以提及底层对象:索引数组、调用函数、在指针上使用间接运算符。 Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear.类比推理导致名称的声明语法与名称通常出现的表达式语法的声明语法相同。 Thus,因此,

 int i, *pi, **ppi;

declare an integer, a pointer to an integer, a pointer to a pointer to an integer.声明一个整数,一个指向整数的指针,一个指向整数指针的指针。 The syntax of these declarations reflects the observation that i, *pi, and **ppi all yield an int type when used in an expression.这些声明的语法反映了当在表达式中使用时 i、*pi 和 **ppi 都产生 int 类型的观察结果。 Similarly,相似地,

 int f(), *f(), (*f)();

declare a function returning an integer, a function returning a pointer to an integer, a pointer to a function returning an integer;声明一个返回整数的函数,一个返回整数指针的函数,一个返回整数的函数指针;

 int *api[10], (*pai)[10];

declare an array of pointers to integers, and a pointer to an array of integers.声明一个指向整数的指针数组,以及一个指向整数数组的指针。 In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration.在所有这些情况下,变量的声明类似于它在表达式中的用法,该表达式的类型是在声明开头命名的类型。

So we use type * var to declare a pointer because this allows the declaration to mirror the usage (dereferencing) of the pointer.所以我们使用type * var来声明一个指针,因为这允许声明反映指针的使用(取消引用)。

In this article, Ritchie also recounts that in "NB", an extended version of the "B" programming language, he used int pointer[] to declare a pointer to an int , as opposed to int array[10] to declare an array of int s.在本文中,Ritchie 还讲述了在“NB”(“B”编程语​​言的扩展版本)中,他使用int pointer[]声明指向int的指针,而不是使用int array[10]声明数组的int s。

If you are a visual thinker, it may help to imagine the asterisk as a black hole leading to the data value.如果您是一名视觉思想家,将星号想象成导致数据值的黑洞可能会有所帮助。 Hence, it is a pointer.因此,它是一个指针。

The ampersand is the opposite end of the hole, think of it as an unraveled asterisk or a spaceship wobbling about in an erratic course as the pilot gets over the transition coming out of the black hole. &符号是黑洞的另一端,可以把它想象成一个解开的星号或一艘宇宙飞船,当飞行员克服从黑洞出来的过渡时,它在不稳定的航线中摇摆不定。

I remember being very confused by C++ overloading the meaning of the ampersand, to give us references.我记得被 C++ 重载 & 号的含义所迷惑,给我们提供参考。 In their desperate attempt to avoid using any more characters, which was justified by the international audience using C and known issues with keyboard limitations, they added a major source of confusion.他们不顾一切地试图避免使用更多字符,国际观众使用 C 和已知的键盘限制问题证明了这一点,他们增加了一个主要的混乱来源。

One thing that may help in C++ is to think of references as pre-prepared dereferenced pointers .在 C++ 中可能有帮助的一件事是将引用视为预先准备好的解引用指针 Rather than using &someVariable when you pass in an argument, you've already used the trailing ampersand when you defined someVariable.在传递参数时没有使用 &someVariable,而是在定义 someVariable 时使用了尾随与符号。 Then again, that might just confuse you further!再说一次,这可能只会让你更加困惑!

One of my pet hates, which I was unhappy to see promulgated in Apple's Objective-C samples, is the layout style int *someIntPointer instead of int* someIntPointer我的一个最厌恶的,我就不高兴了苹果的Objective-C的样品中看到的颁布,是布局风格int *someIntPointer而不是int* someIntPointer

IMHO, keeping the asterisk with the variable is an old-fashioned C approach emphasizing the mechanics of how you define the variable, over its data type.恕我直言,在变量中保留星号是一种老式的 C 方法,它强调如何定义变量的机制,而不是它的数据类型。

The data type of someIntPointer is literally a pointer to an integer and the declaration should reflect that. someIntPointer的数据类型someIntPointer是一个指向整数的指针,声明应该反映这一点。 This does lead to the requirement that you declare one variable per line, to avoid subtle bugs such as:这确实导致要求您每行声明一个变量,以避免出现细微的错误,例如:

int* a, b;  // b is a straight int, was that our intention?

int  *a, *b;  // old-style C declaring two pointers

int* a;
int* b;  // b is another pointer to an int

Whilst people argue that the ability to declare mixed pointers and values on the same line, intentionally, is a powerful feature, I've seen it lead to subtle bugs and confusion.虽然人们认为在同一行上有意地声明混合指针和值的能力是一个强大的功能,但我已经看到它会导致微妙的错误和混乱。

Your second example is not valid C code, only C++ code.你的第二个例子不是有效的 C 代码,只有 C++ 代码。 The difference is that one is a pointer, whereas the other is a reference.区别在于一个是指针,而另一个是引用。

On the right-hand side the '&' always means address-of.右侧的“&”始终表示地址。 In a definition it indicates that the variable is a reference.在定义中,它表明该变量是一个引用。

On the right-hand side the '*' always means value-at-address.在右侧,“*”始终表示地址处的值。 In a definition it indicates that the variable is a pointer.在定义中,它表明该变量是一个指针。

References and pointers are similar, but not the same.引用和指针相似,但又不一样。 This article addresses the differences. 本文解决了这些差异。

Instead of reading int* b as "b is a pointer to int", read it as int *b : "*b is an int".与其将int* b读作“b 是一个指向 int 的指针”,不如将其读作int *b :“*b 是一个 int”。 Then, you have & as an anti- * : *b is an int.然后,您将&作为反* :*b 是一个 int。 The address of *b is &*b , or just b. *b的地址是&*b ,或者只是 b。

I think the answer may well be "because that's the way K&R did it."我认为答案很可能是“因为 K&R 就是这样做的。”

K&R are the ones who decided what the C syntax for declaring pointers was. K&R 决定了声明指针的 C 语法是什么。

It's not int & x;这不是 int & x; instead of int * x;而不是 int * x; because that's the way the language was defined by the guys who made it up -- K&R.因为这就是语言的组成者定义语言的方式——K&R。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么只有函数指针而不是函数变量? - Why is there only pointer to function instead of var of function? `type * var =(int)0`,合法与否? - `type *var = (int)0`, legal or not? 取决于 if 循环的 var 类型 - Depending type of var on if loop 为什么在创建指针类型对象时内存没有分配给类? - Why memory is not allocated to class when we create pointer type object? 当我们通过引用传递时,为什么在调用函数时我们放置一个变量而不是地址(指针)? - When we pass by reference, why do we put a variable instead of address(pointer), when calling the function? C ++中是否有var类型的等价物? - Is there a var type equivalent in C++? 为什么编译器认为我没有为vector var指定类型? - Why compiler thinks I haven't named the type for a vector var? 使用decltype(var)后跟内部类型为“ var”的C ++ 11编译器错误 - C++11 compiler error when using decltype(var) followed by internal type of “var” 我们需要使用指针类型的CTOR显式吗? - Do we need explicit for CTOR with pointer type? Why we use pointer to integer for max stl function instead for size_t data type(which is generally use) for array of characters in c++? - Why we use pointer to integer for max stl function instead for size_t data type(which is generally use) for array of characters in c++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM