为什么这段代码有效?在我打印出来之前,我希望我需要取消引用ptr, printf("%s\n", *ptr);但Segmentation Fault如果我尝试这样做,我会得到一个.
#include <stdio.h>
int main(int argc, char *argv[])
{
char name[] = "Jordan";
char *ptr = name;
printf("%s\n", ptr);
}
Run Code Online (Sandbox Code Playgroud)
希望你们能给我一些见解.
Gri*_*han 21
打印字符串时我们需要字符串的起始地址.
printf("%s\n", ptr);
^ address with %s
Run Code Online (Sandbox Code Playgroud)
它打印字符直到\0nul遭遇.
而打印聊天 int ..我们需要值变量:
printf("%c\n", *ptr);
^ * with %c print first char
Run Code Online (Sandbox Code Playgroud)
在scanf()字符串中,您总是需要提供地址:
scanf("%s", ptr);
^ string address
Run Code Online (Sandbox Code Playgroud)
也适用于int scanf()char
scanf("%c", ptr);
^ read at first location char address
Run Code Online (Sandbox Code Playgroud)
注意: Scanf()需要使用地址%c将扫描值存储在内存中.
要小心,你ptr 指向一个字符串常量,所以你不能在scanf使用.
为什么Segmentation会出现以下代码?
Run Code Online (Sandbox Code Playgroud)printf("%s\n", *ptr);
当你这样做时,由于 %sprintf解释*ptr为一个地址,但它实际上不是一个地址,如果你把它当作地址,它指向一个为你的程序读取保护的位置(进程)所以它会导致分段错误.
你的ptrvia name指向内存中的一些常量字符串("Jordan"),如下图所示:
name 2002
?????????????????????????????????????????????????????????????
? 'J' ? 'o' ? 'r' ? 'd' ? 'a' ? 'n' ?'\0' ? ........
?????????????????????????????????????????????????????????????
^
|
ptr = name
==> ptr = 2002
*ptr = 'J'
Run Code Online (Sandbox Code Playgroud)
在printf("%s\n", *ptr);中*ptr = 'J'的字符"J"和ASCII值74,但74地址是不是你的过程控制之下,并尝试由该内存位置和它的内存冲突和分割故障发生时阅读.
如果您编译包含printf("%s\n", *ptr);然后使用适当选项的代码-Wall,GCC则会收到如下警告:
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’
说%s需要(期望)一个类型的地址,char*但你正在投入价值
注意:
printf("%s\n", *ptr);
^ ^ argument-2
argument-1
Run Code Online (Sandbox Code Playgroud)
这是因为%s您传递给的格式字符串中的格式说明符printf意味着相应的参数应该是字符串,而不是单个字符.在C中,字符串是指向一个字符块开头的指针,该字符块在结尾处具有空字符(值为0的字节).
基本上,这是有效的,因为你正在做你想要的打印字符串.