1

I'm confused with these two ways of initializing pointers

int i=5;
int *p = &i;

and

int i=5;
int *p;
p = &i; 

Is there any difference between these two? These different ways give exactly the same output. If there isn't any difference then doing *p = &i is equivalent to p = &i ?

5
  • @uneven_mark: In such an instance feel free to make an edit. Commented Sep 4, 2019 at 13:59
  • @Bathsheba ok, will do next time Commented Sep 4, 2019 at 14:01
  • 2
    just to clearify your last sentence: while the two snippets you've posted do exactly the same as @bathseba has posted in his answer, having *p = &i as a seperate assignment would be something very different Commented Sep 4, 2019 at 14:04
  • There's some subtle crap though, in case the variables are declared at file scope. Then they have static storage duration and the two forms are no longer equivalent. Commented Sep 4, 2019 at 14:18
  • 1
    The distinction is very similar to int i = 5; vs. int i; i = 5; Note that the first form, which uses an initializer, can be used outside of a function, while the latter cannot. Commented Sep 4, 2019 at 14:26

7 Answers 7

4

Formally, the former is initialization and the latter is assignment. Nothing of this is unique to pointers - all variables follow the same rules.

In C, there isn't really much of a practical difference. Initialization is required to be carried out as per the rules of assignment. Though when initializing you have more options, like providing an initializer list for arrays or structs.

(In C++, these two forms are very different, as the former will call the default constructor but the latter will call the (potentially overloaded) assignment operator.)

There is one important difference though. Whenever you declare objects with static storage duration (globals or variables declared with static), the code that performs the initialization is not executed at the line where you placed it, but rather much earlier on, before main() is called.

So if we write static int x=1;, that code behaves very differently compared to static int x; x=1;

Sign up to request clarification or add additional context in comments.

Comments

2

There's no difference at all, aside from the fact that in the first case, p is never in an uninitialised state and therefore, in my opinion at least, is a better way of writing it.

(Uninitialised variables can be a big source of trouble in c especially with aggressively optimising compilers).

1 Comment

The first form can also be used outside of a function.
2

This

int *p = &i;

is a declaration.

But this

p = &i; 

is an expression statement.

In C declarations are not statements.

For example you may not place a label before a declaration that is this code

L: int *p = &i;

is invalid (though valid in C++ because in C++ declarations are statements).

You have to write

L:; int *p = &i;
 ^^^

However you may write

int *p;
L: p = &x;

One more difference that this declaration with an initializer

int *p = &i;

you may place in the global name space (that is the variable will have the file scope). For example

#include <stdio.h>

int x  = 10;
int *p = &x;

int main(void) 
{
    printf( "%u\n", *p );

    return 0;
}

but you may not write

#include <stdio.h>

int x  = 10;
int *p;
p = &x;

int main(void) 
{
    printf( "%u\n", *p );

    return 0;
}

Also if the pointer is a constant pointer it shall be initialized when it is declared. For example

int * const p = &i;

You may not write

int * const p;
p = &i;

Comments

1

You have come across a curiosity of C's declaration syntax.

When you write

int *p = &i;

you are declaring a variable p of type int *, and you are initializing it to point to i.

But the initialization is not equivalent to the standalone assignment

*p = &i;    /* WRONG */

Rather, it is equivalent to

p = &i;     /* right */

What's actually happening is that there are two slightly different uses of the * character here. When you say

int *p = &i;

the * means that p is being declared as a pointer. (But since this very much determines p's type, some programmers prefer to write it as int* p instead.)

Later, in an actual expression statement, when you use * with a pointer, it means "access the contents of that pointer". If we say

printf("%d\n", *p);

we will fetch the value that p points to (which will actually be i's value). If we say

*p = 5;

we will set the value pointed to by p to 5 (which will actually set i to 5).

Bottom line: When you split up a pointer initialization like

int *p = &i;

into a declaration and separate assignment

int *p;
p = &i;

then yes, it looks like there's something fishy going on. It looks like a * has gotten lost, or something, but actually, when you stop and think about it, it's perfectly correct as-is.

2 Comments

make the last line p = &i; :-)
The question does not ask about an assignment *p = &i;. (It does refer to the source text *p = &i in the final sentence, but this is taken from the context of the declaration shown, not a separate statement.) This is not an answer to the question that was asked.
0

Yes, both do the exactly same thing

int *p = &i;

Here the initialization and declaration is being done on the same line

int *p
p = &i;

In this case the initialization and declaration is being done on different line.

Both codes do the same thing and hence produce the same output.

Happy coding :-)

1 Comment

Yes I've fixed that now
0

Some important distinctions here:

This:

int *p = &i;

Is an initialization of the pointer p, while this:

int *p;
p = &i; 

Is an *assignment. These two are functionally equivalent.

However, this is not the same:

int *p;
*p = &i; 

This assigns the address of i to the location where p points to, performing an implementation defined pointer-to-integer conversion. In this case since p was never assigned a value attempting to dereference it invokes undefined behavior.

Comments

0

Is there any difference between these two?

Just as you put it here -- no, in practice (language lawyers might argue though) there is no difference. The end result is the same.

You have a variable by the name of p.

The type of the variable is a pointer to int. No matter how you write your declaration -- int* p;, int * p;, int *p -- it is still a pointer. Imagine something like this TYPE var; In your case TYPE equals int *.

So you can declare-and-define your pointer with

int i;
int *p = &i; /* Remember 'TYPE' is 'int *' */

or you declare-and-assign-later with

int i;
int *p; /* Remember 'TYPE' is 'int *' */
p = &i;

If there isn't any difference then doing *p = &i is equivalent to p = &i ?

Feels like a broken question to me. You see, this expression *p = &i alone is a pointer dereference. So *p = &i and p = &i are not equivalent at all. I'd even expect a compiler warning at least. But int *p = &i and p = &i are equivalent in your code snippets.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.