我想知道为什么这段代码可以正常工作。我假设scanf
正在将值赋给指向char
的指针的地址。我知道这个表达式是未定义的,但为什么printf
使用指针可以打印正确的值?
int main() {
char* p;
p = (char*)malloc(sizeof(char));
scanf("%c", &p);
printf("%c", p);
return 0;
}
结果是
c
c
答案 0 :(得分:1)
p
是一个保存内存地址的变量,内存地址肯定长于1个字节。如果在此变量中存储char值,则先前的值(malloc的内存块)将丢失。 printf
只需将变量视为char
变量并打印其内容即可。如果你怀疑char会被存储在malloc获得的内存块中,那就不是了。
试试这个:
int main() {
char *p, *q;
p = q = (char*)malloc(sizeof(char));
scanf("%c", &p);
printf("%c\n%c\n", p, *q);
return 0;
}
答案 1 :(得分:0)
使用scanf()
,您将(相当强制地)一个字节存储到一个多于一个字节的变量(sizeof(char *)
,在64位计算机上可能是8个字节)。使用printf()
,然后读取此大小为sizeof(char)
的变量(超过一个字节)的一个字节(sizeof(char *)
,总是按标准一个)并打印出来。您的变量p
比存储char
所需的空间更多。由于大小不对齐,因此您不确定p
将读取printf()
的哪个字节。它可能是scanf()
写的字节,也可能是垃圾数据。你很幸运,printf()
读取scanf()
写的相同字节。
如果所有这些听起来有点不确定,那是因为它涉及未定义的行为。您未正确使用scanf()
和printf()
,因此他们无法保证会发生什么。简而言之,不要这样做。
printf()
和scanf()
不对作为参数给出的源/目标执行任何特殊类型检查。他们使用花式指针算法和堆栈上的参数来确定根据需要读取/写入内容的位置。在编译器构建它之后,printf()
和scanf()
不会抱怨。您的编译器应该已经警告您给出的参数类型与格式字符串不匹配。如果没有,您可能有一个坏/旧的编译器,或者您应该使用命令行选项-Wall
启用更多警告。
答案 2 :(得分:0)
为了帮助解释其他答案,看起来好像你的目标是做以下事情 - 比较差异,然后再看看其他答案,看看是否有帮助,因为我不确定你还没有清楚你的代码中发生了什么。
int main() {
char* p = malloc(sizeof(char));
scanf("%c", p);
printf("%c", *p);
return 0;
}