C 为什么我可以更新指向(常量)字符串文字的指针?

C 为什么我可以更新指向(常量)字符串文字的指针?,c,pointers,string-literals,C,Pointers,String Literals,非常感谢所有答案,并感谢所有花时间澄清这些问题的人-非常感谢你 我正在学习C,刚刚完成了关于指针的一章。 在这本书中,我正在阅读一个示例代码,它让我非常困惑 示例代码的一部分: ... 1 char *inp_file = ""; 2 char *out_file = ""; 3 char ch; 4 5 while ( ( ch = getopt( argc, argv, "i:o:" )) != EOF ) 6 { 7 switch( ch ) 8

非常感谢所有答案,并感谢所有花时间澄清这些问题的人-非常感谢你

我正在学习C,刚刚完成了关于指针的一章。 在这本书中,我正在阅读一个示例代码,它让我非常困惑

示例代码的一部分:

...

 1  char *inp_file = "";
 2  char *out_file = "";
 3  char ch;
 4  
 5  while ( ( ch = getopt( argc, argv, "i:o:" )) != EOF )
 6  {
 7      switch( ch )
 8      {
 9          case 'i':
10              inp_file = optarg;
11              break;
12          case 'o':
13              out_file = optarg;
14              break;
15  
16          default:
17              fprintf( stderr, "Unknown option: '%s'/n", optarg );
18              return 2;
19      }
20  }
21  
22  argc -= optind;
23  argv += optind;

...
我的理解是
char*inp\u file=“”
char*out\u file=“”
是指向 字符串文本

他们指的是哪里?考虑到它是一个空的

当它们存储在只读存储器中时,如何更新它们(第10行、第13行)

char*指针
char*pointer=”“相同


此外,我尝试了这个,它的工作

#include <stdio.h>

int main( int argc, char *argv[] )
{
    char *msg = "Hello";

    msg = "World";

    printf("%s\n", msg );// Prints 'World'
}
#包括
int main(int argc,char*argv[])
{
char*msg=“你好”;
msg=“世界”;
printf(“%s\n”,msg);//打印“World”
}
我100%肯定
char*msg=“你好”是指向字符串文字的指针

Memory loc'n:      Contents
PTR_BASE+0x0000:   (BASE+0x0000)
PTR_BASE+0x0008:   ...
当它位于只读存储器中时,为什么会更新为“World”

这是一次全新的调动还是什么

我现在真的很困惑我对指针的了解。我错过了什么

我的理解是
char*inp\u file=“”
char*out\u file=“”
是指向字符串文本的指针

是的,他们是

他们指的是哪里

它们指向一个空字符串文本

char*指针
char*pointer=”“相同

编号
char*指针
是未初始化的指针,而
char*pointer=“”初始化的代码<代码>“
的类型为
常量字符[1]
具有元素
'\0'

当它位于只读内存中时,为什么会更新为
“World”

char*msg=“你好”相当于

char const *msg = "Hello";  
这意味着不应修改指向的字符串文字
msg
,但此约束位于字符串文字上,而不是指向字符串文字的指针<可以修改代码>消息

这是一次全新的调动还是什么

msg=“世界”
是指针
msg
的新字符串文本赋值

我的理解是
char*inp\u file=“”
char*out\u file=“”
是指向字符串文本的指针

是的,他们是

他们指的是哪里

它们指向一个空字符串文本

char*指针
char*pointer=”“相同

编号
char*指针
是未初始化的指针,而
char*pointer=“”初始化的代码<代码>“
的类型为
常量字符[1]
具有元素
'\0'

当它位于只读内存中时,为什么会更新为
“World”

char*msg=“你好”相当于

char const *msg = "Hello";  
这意味着不应修改指向的字符串文字
msg
,但此约束位于字符串文字上,而不是指向字符串文字的指针<可以修改代码>消息

这是一次全新的调动还是什么


msg=“世界”
是指针的新字符串文本赋值
msg

您没有更新
“hello”
,您正在设置
msg
指向不同的字符串,
“World”
-它可以工作,也可以不工作,而是执行
strcpy(msg,“World”)
(取决于系统设置,但这肯定是未定义的行为,所以不要编写这样做的代码)


要显示这一点,您可以在
msg=“World”
行的两侧添加
printf(“Before:%p\n”,(void*)msg);
printf(“Before:%p\n”,(void*)msg;

您没有更新
“hello”
,您正在将
msg
设置为指向另一个字符串,
“World”
-改为执行strcpy(msg,“World”)
可能有效,也可能无效(取决于系统设置,但这肯定是未定义的行为,因此不要编写执行此操作的代码)


要显示这一点,您可以在
msg=“World”
行的任一侧添加
printf(“Before:%p\n”,(void*)msg);
printf(“Before:%p\n”,(void*);

实际上有两件事。首先,是字符串文字。您创建了一个零长度的字符串,
,它仍然以NUL结尾,因为所有C字符串都以NUL结尾-这就是您知道结尾在哪里的方式

因此,您有一个如下所示的内存块:

Memory loc'n:  Contents
BASE+0x0000:  # start of string
BASE+0x0000:  '\0'  # end of string
也就是说,一个包含“无字符”的内存块,后跟一个尾随的NUL字节以标记字符串的结尾

该数据通常被认为是“常量”。它可能存储在“常量数据”中,也可能不存储在“常量数据”中。这取决于链接器、操作系统等

但是,这只是“常量字符串文字”。代码还有第二部分:

char *inp_file = "";
您已声明指向常量字符串文字的指针。该指针是指针大小的对象(如果有32位地址空间,则为4字节;如果有64位地址空间,则为8字节;如果有不同或混合的地址空间,则为其他大小)并包含常量字符串文本的第一个字节的内存地址

Memory loc'n:      Contents
PTR_BASE+0x0000:   (BASE+0x0000)
PTR_BASE+0x0008:   ...
由于您在任何函数之外声明了
inp_file
,因此它被视为具有文件作用域。文件作用域初始化变量存储在数据段中(有关内存布局的详细信息)。(请注意,未初始化变量可能存储在零段未初始化段中,具体取决于体系结构。)

另一方面,同样取决于架构和p