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(即内存地址)。
这就是为什么 A 和 D 是错误的。
至于 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
我有下面的选择题,想不通为什么(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(即内存地址)。
这就是为什么 A 和 D 是错误的。
至于 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