Domanda

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".

È stato utile?

Soluzione

*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

Altri suggerimenti

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.

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top