问题1:如果scanf中没有&会怎样?
回答:如果在调用scanf函数时忘记在变量前面放置符号&,最起码不会把从输入读进来的值存储到变量中,变量将保留原有的值(如果没有给变量赋初值,那么这个原有值可能是没有意义的)。
拓展:
&是取址运算符,如果x是变量,那么&x就是x在内存中的地址。对变量使用&运算符产生指向变量的指针。
问题2:为什么scanf中需要&?
回答:这个问题本质是<调用函数时,指针作为参数>,如在以下代码块中,必须把&放在i的前面以便给scanf函数传递指向i的指针,指针会告诉scanf函数把读取的值放在哪里。如果没有&运算符,传递给scanf函数的将是i的值。
int i;
scanf("%d", &i);
虽然scanf函数的实际参数必须是指针,但并不总是需要&运算符。如以下代码块,向scanf函数传递了一个指针变量:
int i, *p;
p = &i;
scanf("%d", p);
既然p包含了i的地址,那么scanf函数将读入整数并且把它存储在i中,在调用中使用&运算符将是错误的:
scnaf("%d", &p); // 错误
scanf函数读入整数并且把它存储在p中而不是i中。
拓展:
- 取址运算符
&与间接寻址运算符*的关系:
对变量使用&运算符产生指向变量的指针,而对指针使用*运算符则可以返回到原始变量。//两者是等价的 j = *&i; j = i; - 调用函数时,指针作为参数:
如以下代码,调用函数时,p的值为&x,因此*p(p指向的对象)将是x的别名。函数体内*p的每次出现都将是对x的间接引用,而且允许函数既可以读取x也可以修改x。
因为void test(double x,long *p1, double *p2) { *p1 = (long) x; *p2 = x - *p1; } test(3.14159, &i, &d);i和d前有取地址运算符&,所以test函数的实际参数是指向i和d的指针,而不是i和d的值。调用test函数时,把值3.14159复制到x中,把指向i的指针存储在p1中,而把指向d的指针存储在p2.
博客围绕scanf函数调用中取址运算符&的使用展开。阐述了调用scanf时若忘记在变量前放&,值不会存入变量;说明了为何需要&,即要传递指向变量的指针;还拓展了取址运算符与间接寻址运算符的关系,以及指针作为函数参数的情况。
3333





