This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Correct way of declaring pointer variables in C/C++
For some time the following has been annoying me, where should I put the star in my pointer notation.
int *var; // 1
and
int* var; // 2
obviously do the same thing, and both notations are correct, but I find that most literature and code I look at use the 1th notation.
wouldn't it be more 'correct' to use the 2th notation, separating the type and the variable name by a whitespace, rather than mixing the type and variable tokens?
No. Never. <g>
But consider:
int* var1, var2;
Here, the placement of the * is misleading, because it does not apply to var2, which is an int and not an int*.
The Linux kernel coding style convention is:
int *ptr1 , *ptr2;
So I think you should adopt it as your convention.
When declaring pointer data or a function that returns a pointer type, the
preferred use of * is adjacent to the data name or function name and not
adjacent to the type name. Examples:
char *linux_banner;
unsigned long long memparse(char *ptr, char **retptr);
char *match_strdup(substring_t *s);
I believe part of the reason for this notation is so that the usage and declaration of a variable look similar.
int *var;
int x;
x = *var;
You can also think of it as saying that dereferencing var will give you an int.
Related
This question already has answers here:
Declaring type of pointers?
(10 answers)
Closed 6 years ago.
As the question says. Is there some difference between the content of them?
Why do we have to declare the variable type before the pointer ????
Does the c process them differently?
Exemple:
typedef struct{
int a;
char b;
} some_st;
int main(){
some_st *p;
int *q;
}
Just a note: I came up with this question after work with linked lists.
Thank you for reading and answering.
the pointers are the same size, but one points to an int and the other one to a struct. The reason to declare them accordingly is that the compiler can tell you when you use them incorrectly.
if you think you're above that, you can use void* for all your pointers, or use a language with even less type checking.
C doesn't define how pointers are represented.
Pointers of different types may have different sizes, different alignments requirements and different bit representaion.
For example this is a completely valid result of an implementation:
sizeof( int* ) != sizeof( long* )
as is :
sizeof( int* ) != sizeof( some_st* )
There is no difference in the size or "structure" of the pointer itself, however the declaration does affect two things:
It tells the compiler how to handle the value being pointed to (int or struct or whatever) - that is, what to assume the pointed type is.
The way pointer arithmetic is being performed. That is what memory location ptr++ or ptr[4] evaluates to. For example, Assuming the struct has, say 12 bytes size, ptr++ will result in the address being incremented by at least 12.
I just learned about function pointers and that to declare one, you must put the * in parentheses with the pointer name to make sure it doesn't return an int *.
Is there a difference between
int *p
and
int (*p)
I tried looking this up with cdecl, but no luck so far. cdecl says it is the same thing, but doesn't provide an explanation. If I declared
short (*p)
Would that be a short pointer or a pointer to a short? Would p have a size of 2 bytes or 4? I know similar questions have been asked, but I've had no luck with them so far.
Would there be a difference between
int *p
and
int (*p)
No. Those are two different ways of writing the same type. The parentheses are not magic here -- they just serve to override precedence, just as with arithmetic operators.
The difference is between
int *p();
(declaration of a function "p" returning int *) and
int (*p)();
(declaration of a pointer to a function returning int). Absent the parentheses around *p, the (empty) parameter list associates more tightly with the name being declared.
If I did:
short (*p)
Would be be a short pointer, or a pointer to a short? And would p be 2 bytes, or 4?
Analogous to int (*p) it declares a pointer to a short. The size of the pointer is implementation-specific, but 4 bytes and 8 bytes are common choices. The pointed-to data is expected to be the size of a short, which is also implementation-specific, but is often 2.
The concept of near vs. far pointers is a compiler vendor specific concept (and rarely occurs outside of some strange embedded systems nowadays; x86 machines dropped it when they moved to 32 bit IIRC). There is not, nor has there every been a concept of a "short pointer" declared using short (meaning a smaller than normal pointer), because C's short already has a meaning. A short* is a normal sized pointer that points to a short sized location, that's all.
Basically, sometype (*p) doesn't mean anything different from sometype *p. Function pointers are declared with somereturntype (*p)(argument, types, go here); without the parens for argument types, it's not a function pointer at all.
#include <iostream>
using namespace std;
int main() {
// your code goes here
short (*p);
short *r;
printf("size - %u- %u",sizeof(p) , sizeof(r));
return 0;
}
returns 4 for both of them.
short (*p)
That would be a pointer to a short. Which in most cases is 2 bytes when it is de-referenced. A pointers size will probably be either 4 or 8 bytes on a modern machine.
s = 5;
short *p = &s;
There is no difference in the context you are using it in.
Parenthesis are used to force operator precedence. If there is no need for parenthesis, such as in initialization, both short *p and short (*p) are equivalent (both are pointers to short values in memory). The actual size of pointers should be uniform (and do not correspond in size to the data members they point to) as they simply store the address of the data member in question.
It is possible that you will need to use parentheses to force precedence if you have pointers to objects. For example:
Object *myObject = new Object();
int myObjectSize = *myObject.size(); // INCORRECT: . operator has higher precedence than *
int myObjectSize = (*myObject).size(); // CORRECT: parentheses force precedence
Of course, in this specific situation, myObject->size() is more commonly used (to avoid using parentheses excessively).
when I declare C++ variables, I do it like this:
int a,b,c,d;
or
string strA,strB,strC,strD;
I.e., first the type then a comma separated list of variable names.
However, I declare pointers like this:
int *a,*b,*c,*d;
and references like this:
int &a,&b,&c,&d;
To be consistent it should be
int* a,b,c,d;
and
int& a,b,c,d;
Why is it not consistent?
The best answer I've seen as to why things like * apply to variables and not to types is the idea that declaration should follow use.
Basically, how you declare a variable should look similar to how you use a variable.
For example,
int *a, b;
...
*a = 42;
b = 314159;
...the use of a and b looks similar to the declaration of a and b.
There's even a citation for this behavior from Dennis Ritchie, one of the creators of C:
Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear...In all these cases the declaration of a variable resembles its usage in an expression whose type is the one named at the head of the declaration.
Dennis Ritchie, The Development of the C Language. History of Programming Languages-II ed. Thomas J. Bergin, Jr. and Richard G. Gibson, Jr. ACM Press (New York) and Addison-Wesley (Reading, Mass), 1996; ISBN 0-201-89502-1.
It's because of the C heritage. The * modifier applies to the variable in C. So the C++ designers made & to apply to the variable as well by analogy, since they couldn't change the first without breaking C compatibility. Same is true for the array syntax too:
int anInt, *aPointerToInt, anArrayOfInt[100];
In The Design and Evolution of C++ Bjarne Stroustrup says he wasn't happy with this but had to accept it for C compatibility. He was unhappy with this in particular:
int *a[10];
It's not clear from the declaration if a is a pointer to an array or an array of pointers (it's an array of pointers, you need brackets to override).
Of course, you can always use a typedef to clean things up a little.
The reason is: in reality & and * in C and C++ applies to variable and no to type.
So the problem is that if you want to declare 4 pointer to integers you should write
int *a, *b, *c, *d;
Writing int* a, b; means
int *a;
int b;
For this reason a lot of people prefer to write int *a; than int* a;, just code style.
Of course int* is a type, but the C syntax states clearly that in a variable declaration * and & will apply to variable.
This happens for the same reason that arrays in C are declared in this way:
int a[10], b;
std::cout << typeid(a).name() << std::endl; // it will print int[10]
std::cout << typeid(b).name() << std::endl; // it will print int
In other languages like C# instead the syntax int[] array; is used.
Another thing is the pointer to function syntax:
// Now we declare a variable that is a pointer to function
int (*pt2Function)(char, char) = NULL;
We are applying the * to the variable name.
It seems to me that the use of * and & applied to the variable, also if 90% of us would prefer differently, is more consistent with the rest of the language.
In the same way, going back to arrays:
// Now we declare a variable that is a pointer to an array of 10 integers.
int (*arrayptr)[10];
C has a rule for its declarations: Declarations mimic use. What this means is that the declaration for a variable looks like the way the variable is used. For example:
int i;
Using this variable looks like i, and that expression results in an int.
int *i;
Using this variable looks like *i, and that expression results in an int. This also implies that an expression i results in a pointer to an int.
int i(void);
Using this variable looks like i(), and results in an int. This also implies i is a function that takes nothing and that returns an int.
int (*i[5])();
Using this variable looks like (*i[x])(), and results in an int. This also implies *i[x] is a function returning int, and i[x] is a pointer to a function returning int, and i is an array of pointers to functions returning int.
So:
int a, *b, c(void), (*d[5])(void);
declares several expressions which all have the type int, but the variables themselves are not all ints.
N.B. in declarations of function and arrays the sub declarations don't literally resemble the use of the variable. I.e. int i[5]; doesn't mean that you need to put a '5' inside the square brackets when you use i, and int i(int); doesn't mean you call the function by saying i(int);. Also declarations of variables of struct types don't match their use since you'd have to declare expressions for each member variable.
Related to the syntax for declaring variables is that of typedefs. To declare a typedef with a certain type, you use the same syntax as for declaring a variable of the desired type, but you stick typedef in front of the declaration and the variable name becomes the typedef name.
typedef int (*array_of_function_pointers[5])(void);
C++ adds references, templates, pointers to member, and a bunch of stuff. It tries to some extent to follow the old C convention, but that convention doesn't really work all that well for many of the things C++ adds, so you do start getting inconsistencies. You'll just have to learn the idiosyncrasies and chalk it up to an imperfect marriage between C and C++.
C++ has inherited this syntax from C. The K&R book (§5.1) says that the expression
int *ip, **ipp;
is intended to be mnemonic (i.e. you read “*ip and **ipp have type int”), they wanted it to mimic usage syntax.
I agree it is quite cryptic and counterintuitive for humans, and inconsistent with typedefs, e.g.
typedef int* intptr;
intptr a, b; // equivalent to: int *a, *b
but it never really was C++ author's decision, the choice to make the language compatible with C implied using this syntax, that's why.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What makes more sense - char* string or char *string?
The syntax for pointers has never made sense to me. I noticed that both of these options work for declaring a pointer. Which one should I be using?
The whitespace is insigificant for the C compiler.
The difference matters more if you have multiple declarations on the same line:
int* p1, q1; // p1 is a pointer to int, q1 is an int.
int *p2, *q2; // p2 and q2 are both pointers to ints.
Putting the asterisk near to the variable name may help you to remember this. But it's probably better to just declare each variable on its own line.
It's a question of style, so you should probably use the same style (consistently) as others working on the same code. If it's just you, pick whichever you like.
Personally would argue for int *pointer because int* a, b; means the same as int *a; int b; not int *a; int *b; as one might think, but this is admittedly a fringe case.
The spacing is irrelevant for parsing. There are 3 tokens: int, *, and pointer.
They are equivalent, and a matter of personal preference.
For completeness, I would add that if you're declaring two pointers, you will have to write:
int *a, *b;
If you write int *a,b, you end up with one pointer to int and one int.
From Microsoft's All-In-One Code Framework Coding Standards:
You should put a space between the * character(s) and the type when specifying a pointer type/variable, but there should be no space between the '*' character(s) and the variable. Setting this rule is to be consistent and uniform in code.
You can also use
int * pointer
it just a matter of personal preference. The c++ compiler will know what you mean, just as long as you have the correct syntax.
There is no difference between the two. Use the one that you like more.
They are both equal. Choose the one you like the most, or follow the style guidelines if you are editing existing code.
I'm relatively new to C++ (about one year of experience, on and off). I'm curious about what led to the decision of type * name as the syntax for defining pointers. It seems to me that the syntax should be type & name as the & symbol is used everywhere else in code to refer to the variable's memory address. So, to use the traditional example of int pointers:
int a = 1;
int * b = &a;
would become
int a = 1;
int & b = &a
I'm sure there's some reason for this that I'm just not seeing, and I'd love to hear some input from C++ veterans.
Thanks,
-S
C++ adopts the C syntax. As revealed in "The Development of the C Language" (by Dennis Ritchie) C uses * for pointers in type declarations because it was decided that type syntax should follow use.
For each object of [a compound type], there was already a way to mention the underlying object: index the array, call the function, use the indirection operator [*] on the pointer. Analogical reasoning led to a declaration syntax for names mirroring that of the expression syntax in which the names typically appear. Thus,
int i, *pi, **ppi;
declare an integer, a pointer to an integer, a pointer to a pointer to an integer. The syntax of these declarations reflects the observation that i, *pi, and **ppi all yield an int type when used in an expression.
Here's a more complex example:
int *(*foo)[4][];
This declaration means an expression *(*foo)[4][0] has type int, and from that (and that [] has higher precedence than unary *) you can decode the type: foo is a pointer to an array of size 4 of array of pointers to ints.
This syntax was adopted in C++ for compatibility with C. Also, don't forget that C++ has a use for & in declarations.
int & b = a;
The above line means a reference variable refering to another variable of type int. The difference between a reference and pointer roughly is that references are initialized only, and you can not change where they point, and finally they are always dereferenced automatically.
int x = 5, y = 10;
int& r = x;
int sum = r + y; // you do not need to say '*r' automatically dereferenced.
r = y; // WRONG, 'r' can only have one thing pointing at during its life, only at its infancy ;)
I think that Dennis Ritchie answered this in The Development of the C Language:
For each object of such a composed
type, there was already a way to
mention the underlying object: index
the array, call the function, use the
indirection operator on the pointer.
Analogical reasoning led to a
declaration syntax for names mirroring
that of the expression syntax in which
the names typically appear. Thus,
int i, *pi, **ppi;
declare an integer, a pointer to an
integer, a pointer to a pointer to an
integer. The syntax of these
declarations reflects the observation
that i, *pi, and **ppi all yield an
int type when used in an expression.
Similarly,
int f(), *f(), (*f)();
declare a function returning an
integer, a function returning a
pointer to an integer, a pointer to a
function returning an integer;
int *api[10], (*pai)[10];
declare an array of pointers to
integers, and a pointer to an array of
integers. In all these cases the
declaration of a variable resembles
its usage in an expression whose type
is the one named at the head of the
declaration.
So we use type * var to declare a pointer because this allows the declaration to mirror the usage (dereferencing) of the pointer.
In this article, Ritchie also recounts that in "NB", an extended version of the "B" programming language, he used int pointer[] to declare a pointer to an int, as opposed to int array[10] to declare an array of ints.
If you are a visual thinker, it may help to imagine the asterisk as a black hole leading to the data value. Hence, it is a pointer.
The ampersand is the opposite end of the hole, think of it as an unraveled asterisk or a spaceship wobbling about in an erratic course as the pilot gets over the transition coming out of the black hole.
I remember being very confused by C++ overloading the meaning of the ampersand, to give us references. In their desperate attempt to avoid using any more characters, which was justified by the international audience using C and known issues with keyboard limitations, they added a major source of confusion.
One thing that may help in C++ is to think of references as pre-prepared dereferenced pointers. Rather than using &someVariable when you pass in an argument, you've already used the trailing ampersand when you defined someVariable. Then again, that might just confuse you further!
One of my pet hates, which I was unhappy to see promulgated in Apple's Objective-C samples, is the layout style int *someIntPointer instead of int* someIntPointer
IMHO, keeping the asterisk with the variable is an old-fashioned C approach emphasizing the mechanics of how you define the variable, over its data type.
The data type of someIntPointer is literally a pointer to an integer and the declaration should reflect that. This does lead to the requirement that you declare one variable per line, to avoid subtle bugs such as:
int* a, b; // b is a straight int, was that our intention?
int *a, *b; // old-style C declaring two pointers
int* a;
int* b; // b is another pointer to an int
Whilst people argue that the ability to declare mixed pointers and values on the same line, intentionally, is a powerful feature, I've seen it lead to subtle bugs and confusion.
Your second example is not valid C code, only C++ code. The difference is that one is a pointer, whereas the other is a reference.
On the right-hand side the '&' always means address-of. In a definition it indicates that the variable is a reference.
On the right-hand side the '*' always means value-at-address. In a definition it indicates that the variable is a pointer.
References and pointers are similar, but not the same. This article addresses the differences.
Instead of reading int* b as "b is a pointer to int", read it as int *b: "*b is an int". Then, you have & as an anti-*: *b is an int. The address of *b is &*b, or just b.
I think the answer may well be "because that's the way K&R did it."
K&R are the ones who decided what the C syntax for declaring pointers was.
It's not int & x; instead of int * x; because that's the way the language was defined by the guys who made it up -- K&R.