为什么我不需要在打印之前取消引用C中的字符指针?

use*_*531 6 c

为什么这段代码有效?在我打印出来之前,我希望我需要取消引用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会出现以下代码?

    printf("%s\n", *ptr);
Run Code Online (Sandbox Code Playgroud)

当你这样做时,由于 %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)


Eri*_*inn 5

这是因为%s您传递给的格式字符串中的格式说明符printf意味着相应的参数应该是字符串,而不是单个字符.在C中,字符串是指向一个字符块开头的指针,该字符块在结尾处具有空字符(值为0的字节).

基本上,这是有效的,因为你正在做你想要的打印字符串.