Pointers are a new thing for me and I'm struggling to understand it, but I won't give in and hopefully learn it.
What would be the difference between scanf ("%d", *p)
and scanf ("%d", p)
?
In examples I saw that if I want to input some value in a variable, I should use scanf ("%d", p)
. That doesn't make sense to me. Shouldn't it be scanf ("%d", *p)
?
I interpret it as: "put some integer value where the pointer is pointing" and for instance it is pointing on variable x
and then it should be x = 10
, but it isn't. And how then to use scanf()
and pointers to set values in an array?
Where and what am I getting wrong? I'm trying to learn this using C language, since it is the one which I'm supposed to use in my class.
For example:
#include <stdio.h>
int main () {
float x[10], *p;
int i;
p = &x[0];
for (i = 0; i < 10; i++) {
scanf("%d", p + i);
}
for (i = 0; i < 10; i++) {
printf("%d", *(p + i));
}
return 0;
}
Why is only p + i
in the first for () {}
and *(p + i)
in the second loop? I would put *(p + i)
also in the first for () {}
. *(p + i)
to me is like: "to what the (p+i)th element is and make it equal some value".
*p
means go to the place p
points to
&p
means take the address of p
, or "get a pointer to" p
int i;
scanf("%d", &i); // gives scanf a pointer to i
int i;
int *p = &i;
scanf("%d", p); // a more contrived way to say the same thing
The obligatory visual explanation is Pointer Fun with Binky .
You can read the types from right to left:
int *p
=> " p
has type int *
" => p
is a pointer to an int
int *p
=> " *p
has type int
" => *p
is the int
pointed to by p
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 (ie, 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
.
Function calls in C pass arguments by value, not by reference. This means that when you call a function with arguments, the function receives copies of the arguments, and that function cannot directly modify the original arguments from the callsite. That is:
int x = 42;
foo(x);
printf("%d\n", x);
foo
cannot change the variable x
, and the code will always print 42
.
But there are many cases where a function might want to modify the arguments from the caller. scanf
is one such case. To accomplish this, these functions require using a level of indirection . Instead of passing the variable to be modified directly to the function, the caller instead passes a pointer to that variable. The function then receives a copy of the pointer, and by dereferencing it, can access and can modify the variable it's pointing to.
I recommend spending some time reading the comp.lang.c FAQ. This topic is discussed in:
If p is the variable (say, an int), you would use &p to pass its pointer to scanf. p alone is not a pointer, and *p compounds the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.