How does the scanf function work in C?

前端 未结 7 1677
孤独总比滥情好
孤独总比滥情好 2020-12-06 13:48

Why do you require ampersand (&) in the scanf function. What will the output or type of error (compile or runtime) be in the following C code?



        
7条回答
  •  情话喂你
    2020-12-06 14:04

    In C, all function arguments are passed by value; any changes to the function's formal parameter are not reflected in the actual parameter. For example:

    void foo(int bar)
    {
      bar = bar + 1;
    }
    
    int main(void)
    {
      int x = 0;
      printf("x before foo = %d\n", x);
      foo(x);
      printf("x after foo = %d\n", x);
      return 0;
    }
    

    The output of the program will be

    x before foo = 0
    x after foo = 0
    

    because bar receives the value of x (0), not a reference to x itself. Changing bar has no effect on x.

    In C, the way around this is to pass a pointer to a variable:

    void foo(int *bar)
    {
      *bar = *bar + 1;
    }
    
    int main(void)
    {
      int x = 0;
      printf("x before foo = %d\n", x);
      foo(&x);
      printf("x after foo = %d\n", x);
      return 0;
    }
    

    Now the output of the program is

    x before foo = 0
    x after foo = 1
    

    This time, the formal parameter bar is not an int, but a pointer to int, and it receives the address of x (given by the expression &x in the call to foo), not the value contained in x. The expression *bar means "get the value in the location bar points to", so *bar = *bar + 1 corresponds to x = x + 1.

    Since scanf() needs to write to its arguments, it expects those arguments to typed as pointers. The "%d" conversion specifier expects the corresponding argument to be a pointer to int (int *), the "%u" conversion specifier expects a pointer to unsigned int (unsigned *), "%s" expects a pointer to char (char *), "%f" expects a pointer to float (float *), etc. In your example, since a is typed int, you need to use the expression &a to get a pointer.

    Note that if a were already a pointer type, you would not need to use the & operator in the call to scanf():

    int main(void)
    {
      int a, *pa;      // declare pa as a pointer to int
      ...
      pa = &a;         // assign address of a to pa
      scanf("%d", pa); // scanf() will write to a through pa
      ...
    }
    

    Note also that when passing an array to a function (such as when using the "%s" conversion specifier to read a string), you don't need to use the & operator; the array expression will implicitly be converted to a pointer type:

    int main(void)
    {
      char name[20];
      ...
      scanf("%19s", name); // name implicitly converted from "char [20]" to "char *"
      ...
    }
    

提交回复
热议问题