Placement of the asterisk in pointer declarations

2018-12-31 15:51发布

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.

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;

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

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?

13条回答
永恒的永恒
2楼-- · 2018-12-31 16:08

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

int *test, *test2;

Or, even better (to make everything clear):

int* test;
int* test2;
查看更多
只若初见
3楼-- · 2018-12-31 16:09

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

char *a[100];

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

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)

查看更多
其实,你不懂
4楼-- · 2018-12-31 16:13

Cases 1, 2 and 3 are the same, they declare pointers to int variables. Cases 3, 4 and 5 are the same, as they declare one pointer to, and one int variable respectively. If you want do declare two pointers in one line (which you shouldn't), you need to put an asterisk in front of each variable name:

int *test, *test2;

There is no certain correct way that says where the asterisk goes. int* test looks better because it is easier for us to imagine that appending * to the end of a type means "pointer to" that type. However, int *test makes more sense, because you can work with it like the minus sign in maths:

-(-x) = x

is analogous to

*(*test) = test

This has always helped me. Sadly, the upshot of it all is that sometimes I use int* test and sometimes int *test.

查看更多
只靠听说
5楼-- · 2018-12-31 16:15
#include <type_traits>

std::add_pointer<int>::type test, test2;
查看更多
孤独寂梦人
6楼-- · 2018-12-31 16:16

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

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!

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

查看更多
不流泪的眼
7楼-- · 2018-12-31 16:17

The pointer is a modifier to the type. It's best to read them right to left in order to better understand how the asterisk modifies the type. 'int *' can be read as "pointer to int'. In multiple declarations you must specify that each variable is a pointer or it will be created as a standard variable.

1,2 and 3) Test is of type (int *). Whitespace doesn't matter.

4,5 and 6) Test is of type (int *). Test2 is of type int. Again whitespace is inconsequential.

查看更多
登录 后发表回答