C 为什么我可以更新指向(常量)字符串文字的指针?
非常感谢所有答案,并感谢所有花时间澄清这些问题的人-非常感谢你 我正在学习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
...
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