可能重复:
scanf()与&运算符混淆
为什么我们需要一个&in scanf来输入整数,为什么不输入字符.&in scanf在获取输入时是指merory位置.
例如:-
main()
{
int a;
char c;
scanf("%d",&a);
scanf("%c"c);
}
Run Code Online (Sandbox Code Playgroud)
对于每个转换说明符,scanf()期望相应的参数是指向正确类型的指针:%d期望一个类型的参数int *,%f期望一个类型的参数double *,%c并且%s都期望一个类型的参数char *,等等.
%c和之间的区别在于%s前者告诉scanf()读取单个字符并将其存储在相应参数指定的位置,而后者告诉scanf()读取多个字符,直到它看到0值字符并将所有这些字符存储在缓冲区中从参数指定的位置开始.
&如果它们不是指针类型,则需要在参数上使用运算符.例如:
int x;
int *px = some_valid_memory_location_such_as_&x;
char c;
char *pc = some_valid_memory_location_such_as_&c;
...
scanf("%d", &x); // x is not a pointer type, so we must use the & operator
scanf("%d", px); // px is a pointer type, so we don't need the & operator
scanf("%c", &c); // etc.
scanf("%c", pc); // etc.
Run Code Online (Sandbox Code Playgroud)
令人困惑的地方是读取字符串(使用%s转换说明符):
char buf[SIZE];
scanf("%s", buf); // expression 'buf' *implicitly* converted to pointer type
Run Code Online (Sandbox Code Playgroud)
&在这种情况下,为什么我们不需要操作员?它与C如何处理数组表达式有关.当编译器看到数组类型的表达式(例如buf在scanf()调用中)时,它将隐式地将表达式从type转换N-element array of T为pointer to T,并将其值设置为数组中第一个元素的地址.这个值不是左值 - 它不能分配给(因此你不能写出类似的东西buf = foo).此规则的唯一例外是当数组表达式是sizeof或&运算符的操作数时,或者数组表达式是用于初始化另一个数组的字符串文字时:
char *p = "This is a test"; // string literal implicitly converted to char *,
// string *address* written to p
char a[] = "This is a test"; // string literal not implicitly converted,
// string *contents* copied to a
Run Code Online (Sandbox Code Playgroud)
简而言之,表达式buf是从类型隐式转换char [SIZE]为char *,因此我们不需要使用&运算符,实际上表达式的类型&buf将是pointer to SIZE-element array of char,或者(*)[SIZE],它不是转换说明符所scanf()期望的%s.