C 中的符号 (&) 和 scanf?

Ampersand(&) and scanf in C?

我有下面的选择题,想不通为什么(A)和(C)不对,如有解释,将不胜感激!下列问题中唯一正确的答案是(B)。

Which of the following is a correct usage of scanf?
(A) int i=0; scanf("%d", i);
(B) int i=0; int *p=&i; scanf("%d", p);
(C) char *s="1234567"; scanf("%3s", &s);
(D) char c; scanf("%c", c);

对于 A:

(A) int i=0; scanf("%d", i);

这应该是:

(A) int i=0; scanf("%d", &i);

看看scanf()signature

学习这个:

int i=0; scanf("%d", i);

说明:i变量的地址是什么?为此 & 运算符给出了 i 变量的地址。 scanf() 获取用户输入并将值存储在该地址上。

char *s="1234567"; scanf("%3s", &s);

说明:在本例中,您将字符串分配给位于代码段中的字符指针。这个选项的主要目的是我们不能修改代码部分。但在这种情况下,我们正在修改指针。因此,在该指针指向新分配的地址之后,它可能会输入错误的地址,然后出现分段错误。所以我们丢失了之前分配的字符串。

scanf 想要一个正确的地址来存储结果:

(A) int i=0; scanf("%d", i);

i这里是传值,没有地址:错误。

(B) int i=0; int *p=&i; scanf("%d", p);

p是一个指向int的指针,scanf可以把它的结果存在这里:对

(C) char *s="1234567"; scanf("%3s", &s);

&s是指向char *的指针的地址,你不能在那里存储字符串:错误

(D) char c; scanf("%c", c);

c是按值传递的,不是地址:错误

您必须将指针传递给该函数,以便它知道在内存中的何处存储该值。如果你只是按值传递,它会将其视为一个内存地址,一切都会崩溃。因此,您使用 & 获取变量的 reference(即内存地址)。

这就是为什么 AD 是错误的。

至于 C,它 看起来 是正确的,因为您提供了一个指针,但您实际上是在引用该指针。所以 scanf 将覆盖指针本身,而不是它指向的内存。

如果您刚刚提供了 s,那么我们将进入另一个禁区。指针指向一个 字符串文字 ,您不能修改它。但是,如果它不是文字而是使用文字作为初始值设定项的数组,它 没问题,前提是您没有读入超过它可以存储的数据:

char s[] = "1234567"; scanf("%3s", s); /* this is okay */ 

scanf 带有说明符 %d 将输入作为要扫描的位置的地址。

对于 1. 你给出的输入是 i 这是错误的

对于 2. 您将输入作为 p,其地址为 i。这在初始化期间设置为 int *p=&i。所以这是正确的。

对于 3. 说明符是 %s。这需要输入开始存储字符串的地址。 s的输入是一个数组,已经包含了地址。 &s 错误。

使用 4。您使用的是 %c 的说明符,它也采用位置的地址。因此在这种情况下输入 c 是错误的,因为要获取您需要的位置的地址 &c