C 中的字符串常量可以通过两种方式初始化:使用数组和字符指针;
两者都可以访问字符串常量并可以打印它;
来到编辑部分,如果我想编辑一个使用数组初始化的字符串,它很简单,我们可以使用数组单个字符进行编辑。
如果我想编辑一个使用字符指针初始化的字符串,这是不可能的吗?
让我们考虑以下两个程序:
程序#1:
#include<stdio.h>
void str_change(char *);
int main()
{
char str[] = "abcdefghijklm";
printf("%s\n", str);
str_change(str);
printf("%s\n", str);
return 0;
}
void str_change(char *temp)
{
int i = 0;
while (temp[i] != '\0') {
temp[i] = 'n' + temp[i] - 'a';
i++;
}
}
程序#2:
#include<stdio.h>
void str_change(char *);
int main()
{
char *str = "abcdefghijklm";
printf("%s\n", str);
str_change(str);
printf("%s\n", str);
return 0;
}
void str_change(char *temp)
{
int i = 0;
while (temp[i] != '\0') {
temp[i] = 'n' + temp[i] - 'a';
i++;
}
}
我尝试使用以下版本的函数来编程 #2,但没有用
void str_change(char *temp)
{
while (*temp != '\0') {
*temp = 'n' + *temp - 'a';
temp++;
}
}
第一个程序运行良好,但其他程序出现段错误,那么,如果需要编辑字符串,是否必须仅在函数之间传递使用数组初始化的字符串常量?
最佳答案
So it is mandatory to pass only the string constants that are initialized using arrays between functions, if editing of string is requiredc?
基本上是的,尽管真正的解释并不是这些确切的文字。以下定义创建一个数组:
char str[] = "abc";
这不是字符串文字。 "abc"
标记是字符串文字语法,而不是字符串文字对象。在这里,该文字指定 str 数组的初始值。数组对象是可修改的。
char *str = "abc";
这里源代码中的“abc”
语法是表示翻译后的程序镜像中的字符串文字对象的表达式。它也是一种数组,具有静态存储持续时间(与str
的存储持续时间无关)。 "abc"
语法计算结果为指向该数组第一个字符的指针,并且 str
指针使用该指针值进行初始化。
字符串文字不需要支持修改;尝试修改字符串文字对象的行为是未定义的行为。
即使在无法预测段错误的系统中,也可能会发生奇怪的事情。例如:
char *a = "xabc";
char *b = "abc";
b[0] = 'b'; /* b changes to "bbc" */
假设作业有效。 a
也可能会更改为 "xbbc"
。 C 编译器允许合并相同文字或作为其他文字后缀的文字的存储。
a
和 b
是否靠近并不重要;即使在不同函数中的远程声明之间,甚至在不同的翻译单元中,这种偷偷摸摸的效果也可能发生。
字符串文字应被视为程序镜像的一部分;成功修改字符串文字的程序实际上是自修改代码。在您的环境中出现“段错误”的原因正是因为防止自修改代码:已编译程序的“文本”部分(包含机器代码)位于虚拟内存的写保护页中。字符串文字与机器代码一起放置在那里(通常散布在其函数中)。尝试修改字符串文字会导致对文本部分的写访问,该访问会被页面上的权限位阻止。
在另一种环境中,C 代码可能用于生成进入只读存储器的软件镜像:实际的 ROM 芯片。字符串文字与代码一起进入 ROM。尝试修改一个就相当于尝试修改 ROM。硬件可能无法检测到这一点。例如,指令可能看起来正在执行,但是当读回该位置时,原始值仍然存在,而不是新值。与段错误一样,这在“未定义行为”的规范范围内:任何行为都是!
关于c - 在C中,是否必须传递字符数组名称才能更改字符串常量的字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45667274/