Is there a convention for pointer declarations in

2020-05-23 01:28发布

When declaring pointers in C, there are 3 variants:

Variant A:

int* ptr;

Variant B:

int *ptr;

Variant C:

int * ptr;
  • In A, the indirection operator has been appended to the type.
  • In B, the indirection operator has been prepended to the variable.
  • In C, the indirection operator stands freely in between type and variable.

The way a pointer is declared differs depending on the type of documentation I read. Some authors seem to have a preference for certain variants, others use several.

  • Am I correct to assume that there is no difference in functionality between the different variants?
  • If yes, is there a convention for which variant one should be using in C?

8条回答
狗以群分
2楼-- · 2020-05-23 01:55

C declarations are based around the types of expressions, not objects.

If you have a pointer to an int named pi, and you want to access the integer value that it points to, you have to dereference the pointer, as in:

x = *pi;
printf("%d", *pi);
*pi = 1 + 2;

etc. The type of the expression *pi is int: therefore, the declaration should read as

int *pi;

Now let's suppose you had an array of pointers to char; to get to any character, you need to first subscript into the array, then dereference the result:

c = *pc[i];
if (*pc[j] == 'a') {...}

etc. Again, the type of the expression *pc[i] is char, so the declaration reads as

char *pc[N];

Both *pi and *pc[N] are known as declarators, and specify additional type information not given by the type specifier. IOW, the array-ness and pointer-ness of pc are specified as part of the declarator, while the char-ness is given by the type specifier.

As to the question of which is style is proper...

Neither one is "right", but I (and many other C programmers) prefer to write T *p as opposed to T* p, since it more closely reflects the language grammar (the * is part of the declarator) and it helps avoid confusion when declaring multiple items. I've seen far too many examples of people writing T* a, b; and expecting b to be a pointer.

The usual response to that criticism is "don't declare more than one item per line." My response to that response is "write your declarators correctly and you won't have any problems".

There's a different school of thought among many C++ programmers, who prefer the T* p style, and I have to say there are a few cases (limited to C++) where it can make the code more readable.

However, that only works for simple pointers to T: the paradigm rapidly breaks down when you start dealing with arrays of pointers, or pointers to arrays, or pointers to functions, or pointers to arrays of pointers to functions, etc. I mean, writing something like

T* (*(*p)[N])(); // p is a pointer to an array of pointers to functions
                 // returning pointers to T.

just indicates confused thinking. Although, if you really really really feel that you must follow the T* p paradigm, you could always create a series of typedefs:

EDIT

Let's try that again:

typedef T* TPtr;                           // pointer to T
typedef TPtr TPtrFunc();                   // function returning pointer to T
typedef TPtrFunc* TPtrFuncPtr;             // pointer to function returning
                                           // pointer to T
typedef TPtrFuncPtr TPtrFuncPtrArray[N];   // N-element array of pointer to function
                                           // returning pointer to T

TPtrFuncPtrArray* p;

For the love of God, don't do that.

查看更多
萌系小妹纸
3楼-- · 2020-05-23 01:55

You are correct, both mean exactly the same thing to the compiler. Both statements will produce a variable of type (int *).

As for which is correct: Can of worms! That is a debate topic usually. If you work for a company or on OSS, it's probably best to defer to a defined coding style. If there isn't one I usually go the the LNT (leave no trace) style of matching whatever style has evidentially been used in this part of the code base.

It can be argued that to the reader one is easier to understand. For example int* ptr; puts the * closer to the int which more clearly communicates the we are talking about an (int *) type...

查看更多
登录 后发表回答