1

So in the following snippet, we ask the user to assign some value to our integer x.

   int x;
   scanf("%d", &x);

What I'm confused about is why we're saying "put the value of the input into the adress of x", instead of just "let x be equal to the value of the input"? What would be the problem with scanf("%d", x)?

Benjamin Lindqvist
  • 4,300
  • 3
  • 18
  • 19

4 Answers4

7

In C, parameters are passed by value. So if you use x as a parameter to scanf, it just gets a copy of the value of x, it doesn't get a reference to the actual variable x.

By passing a pointer, you're giving it the address of the memory that the x variable's value is stored in. That allows scanf to modify the value of x by storing into that memory.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • "parameters are passed by value" except those pesky [arrays](http://stackoverflow.com/a/11158906/2410359) – chux - Reinstate Monica Aug 27 '15 at 12:47
  • I can't win. A few weeks ago I posted that arrays are passed by reference, someone commented that they're not. They're converted to pointers and the pointer is passed by value. – Barmar Aug 27 '15 at 12:56
  • Hmmm. "Array expressions and function designators as arguments were converted to pointers before the call" §6.9.1 10 so the function is called with pointers (which supports your "passed by value"). With that, an array cannot be passed to a function, the array argument being converted to a pointer first. Or in another perspective, the calling code _does_ pass an array to a function. The language then converts that array argument with a conversion as part of "On entry to the function" (same ref). I shall ponder. – chux - Reinstate Monica Aug 27 '15 at 14:01
  • See http://stackoverflow.com/a/31687178/1491895 for the answer where someone complained when I said arrays are passed by reference. – Barmar Aug 27 '15 at 14:09
3

All function calls take their arguments by value. Passing x would just give scanf a copy of x, and it still wouldn't have access to our x.

Taking the address of a variable produces a pointer, which when copied, still points to the same variable. Thus scanf can dereference its copy of the pointer and gain access to x.

Quentin
  • 62,093
  • 7
  • 131
  • 191
3

Short answer: because you have to. The specification of scanf says that for the format specifier %d it expects the corresponding argument to have the type int *, which means &x, not x.

C doesn't have pass-by-reference. scanf is a function like any other and when you pass a variable to it, you don't pass the variable itself, but its value. So when you call scanf("%d", x); you give it the (uninitialized) value of x, which is useless to scanf. When you pass the address of x, scanf can put the value it scanned into x by dereferencing it.

As n.m. commented, calling scanf("%d", x); is (somewhat) equivalent to calling scanf("%d", 5); (or more accurately: scanf("%d", <garbage>);). It can't assign to a constant, or an ordinary number, but it can assign to the place that a (valid) address points to.

Kninnug
  • 7,992
  • 1
  • 30
  • 42
1

I'm just going to take a slightly different approach and try and make you answer the question for yourself.

Consider the following code (that won't compile but supposes that you only need to do as you suggest and call scanf("%d", x)):

int w = 5;
int x = 5;
int y = 5;
int z = 5;
scanf("%d", x);

When you make the call to scanf, scanf doesn't know that you have passed the value of x, all it knows is that you have given it a value of 5, just as if you had written the line scanf("%d", 5)

Assuming you were the programmer who was coding scanf, if you've been given the parameters "%d" and 5, which of the variables w, x, y or z would you update? How would you even know that the variables w, x, y, z exist? How would you know that there aren't any other variables in the code with the value of 5? How would you know that the value of 5 you have received actually came from the variable x?

DanL
  • 1,974
  • 14
  • 13