What is the difference between these two declarations?Can someone explain me?
int *ptr=#
and
int *ptr;
ptr= #
What is the difference between these two declarations?Can someone explain me?
int *ptr=#
and
int *ptr;
ptr= #
There is no difference meaning wise. In the first case, you are declaring the pointer variable and initializing it right away. (&num is initializer here).
In the second case the pointer is declared and it then contains the garbage value (considering they are of automatic storage duration) until you assign it the address of num - in between these two if you use it then it's UB. In the first case you kill this chance of using unintiialized pointer variable's value.
Note that, in the second case ptr= # is not part of declaration. It is assignment statement. The declaration was simply that int *ptr.
You can check this rule to get an idea of declaration: From standard
declaration:
declaration-specifiers init-declarator-listopt ;
static_assert-declaration
declaration-specifiers:
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
alignment-specifier declaration-specifiersopt
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator
declarator = initializer <-------
There is a semantic difference, even if both end in same result: you have declared a pointer to int (ptr) and have it point to a variable (num).
Now for the difference:
int *ptr=#
declares a pointer (it is even a definition) and uses an initialization to set its initial value, while:
int *ptr;
ptr= #
first declares a pointer, and then assigns a value to it.
The specific differences come from there:
if the pointer were static, the assignement would be repeated on each pass, while the initialization let the variable keep its value:
int *foo() {
static int num[5] = { 1, 2, 3, 4, 5 };
static int ptr = # // one time only initialization
return ptr++;
}
int main() {
for(int i=0; i<5; i++) {
printf("%d ", *foo());
}
return 0;
}
will print 1 2 3 4 5, but if we write:
int *foo() {
static int num[5] = { 1, 2, 3, 4, 5 };
static int ptr;
ptr = # // assignment on each call
return ptr++;
...
the result will be 1 1 1 1 1
you can initialize a const variable
int * const ptr = #
while you cannot assign to it
int * const ptr;
ptr = # // syntax error
you can initialize an array, while you cannot assign to it
To me, the big difference is that it looks funny at first.
For conventional, non-pointer variables, we can write, for example, either
int num = 5;
or
int num;
num = 5;
The thing we declare (num) is exactly the same as the thing we assign.
But in the case of pointer declarations, there's that pesky extra *. This pattern causes some beginning programmers to attempt to write the following incorrect code. Since we can have
int *ptr = #
why can't we rearrange it as
int *ptr;
*ptr = # /* XXX looks superficially right, but WRONG */
In this case, following the previous pattern, we're trying to make the thing we declare (*ptr) the same as the thing we assign.
But this is wrong, that's not the way pointer declarations work in C. The thing we're declaring is not *ptr. The thing we are declaring is just ptr, which has type int *, or pointer to int.
For this reason, some people like to write pointer declarations differently:
int* ptr;
ptr = #
Now it's more obvious that the thing we're declaring (ptr) is the same as the thing we're assigning.
The only problem here comes if we try to declare two pointers on the same line:
int* ptr1, ptr2; /* probably WRONG: ptr2 is *not* a pointer */
But of course this does not actually declare ptr2 to be a pointer.
We could also make things more clear using typedefs:
typedef int *intptr;
followed by either
intptr ptr = #
or
intptr ptr;
ptr = #
And in this case declaring two pointers on the same line works properly:
intptr ptr1, ptr2; /* both ptr1 and ptr2 are pointers */
int *ptr=& num; statement declares a variable "ptr" of pointer type and initializes it with the address of variable "num" at the same time.
Whereas the statements int *ptr; *ptr=& num; first declare a pointer type variable which currently holds garbage value.
The value, i.e. the address of "num" variable is assigned to the pointer variable in the next statement.