C 为什么指针声明指向未知内存,而定义不指向未知内存?

C 为什么指针声明指向未知内存,而定义不指向未知内存?,c,pointers,memory,C,Pointers,Memory,我知道以下代码返回分段错误,因为它试图写入q指向(某个随机地址)的内存部分,并且给定进程不允许写入该内存部分: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(){ char* p = "Hello"; char* q; strcpy(q, p); printf("%s\n", q); } 但为什么下面的例子有效呢 #include <stdio

我知道以下代码返回分段错误,因为它试图写入
q
指向(某个随机地址)的内存部分,并且给定进程不允许写入该内存部分:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
  char* p = "Hello";
  char* q;

  strcpy(q, p);
  printf("%s\n", q);
}
但为什么下面的例子有效呢

#include <stdio.h>

int main(){
  char* p = "Hello";
  printf("%s\n", p);
}
#包括
int main(){
char*p=“你好”;
printf(“%s\n”,p);
}
不是
char*p=“Hello”还指向某个未知内存,该内存是给定进程不允许写入的?

代码

char* p = "Hello";
创建一个包含六个字符的数组,并将它们设置为
“Hello”
(第六个字符是空字符)。然后,它将该数组的内存地址写入
p
。因此
p
指向一个初始化的内存段

关于第二个示例:
p
包含字符数组的内存地址
“Hello”
。如果希望
q
包含相同的内存地址,则必须使用以下命令

q = p;
在代码中

q = &p;
类型不兼容,因为
q
具有类型
char*
,而
&p
具有类型
char**
代码

char* p = "Hello";
创建一个包含六个字符的数组,并将它们设置为
“Hello”
(第六个字符是空字符)。然后,它将该数组的内存地址写入
p
。因此
p
指向一个初始化的内存段

关于第二个示例:
p
包含字符数组的内存地址
“Hello”
。如果希望
q
包含相同的内存地址,则必须使用以下命令

q = p;
在代码中

q = &p;

类型不兼容,因为当您编写
char*p=“Hello”时,
q
具有类型
char*
,而
&p
具有类型
char**

char
数组,填充为
{H',e',l',l',o','\0'}
。指针
p
用该数组的地址填充。因此地址是有效的,它可以安全地读取,但不能写入,它可以作为可读字符串传递给C的字符串函数,并且您无需担心
malloc
ing和
free
ing字符串文本,因为它们代表静态数组。

当您编写
char*p=“Hello”char
数组,填充为
{H',e',l',l',o','\0'}
。指针
p
用该数组的地址填充。因此,地址是有效的,可以从安全的但不写入的位置读取,它可以作为可读字符串传递给C的字符串函数,您不必担心
malloc
ing和
free
ing字符串文本,因为它们代表静态数组。

当您编写
char*p=“Hello”时,编译器在内部创建一个
const char[6]
来保存字符串,然后将其地址复制到
p
。不幸的是,字符串literal的类型不是const,因此您不会收到任何警告,告诉您正在删除
const
属性,但不能修改字符串literal

因此
p
指向一个定义良好的内存区域,您可以安全地从中读取,例如使用
printf(“%s\n”,p)

问题是不能修改字符串literal,并尝试使用指针进行写入,如
p[1]=“a”调用未定义的行为。在常见的实现中,编译器实际上使用只读段来存储字符串,如果您试图覆盖它,就会出现内存冲突或段冲突错误


但它不是未知内存,而是只读内存。

当您编写
char*p=“Hello”,编译器在内部创建一个
const char[6]
来保存字符串,然后将其地址复制到
p
。不幸的是,字符串literal的类型不是const,因此您不会收到任何警告,告诉您正在删除
const
属性,但不能修改字符串literal

因此
p
指向一个定义良好的内存区域,您可以安全地从中读取,例如使用
printf(“%s\n”,p)

问题是不能修改字符串literal,并尝试使用指针进行写入,如
p[1]=“a”调用未定义的行为。在常见的实现中,编译器实际上使用只读段来存储字符串,如果您试图覆盖它,就会出现内存冲突或段冲突错误


但它不是未知内存,只是只读内存。

@user3121023哦,那是学者的错误,谢谢。为了避免混淆,我删除了第二个问题。否决我的人请说明原因,这样我可以改进这个问题。由于删除了帖子的一部分,ThanksPost现在更令人困惑了。建议出于良好的礼仪将其带回来。示例中没有一个试图修改
p
所指内容。那么为什么要问“难道不是
char*p=“Hello”;
也指向一些不允许写入的未知内存…”@user3121023哦,那是个错误,谢谢。为了避免混淆,我删除了第二个问题。否决我的人请说明原因,这样我可以改进这个问题。由于删除了帖子的一部分,ThanksPost现在更令人困惑了。建议出于良好的礼仪将其带回来。示例中没有一个试图修改
p
所指内容。那么,为什么要问“难道不是
char*p=“Hello”;
也指向一些不允许写入的未知内存…”为什么要投反对票?请告诉我哪里出了问题。字符串文字的类型不是常量。为什么要投反对票?请告诉我哪里出错了。字符串文字的类型不是常量。什么是字符串文字?什么