good way to write “pointer to something” in C/C++

☆樱花仙子☆ 提交于 2019-12-01 06:30:41

问题


Is there a "good" way to write "pointer to something" in C/C++ ?
I use to write void foo( char *str ); But sometimes I find it quite illogical because the type of str is "pointer to char", then it should more logical to attach the * to the type name.
Is there a rule to write pointers ?

char*str;
char* str;
char *str;
char * str;

回答1:


The common C convention is to write T *p, whereas the common C++ convention is to write T* p. Both parse as T (*p); the * is part of the declarator, not the type specifier. It's purely an accident of pointer declaration syntax that you can write it either way.

C (and by extension, C++) declaration syntax is expression-centric; IOW, the form of a declaration should match the form of an expression of the same type in the code.

For example, suppose we had a pointer to int, and we wanted to access that integer value. To do so, we dereference the pointer with the * indirection operator, like so:

x = *p; 

The type of the expression *p is int; thus, it follows that the declaration of p should be

int *p  

The int-ness of p is provided by the type specifier int, but the pointer-ness of p is provided by the declarator *p.

As a slightly more complicated example, suppose we had a pointer to an array of float, and wanted to access the floating point value at the i'th element of the array through the pointer. We dereference the array pointer and subscript the result:

f = (*ap)[i];

The type of the expression (*ap)[i] is float, so it follows that the declaration of the array pointer is

float (*ap)[N];

The float-ness of ap is provided by the type specifier float, but the pointer-ness and array-ness are provided by the declarator (*ap)[N]. Note that in this case the * must explicitly be bound to the identifer; [] has a higher precedence than unary * in both expression and declaration syntax, so float* ap[N] would be parsed as float *(ap[N]), or "array of pointers to float", rather than "pointer to array of float". I suppose you could write that as

float(* ap)[N];

but I'm not sure what the point would be; it doesn't make the type of ap any clearer.

Even better, how about a pointer to a function that returns a pointer to an array of pointer to int:

int *(*(*f)())[N];

Again, at least two of the * operators must explicitly be bound in the declarator; binding the last * to the type specifier, as in

int* (*(*f)())[N];

just indicates confused thinking IMO.

Even though I use it in my own C++ code, and even though I understand why it became popular, the problem I have with the reasoning behind the T* p convention is that it just doesn't apply outside of the simplest of pointer declarations, and it reinforces a simplistic-to-the-point-of-being-wrong view of C and C++ declaration syntax. Yes, the type of p is "pointer to T", but that doesn't change the fact that as far as the language grammar is concerned * binds to the declarator, not the type specifier.

For another case, if the type of a is "N-element array of T", we don't write

T[N] a;

Obviously, the grammar doesn't allow it. Again, the argument just doesn't apply in this case.

EDIT

As Steve points out in the comments, you can use typedefs to hide some of the complexity. For example, you could rewrite

int *(*(*f)())[N];

as something like

typedef int *iptrarr[N];           // iptrarr is an array of pointer to int
typedef iptrarr *arrptrfunc();     // arrptrfunc is a function returning
                                   // a pointer to iptrarr

arrptrfunc *f;                     // f is a pointer to arrptrfunc

Now you can cleanly apply the T* p convention, declaring f as arrptrfunc* f. I personally am not fond of doing things this way, since it's not necessarily clear from the typedef how f is supposed to be used in an expression, or how to use an object of type arrptrfunc. The non-typedef'd version may be ugly and difficult to read, but at least it tells you everything you need to know up front; you don't have to go digging through all the typedefs.




回答2:


There is no strict rule, but bear in mind that the * attaches to the variable, so:

char *str1, *str2; // str1 and str2 are pointers
char* str1, str2;  // str1 is a pointer, str2 is a char

Some people like to do char * str1 as well, but it's up to you or your company's coding standard.




回答3:


The "good way" depends on

  1. internal coding standards in your project
  2. your personal preferences

(probably) in that order.




回答4:


There is no right or wrong in this. The important thing is to pick one coding standard and stick to it.

That being said, I personally believe that the * belongs with the type and not the variable name, as the type is "pointer to char". The variable name is not a pointer.




回答5:


I think this is going to be heavily influenced by the general pattern in how one declares the variables.

For example, I have a tendency to declare only one variable per line. This way, I can add a comment reminding me how the variable is to be used.

However, there are times, when it is practical to declare several variables of the same type on one line. Under such circumstances, my personal coding rule is to never, NEVER, EVER declare pointers on the same line as non-pointers. I find that mixing them can be a source of errors, so I try to make it easier to see "wrongness" by avoiding mixing.

As long as I follow the first guideline, I find that it does not matter overly much how I declare the pointers so long as I am consistent.

However, if I use the second guideline and declare several pointers on the same line, I find the following style to be most beneficial and clear (of course others may disagree) ...

char  *ptr1, *ptr2, *ptr3;

By having no space between the * and the pointer name, it becomes easier to spot whether I have violated the second guideline.

Now, if I wanted to be consistent between my two personal style guidelines, when declaring only one pointer on a line, I would use ...

char  *ptr;

Anyway, that's my rationale for part of why I do what I do. Hope this helps.



来源:https://stackoverflow.com/questions/5016117/good-way-to-write-pointer-to-something-in-c-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!