C++ 在指针声明中放置星号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/180401/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:29:28  来源:igfitidea点击:

Placement of the asterisk in pointer declarations

c++cpointersdeclaration

提问by Michael Stum

I've recently decided that I just have to finally learn C/C++, and there is one thing I do not really understand about pointers or more precisely, their definition.

我最近决定我只需要最终学习 C/C++,关于指针,或者更准确地说,我不太了解它们的定义。

How about these examples:

这些例子怎么样:

  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;
  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;

Now, to my understanding, the first three cases are all doing the same: Test is not an int, but a pointer to one.

现在,据我所知,前三种情况都在做同样的事情:Test 不是一个 int,而是一个指向一个的指针。

The second set of examples is a bit more tricky. In case 4, both test and test2 will be pointers to an int, whereas in case 5, only test is a pointer, whereas test2 is a "real" int. What about case 6? Same as case 5?

第二组例子有点棘手。在情况 4 中,test 和 test2 都是指向 int 的指针,而在情况 5 中,只有 test 是一个指针,而 test2 是一个“真正的”int。案例6呢?和案例5一样吗?

回答by Milan Babu?kov

4, 5, and 6 are the same thing, only testis a pointer. If you want two pointers, you should use:

4、5、6是同一个东西,只有test是一个指针。如果你想要两个指针,你应该使用:

int *test, *test2;

Or, even better (to make everything clear):

或者,甚至更好(让一切都清楚):

int* test;
int* test2;

回答by Ates Goral

White space around asterisks have no significance. All three mean the same thing:

星号周围的空白没有意义。这三个意思是一样的:

int* test;
int *test;
int * test;

The "int *var1, var2" is an evil syntax that is just meant to confuse people and should be avoided. It expands to:

" int *var1, var2" 是一种邪恶的语法,只是为了混淆人们,应该避免。它扩展为:

int *var1;
int var2;

回答by Michael Burr

Use the "Clockwise Spiral Rule"to help parse C/C++ declarations;

使用“顺时针螺旋规则”帮助解析 C/C++ 声明;

There are three simple steps to follow:

  1. Starting with the unknown element, move in a spiral/clockwise direction; when encountering the following elements replace them with the corresponding english statements:

    [X]or []: Array X size of... or Array undefined size of...

    (type1, type2): function passing type1 and type2 returning...

    *: pointer(s) to...

  2. Keep doing this in a spiral/clockwise direction until all tokens have been covered.
  3. Always resolve anything in parenthesis first!

只需遵循三个简单的步骤:

  1. 从未知元素开始,沿螺旋/顺时针方向移动;当遇到以下元素时,用相应的英文语句替换它们:

    [X][]:数组 X 大小...或数组未定义大小...

    (type1, type2): 函数传递 type1 和 type2 返回...

    *: 指向...的指针

  2. 继续以螺旋/顺时针方向执行此操作,直到覆盖所有标记。
  3. 总是先解决括号中的任何问题!

Also, declarations should be in separate statements when possible (which is true the vast majority of times).

此外,声明应该在可能的情况下在单独的语句中(绝大多数情况下都是如此)。

回答by Scott Langham

Many coding guidelines recommend that you only declare one variable per line. This avoids any confusion of the sort you had before asking this question. Most C++ programmers I've worked with seem to stick to this.

许多编码指南建议您每行只声明一个变量。这可以避免您在问这个问题之前遇到的任何混淆。我共事过的大多数 C++ 程序员似乎都坚持这一点。



A bit of an aside I know, but something I found useful is to read declarations backwards.

我知道有点旁白,但我发现有用的是向后阅读声明。

int* test;   // test is a pointer to an int

This starts to work very well, especially when you start declaring const pointers and it gets tricky to know whether it's the pointer that's const, or whether its the thing the pointer is pointing at that is const.

这开始工作得很好,特别是当你开始声明 const 指针时,很难知道它是 const 的指针,还是指针指向的东西是 const 的。

int* const test; // test is a const pointer to an int

int const * test; // test is a pointer to a const int ... but many people write this as  
const int * test; // test is a pointer to an int that's const

回答by huskerchad

As others mentioned, 4, 5, and 6 are the same. Often, people use these examples to make the argument that the *belongs with the variable instead of the type. While it's an issue of style, there is some debate as to whether you should think of and write it this way:

正如其他人提到的,4、5 和 6 是相同的。通常,人们使用这些例子来证明*属于变量而不是类型。虽然这是一个风格问题,但关于您是否应该以这种方式思考和编写它存在一些争论:

