gpt4 book ai didi

c - 如果我在 scanf 函数中将 "&"与字符串一起使用会怎样?

转载 作者:太空狗 更新时间:2023-10-29 15:23:12 25 4
gpt4 key购买 nike

我刚刚在博客中看到了一些代码。它使用了

scanf("%s",&T);

但正如我们所知,我们不应该在字符串中使用 & 符号,因为它会自动分配该字符串的首地址。我确实运行了该代码,令人惊讶的是它可以正常工作,所以我想知道当我在字符串中使用 & 时会发生什么?

#include <stdio.h>
int main()
{
char T[2];
scanf("%s", &T);
printf("You entered %s\n", T);
}

最佳答案

代码片段的相关部分是:

char T[2];
scanf("%s", &T);

&T 是指向两个字符数组的指针 (char (*)[2])。这不是 scanf 需要的 %s 说明符类型:它需要一个指向字符的指针 (char *)。所以程序的行为是未定义的。

如您所知,编写此程序的正确方法是

char T[2];
scanf("%s", T);

由于 T 是一个数组,当它在大多数上下文中使用时,它“衰减”为指向第一个字符的指针:T 等同于 &(T[0]) 类型为 char *。当您获取数组的地址 (&T) 或其大小 (sizeof(T)) 时,不会发生这种衰减。

实际上,几乎所有平台都对指向同一地址的所有指针使用相同的表示。因此,编译器为 T&T 生成完全相同的代码。有一些罕见的平台可能会生成不同的代码(我听说过它们,但我不能说出一个)。一些平台对“字节指针”和“字指针”使用不同的编码,因为它们的处理器本身处理字而不是字节。在这样的平台上,指向同一地址的 int *char * 具有不同的编码。这些类型之间的转换会转换值,但在变量参数列表之类的东西中滥用会导致错误的地址。但是,我希望此类平台使用字符数组的字节地址。还有一些罕见的平台,其中指针不仅对数据地址进行编码,而且还对某些类型或大小信息进行编码。然而,在这样的平台上,类型和大小信息必须是等效的:它是一个 2 字节的 block ,从 T 的地址开始,并且可以逐字节寻址。因此,这个特定错误不太可能产生任何实际影响。

请注意,如果您首先使用指针而不是数组,情况将完全不同:

char *T; // known to point to an array of two characters
scanf("%s", &T); // bad

这里的&T是一个指向内存中包含字符数组地址的位置的指针。所以 scanf 会将它读取的字符写入内存中指针 T 存储的位置,而不是 T 指向的位置.大多数编译器会分析 printfscanf 等函数的格式字符串,因此会发出错误消息。

请注意,char T[2] 只能容纳两个字符,其中包括字符串末尾的空字节。所以 scanf("%s", T) 只能读取一个字符。如果此时输入包含多个非空白字符,程序将溢出缓冲区。要读取单个字符并使其成为单字符字符串,请使用

char T[2];
scanf("%c", T);
T[1] = 0;

scanf("%s", T) 不同,它可以读取任何字符,甚至是空格。要读取具有长度限制的字符串,请将限制添加到 %s 规范。你永远不应该在 scanf 中使用无限的 %s,因为这将读取尽可能多的可用输入,无论内存中有多少空间可以存储此输入。

char T[2];
scanf("%1s", T); // one less than the array size

关于c - 如果我在 scanf 函数中将 "&"与字符串一起使用会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53332187/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com