tags:

views:

331

answers:

6

What's the difference between float* varname and float *varname in classic C?

+22  A: 

Formatting. That's it. They mean the same thing.

Where you put the space (or if you even have one, really) is a matter of preference. Some prefer the * next to the varname so that you don't get confused by something like:

float* a, b;

(here, only a is a pointer, b is not)

Others argue that they never declare multiple variables at once, so they prefer the * next to float, since it's part of the type.

Laurence Gonsalves
cheers buddy just checking :)
PeanutPower
One wonders how those who put the `*` next to `float` because "it's part of the type" ever manage to declare arrays.
caf
They use typedefs.
Mark Tolonen
You still can't put the `[N]` next to the rest of the type, though.
caf
@caf: That's why I find the whole "it describes the type" argument to be specious, because it's inconsistent with *every other type*; every time I see something like `int* a[10];` or `double* foo();` it just screams confused thinking to me.
John Bode
+8  A: 

There is no difference. The whitespace is completely ignored.

However note that the following can be misleading:

float* var1, var2;

Casual examination of the above would lead you to think that both var1 and var2 are pointers to a float. However you'd be wrong, because this declares var1 as a pointer to a float, but var2 would be a regular float.

Daniel Vassallo
It's an interesting thing that C considers the * to be associated more with the variable name than with the pointer-to type. Kind of makes you wish for the old Pascal colon as a disambiguation - separate the shared type from the names-with-modifiers list.
Steve314
@Steve314 But think about what happens when you have `typedef int *foo_t;`, then `foo_t a, b, c;`. At that point C "considers" the `*` to be associated with the type. (Although I would argue that the C language doesn't really "consider" anything...)
asveikau
+4  A: 

The latter is more explicit in that it shows that you are creating a variable which is a pointer to a float, instead of creating a variable that is a float pointer. This becomes important in constructs such as:

float *foo, bar;

foo is a pointer to a float, but bar is just a float.

Ignacio Vazquez-Abrams
+1  A: 

Mostly, it is a matter of coding style. However, most C programmers prefer to use the second option: float *var; as it is closer to how the language syntax binds the * asterisk: the * is bound to the declarator, not the specifier of type.

In other words, C programmers translate float *var as *var is of type of float. but not var is of type of float*.

There is more elaborate explanation in Wikipedia article C variable types and declarations

Also, you may find the question C Pointer Syntax: Style poll interesing.

mloskot
A: 

As others said, it makes no difference - matter of style. Note that in C++ it's customary to write:

type* var;

Because the pointer is part of the type - at least this true for custom types. But by extension for built-in types too. So it makes some sense in C to do the same to be consistent. Personally I find it more intuitive to have pointer part of the type.

zaharpopov
A: 

There is effectively no difference; the declaration is parsed as though it were written float (*varname);.

In both C and C++, declarations are centered around expressions, not objects; basically, the form of the declaration should match the form of the expression in executable code (IOW, declaration mimics use). For example, if you have a pointer to an integer named p and you want to access that integer value that p points to, you dereference the pointer like so:

x = *p;

The type of the expression *p is int; thus, the declaration should look like

int *p;

Similarly, if you have an array of int named arr and you want to access the integer value at a specific element i, you would write

x = a[i];

The type of the expression a[i] is int; thus, the declaration should look like

int a[N];

In the examples above, *p and a[N] are called declarators; declarators introduce the name of the object being declared along with additional type information not provided in the type specifier. The int-ness of both p and a are provided by the type specifier int, but the pointer-ness of p and the array-ness of a are provided by their respective declarators.

This is an important point, and something that needs to be stressed; the * of both int *p; and int* p; is bound to the declarator, not the type specifier, regardless of whitespace. The fact that you can write it either way is an accident of C (and C++) syntax, and as a result there's a school of thought that pointer variables should be declared as T* p; as opposed to T *p;, since the type of p is "pointer to T". My problem is that reasoning only works for simple pointer types; we cannot treat array or function types the same way. For example, we cannot write int[N] arr;, even though the type of arr is "N-element array of int". It really falls down when we get into declaring pointers to arrays, or pointers to functions, or combinations of such. For example:

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

The type of farr is "pointer to a function returning a pointer to an N-element array of pointers to functions returning pointers to int". Everything other than the "int" is part of the declarator; writing int* (*(*(*farr)())[N])(); or even int*(*(*(* farr)())[N])(); would just be ... silly.

I believe that insisting on writing T* p; for pointer declarations results in more confusion, not less. Much as Stroustrup and legions of C++ programmers would like to pretend otherwise, declarations in C and C++ are centered around expressions, not objects.

Since I'm part of a larger team writing C++ code, I follow the agreed-upon coding guidelines which include declaring pointer and references as T* p; and T& r;, but it makes me grind my teeth every time I have to do it.

John Bode