int* x; // "x is a pointer to int"

or this way:

或者这样:

int *x; // "*x is an int"

FWIW I'm in the first camp, but the reason others make the argument for the second form is that it (mostly) solves this particular problem:

FWIW 我在第一个阵营,但其他人为第二种形式提出论点的原因是它(主要)解决了这个特殊问题:

int* x,y; // "x is a pointer to int, y is an int"

which is potentially misleading; instead you would write either

这可能具有误导性;相反,你会写

int *x,y; // it's a little clearer what is going on here

or if you really want two pointers,

或者如果你真的想要两个指针,

int *x, *y; // two pointers

Personally, I say keep it to one variable per line, then it doesn't matter which style you prefer.

就我个人而言,我说每行保持一个变量,那么你喜欢哪种风格并不重要。

回答by fredoverflow

#include <type_traits>

std::add_pointer<int>::type test, test2;

回答by 1800 INFORMATION

In 4, 5 and 6, testis always a pointer and test2is not a pointer. White space is (almost) never significant in C++.

在 4、5 和 6 中,test始终是指针而test2不是指针。空白在 C++ 中(几乎)从不重要。

回答by deLock

In my opinion, the answer is BOTH, depending on the situation. Generally, IMO, it is better to put the asterisk next to the pointer name, rather than the type. Compare e.g.:

在我看来,答案是两者兼而有之,视情况而定。通常,IMO,最好将星号放在指针名称旁边,而不是类型。比较例如:

int *pointer1, *pointer2; // Fully consistent, two pointers
int* pointer1, pointer2;  // Inconsistent -- because only the first one is a pointer, the second one is an int variable
// The second case is unexpected, and thus prone to errors

Why is the second case inconsistent? Because e.g. int x,y;declares two variables of the same type but the type is mentioned only once in the declaration. This creates a precedent and expected behavior. And int* pointer1, pointer2;is inconsistent with that because it declares pointer1as a pointer, but pointer2is an integer variable. Clearly prone to errors and, thus, should be avoided (by putting the asterisk next to the pointer name, rather than the type).

为什么第二种情况不一致?因为 egint x,y;声明了两个相同类型的变量,但在声明中只提到了一次类型。这创造了一个先例和预期的行为。并且int* pointer1, pointer2;与此不一致,因为它声明pointer1为指针,但它pointer2是一个整数变量。显然容易出错,因此应该避免(通过将星号放在指针名称旁边,而不是类型)。

However, there are some exceptionswhere you might not be able to put the asterisk next to an object name (and where it matters where you put it) without getting undesired outcome — for example:

但是,在某些例外情况下,您可能无法将星号放在对象名称旁边(以及放置它的位置很重要)而不会得到不想要的结果——例如:

MyClass *volatile MyObjName

MyClass *volatile MyObjName

void test (const char *const p) // const value pointed to by a const pointer

void test (const char *const p) // const value pointed to by a const pointer

Finally, in some cases, it might be arguably clearerto put the asterisk next to the typename, e.g.:

最后,在某些情况下,将星号放在类型名称旁边可能会更清楚,例如:

void* ClassName::getItemPtr () {return &item;} // Clear at first sight

void* ClassName::getItemPtr () {return &item;} // Clear at first sight

回答by TheDrev

I would say that the initial convention was to put the star on the pointer name side (right side of the declaration

我会说最初的约定是将星号放在指针名称一侧(声明的右侧

You can follow the same rules, but it's not a big deal if you put stars on the type side. Remember that consistencyis important, so always but the star on the same side regardless of which side you have choose.

你可以遵循同样的规则,但如果你在字体上加上星星,这没什么大不了的。请记住,一致性很重要,因此无论您选择哪一边,始终是同一边的明星。

回答by Michel Billaud

The rationale in C is that you declare the variables the way you use them. For example

C 语言的基本原理是您可以按照使用变量的方式声明变量。例如

char *a[100];

says that *a[42]will be a char. And a[42]a char pointer. And thus ais an array of char pointers.

说那 *a[42]将是一个char. 和a[42]一个字符指针。因此a是一个字符指针数组。

This because the original compiler writers wanted to use the same parser for expressions and declarations. (Not a very sensible reason for a langage design choice)

这是因为最初的编译器编写者希望对表达式和声明使用相同的解析器。(不是语言设计选择的一个非常明智的理由)