关于C#:char * str =“…”和char str [N] =“……”之间的区别?

Difference between char *str = “…” and char str[N] = “…”?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
What is the difference between char s[] and char *s in C?
Question about pointers and strings in C

我在读C中的弦乐,我很困惑。我可以用两种方式"声明"字符串:

1
2
char *str ="This is string";
char str2[20] ="This is string";

这两个声明有什么区别?什么时候会优先选择char str2[20]而不是char *str


在C语言中,字符串表示为chars的序列,带有一个空字符(aka 0,'\0')。它们存储在内存中,您可以使用引用它的方法。您已经确定了引用它的两种方法:char *,它是指向chars序列的指针,以及一个数组,它是作为实际变量的字符的即时字符串。请注意,字符串"abc"的长度为4个字节,只要有一个额外的空字符来表示字符串的结尾。

除此之外,您实际上还在示例中分配字符串,这也涉及到在编译时给定的字符串。

所以有两个问题。第一个问题是如何表示字符串(char *vs char[]),第二个问题是编译时字符串。

举个例子:

第一个在程序的文本中创建一个常量字符串,并创建一个指向它的指针。根据编译器的不同,它可以存储在任何地方。它相当于mallocing一个字符串并存储指向它的指针,除非您不能更改内存的内容。它是一个char *,因此您可以将指针更改为指向其他地方,如另一个malloced字符串或示例2中定义的数组的开头。

第二个创建一个char数组(一种表示字符串的方法)。数组在函数执行期间存储并分配在堆栈上,您可以更改内容。因为它不是指针,所以不能将其更改为指向其他字符串。


1
char *str ="This is string";

将字符串放入程序的constant data section (also known as .rdata)中。此数据不能修改。

1
char str2[20] ="This is string";

在这种类型的声明中,如果在function scope中声明,数据最好是程序的stored in the stack area;如果在global scope中声明,数据最好是data section。可以修改此数据。

因此,如果您有必要修改数据,那么使用第二种方法。


char *str ="This is string";—这将使文本段中的字符串保持为只读数据,并将地址存储在本地指针变量str中。

1
2
str[0] = 'a'; //This will leads to crash, because strings are in read only segment.
printf("%d",sizeof(str)); //This will print 4(in 32bit m/c) or 8(in 64 bit m/c)

char str2[20] ="This is string";—这将把字符串作为字符数组保存在本地堆栈中。

1
2
str2[0] = 'a'; //This will change the first character to a
printf("%d",sizeof(str2)); //This will print 20

C字符串在内存中是常量,因此:

1
char *str ="This is string";

将"this is string"存储在内存中,它不是可变的,您只能将另一个地址分配给str。

然而

1
char str2[20] ="This si string";

1
char String2[20]={'T','h','i','s',' ','s','i',' ','s','t','r','i','n','g','\0'};

它不在内存中存储字符串,而是存储独立的字节。

如果要使用像消息这样的常量字符串,请使用第一行。如果您想像在字处理器中那样使用和操作字符串,请使用second。

当做


C没有字符串。所有这些都是char数组。C中的数组只是指向第一个元素的指针。

最简单的方法实际上是你的第一个变体。如果不为文本指定数组的显式长度,将避免意外地执行类似的操作

1
char[3] ="abc";