不应该';在C语言中直接指向文本不是不可能吗?

不应该';在C语言中直接指向文本不是不可能吗?,c,pointers,c-strings,C,Pointers,C Strings,我正在学习C,我遇到了指针。 尽管我在本教程中学到了比课本更多的东西,但我仍然对char指针感到好奇 如果我对这个进行编程 #include <stdio.h> int main() { char *ptr_str; ptr_str = "Hello World"; printf(ptr_str); return 0; } 我不明白为什么编译时没有错误,因为指针ptr_str直接指向文本,而不是文本的第一个字符。我以为只有这样才行 #inc

我正在学习C,我遇到了指针。 尽管我在本教程中学到了比课本更多的东西,但我仍然对char指针感到好奇

如果我对这个进行编程

#include <stdio.h>

int main()
{
    char *ptr_str;

    ptr_str = "Hello World";

    printf(ptr_str);

    return 0;

}

我不明白为什么编译时没有错误,因为指针ptr_str直接指向文本,而不是文本的第一个字符。我以为只有这样才行

#include <stdio.h>

int main()
{
    char *ptr_str;
    char var_str[] = "Hello World";

    ptr_str = var_str;

    printf(ptr_str);

    return 0;

}
#包括
int main()
{
char*ptr_str;
char var_str[]=“你好,世界”;
ptr_str=var_str;
printf(ptr_str);
返回0;
}

那么在第一个示例中,我是如何直接指向文本的呢?

您的代码可以正常工作,因为字符串文本本质上是静态数组

ptr_str = "Hello World";
编译器将其视为

static char __tmp_0[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0' };
ptr_str = __tmp_0;
(除非试图修改字符串文字的内容具有未定义的行为)


您甚至可以将
sizeof
应用于字符串文字,您将得到数组的大小:
sizeof“Hello”
是6,例如。

您的代码可以工作,因为字符串文字本质上是静态数组

ptr_str = "Hello World";
编译器将其视为

static char __tmp_0[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0' };
ptr_str = __tmp_0;
(除非试图修改字符串文字的内容具有未定义的行为)


您甚至可以将
sizeof
应用于字符串文本,您将得到数组的大小:
sizeof“Hello”
是6,例如。

在分配给字符指针的上下文中,字符串文本的“value”是其第一个字符的地址

所以


将ptr_str设置为“H”的地址。

在为字符指针赋值的上下文中,字符串文字的“值”是其第一个字符的地址

所以


将ptr_str设置为“H”的地址

为什么第一个不能工作?正如你所看到的那样,它将起作用

字符串文本是数组。从§
C11
标准
N1570

然后使用多字节字符序列初始化静态存储持续时间和长度刚好足以包含该序列的数组。对于字符串文字,数组元素的类型为char,并使用多字节字符序列的各个字节进行初始化

现在在第一种情况下,衰减的指针基本上指向
'H'
。您已将该指针指定给
ptr\u str
。现在,
printf
需要一个格式说明符和相应的参数。这里是
%s
,相应的参数是
char*
。而
printf
将打印每个字符,直到它到达
\0
。事情就这样发生了。这就是你直接指向文本的方式


请注意,第二种情况与第一种情况有很大不同——第二种情况是制作一个可以修改的副本(试图修改第一种情况将是未定义的行为)。我们正在处理字符串文本的内容

为什么第一个不起作用?正如你所看到的那样,它将起作用

字符串文本是数组。从§
C11
标准
N1570

然后使用多字节字符序列初始化静态存储持续时间和长度刚好足以包含该序列的数组。对于字符串文字,数组元素的类型为char,并使用多字节字符序列的各个字节进行初始化

现在在第一种情况下,衰减的指针基本上指向
'H'
。您已将该指针指定给
ptr\u str
。现在,
printf
需要一个格式说明符和相应的参数。这里是
%s
,相应的参数是
char*
。而
printf
将打印每个字符,直到它到达
\0
。事情就这样发生了。这就是你直接指向文本的方式


请注意,第二种情况与第一种情况有很大不同——第二种情况是制作一个可以修改的副本(试图修改第一种情况将是未定义的行为)。我们正在处理字符串文本的内容

“我不明白为什么编译时没有错误,因为指针ptr_str直接指向文本,而不是文本的第一个字符。”它确实指向第一个字符。那么您认为“文本”是什么?指针是如何指向文本的?甚至“指向文本”而不是指向第一个字符意味着什么?你认为计算机内存是如何布局的?不要做
printf(ptr_str)
,do
put(ptr\u str)
printf(“%s\n”,ptr\u str)
printf
期望格式作为第一个参数,如果
ptr\u str
例如
“100的10%是10”
printf(ptr\u str)
将fail@Pablo事实上,它将是UB。一些编译器对此提出警告。“我不明白为什么编译时没有错误,因为指针ptr_str直接指向文本,而不是文本的第一个字符。”它确实指向第一个字符。那么您认为“文本”是什么?指针是如何指向文本的?甚至“指向文本”而不是指向第一个字符意味着什么?你认为计算机内存是如何布局的?不要做
printf(ptr_str)
,do
put(ptr\u str)
printf(“%s\n”,ptr\u str)
printf
期望格式作为第一个参数,如果
ptr\u str
例如
“100的10%是10”
printf(ptr\u str)
将fail@Pablo事实上,它将是UB。一些编译器对此发出警告。这并不完全正确,因为字符串文字是数组。“value”是数组,而不是第一个字符的地址。参见melpomene的答案。ptr_str是一个字符指针-它包含“H”的地址。它对数组一无所知。rhs值被分配给lhs,该值是arr中“H”的地址