One is right, the other is wrong. (Or both may be wrong, depending on what p
is.)
If you call
scanf("%d", SOMETHING);
then SOMETHING
must be a pointer to an int
.
If you have an int
object, use unary &
to get its address (i.e., a pointer to the object):
int n;
scanf("%d", &n);
If p
happens to be an int*
, then you can use its value:
int *p;
scanf("%d", p);
But here I haven't assigned a value to p
, so this compiles but has undefined behavior. This is ok:
int n;
int *p = &n;
scanf("%d", p);
As for using *p
, that would be valid only if p
is a pointer to a pointer to an int
:
int n;
int *p0 = &n;
int **p = &p0;
scanf("%d", *p);
But it would rarely make sense to do that. The vast majority of the time, the argument is going to be simply the address of some int
object, like &n
.
If n
is an int, then just passing n
to scanf
wouldn't make sense. You'd merely be passing the current value of n
. The point is that you want to permit scanf
to store a new value in n
, and to do that, scanf
need's the address of n
.