C 函数参数中的字符串
在上述程序中,C 函数参数中的字符串,c,gcc,string-literals,function-parameter,C,Gcc,String Literals,Function Parameter,在上述程序中,HelloWorld将位于只读部分(即字符串表)x将指向该只读部分,因此尝试修改该值将是未定义的行为 但是y将在堆栈中分配,并且HelloWorld将被复制到该内存中。所以修改y会很好 这是我的问题: 在以下程序中,如果内容被修改,则char*arr和char arr[]都会导致分段错误 int main() { char *x = "HelloWorld"; char y[] = "HelloWorld"; x[0] = 'Z';
HelloWorld
将位于只读部分(即字符串表)x
将指向该只读部分,因此尝试修改该值将是未定义的行为
但是y
将在堆栈中分配,并且HelloWorld
将被复制到该内存中。所以修改y会很好
这是我的问题:
在以下程序中,如果内容被修改,则char*arr
和char arr[]
都会导致分段错误
int main()
{
char *x = "HelloWorld";
char y[] = "HelloWorld";
x[0] = 'Z';
//y[0] = 'M';
return 0;
}
void function(char arr[])
//void function(char *arr)
{
arr[0] = 'X';
}
int main()
{
function("MyString");
return 0;
}
类似于
function("MyString");
“MyString”
在这两种情况下都是字符串文本,并且在这两种情况下字符串都是不可修改的
char *s = "MyString";
function(s);
将字符串文本的地址作为参数传递给
函数。在函数参数列表中,char arr[]
与char*arr
完全等效,因此定义对和声明对是等效的
function("MyString");
问题在于调用上下文。您为函数提供了一个字符串文本;不能修改字符串文字;函数试图修改给定的字符串文字;您的程序调用了未定义的行为并崩溃。都是完全洁净的
将字符串文字视为static const char literal[]=“字符串文字”编码>,不要试图修改它们。char*arr;
上面的语句意味着arr是一个字符指针,它可以指向一个字符或字符串
&char-arr[];
上面的语句意味着arr是字符串,可以存储尽可能多的字符,甚至一个字符,但将始终依赖于“\0”字符,因此使其成为字符串
(例如,char arr[]=“a”类似于char arr[]={'a','\0'})
但是,当在被调用函数中用作参数时,传递的字符串将逐个字符存储在形式参数中,没有任何区别。可能的重复与数组参数大小的讨论无关。这是关于字符串文字与字符数组的一致性,它与大小无关,甚至可以说“代码>静态conchchar <代码>拥有正确的存储时间。C++标准实际上指定了字符串文字是<代码> const 。不幸的是,C标准没有这样做,大概是因为这会破坏太多的遗留代码,这些代码虽然没有修改这些文字,但其声明却很松散。@microtherion:是的,关于遗留代码,你是对的。GCC v3.x和更早版本有一个选项-fwriteable strings
(有两个e的IIRC,但可能是一个),它使字符串文本可写而不是常量。GCC v4.x不支持该选项;字符串文字总是不可写的。我认为第一句话可能会被误解,在函数原型中,这两个句子是相同的,而不是在函数体中。我知道你的意思,但也许不是每个读者都这么想。@DanielFischer:我明白你的意思;修订版解决了这个问题吗?在第一种情况下,HelloWorld
仅在char arr[]
情况下是字符串文字。右??在第一个代码片段中,y
的字符串文字是复制到堆栈中的初始值设定项。如果函数被多次调用,那么数组将在每次调用时初始化,可能是使用其他地方的常量初始值设定项。不过,该数组是可修改的。
void function(char arr[]) { ... }
void function(char *arr) { ... }
void function(char arr[]);
void function(char *arr);