char *array和char array[]的区别

27

如果我写这个

 char *array = "One good thing about music";

我实际上是在创建一个数组吗?我的意思是这样做跟这个有什么不同吗?

char array[] = {"One", "good", "thing", "about", "music"};

https://dev59.com/NXI-5IYBdhLWcg3wu7FU - Ciro Santilli OurBigBook.com
修改使代码出现了故障,或者至少存在缺陷。在第二个示例中,“array”是一个由字符组成的数组,它被初始化为字符指针。如果想要一个字符串数组,则声明应该是char *array [] = { ... } - Some programmer dude
4个回答

57

声明和初始化

char *array = "One good thing about music";

声明一个指向包括终止空字符在内的27个字符(只读)数组的指针array

声明和初始化:

char array[] = "One, good, thing, about, music";

声明一个包含31个字符的字符数组。

是的,数组的大小为31,因为它包括终止字符'\0'


在内存中排列,第一种方式如下:

+-------+     +------------------------------+
| 数组  | --> | "音乐的一个好处"           |
+-------+     +------------------------------+

第二种方式如下:

+------------------------------+
| "音乐的一个好处"           |
+------------------------------+

数组会衰变为指向数组第一个元素的指针。如果你有一个数组,比如

char array[] = "One, good, thing, about, music";

当需要指针时,使用普通的array&array[0]相同。

这意味着,例如,将数组作为参数传递给函数时,它将被传递为指针。

指针和数组几乎可以互换。例如,您不能使用sizeof(pointer),因为它返回实际指针的大小而不是指向的内容的大小。此外,当您执行例如&pointer时,您会得到指针的地址,但&array返回指向数组的指针。应该注意的是,&arrayarray(或其等效的&array[0])非常不同。虽然&array&array[0]都指向同一位置,但类型不同。使用上面的数组,&array的类型为char (*)[31],而&array[0]的类型为char *


更多有趣的内容:众所周知,在访问指针时可以使用数组索引。但是由于数组会衰减为指针,因此可以在数组中使用一些指针算术运算。
例如:
char array[] = "Foobar";  /* Declare an array of 7 characters */

有了上面的代码,你可以使用下列方法之一访问第四个元素(即'b'字符):

array[3]

或者

*(array + 3)

由于加法是交换的,因此最后也可以表示为

*(3 + array)

这导致了有趣的语法

3[array]

在第二个命令中,可以将array用作指向该数组的指针吗? - yaylitzis
1
@Nat95 我更新了我的答案,加入了另一个段落。 - Some programmer dude
2
&array是指向数组的指针,而不是指向第一个元素的&array[0] - Kerrek SB
1
你在 char* 字符串文字样本中忘记加逗号了。 - jterm
我认为这个答案需要更新以跟上原问题的变化! - user146043
@DrEval 问题在于所做的编辑有缺陷,会导致错误的行为。我认为 OP 并不是想让它看起来像那样,而是像我的答案一样(char array[] = "...")。否则这将没有多大意义,两个定义将大相径庭。 - Some programmer dude

9
不,你正在创建一个数组,但是有一个很大的区别:
char *string = "Some CONSTANT string";
printf("%c\n", string[1]);//prints o
string[1] = 'v';//INVALID!!

数组是在内存的一个只读部分创建的,因此您无法通过指针编辑该值,而:
char string[] = "Some string";

创建相同的只读常量字符串,并将其复制到堆栈数组中。这就是为什么:

string[1] = 'v';

在后一种情况下是有效的。
如果你写:

char string[] = {"some", " string"};

编译器会报错,因为你正在构造一个字符数组(或字符指针)的数组,并将其赋值给一个字符数组。这些类型不匹配。要么写成:
char string[] = {'s','o','m', 'e', ' ', 's', 't','r','i','n','g', '\0'};
//this is a bit silly, because it's the same as char string[] = "some string";
//or
char *string[] = {"some", " string"};//array of pointers to CONSTANT strings
//or
char string[][10] = {"some", " string"};

在最新版本中,它会给你一个字符串数组(字符数组),你实际上是可以编辑的...


3

这与……非常相似。

char array[] = {'O', 'n', 'e', ' ', /*etc*/ ' ', 'm', 'u', 's', 'i', 'c', '\0'};

但是它只提供给你只读内存。

关于char[]char *之间的区别,请参见comp.lang.c FAQ 1.32


这意味着如果你试图向它写入数据(例如 array[0] = 'X'),你会得到未定义的行为(通常是分段错误)。 - tom

2

实际上,它与之前的内容是“相同”的。

char array[] = {'O', 'n', 'e', ..... 'i','c','\0');

每个字符都是一个独立的元素,另外还有一个\0字符作为字符串终止符。

我引用了“相同”,因为char * arraychar array[]之间存在一些差异。如果您想了解更多信息,请查看C:char指针和数组之间的区别


1
这些不是“小”差异。澄清它们比让OP和未来的读者感到困惑要好。 - StoryTeller - Unslander Monica
只是一个只读数组,为什么会是一个“次要”的差异,而不与 OP 相关呢?如果你说了这样的话,接下来的 15 分钟内肯定会有后续问题。 - Elias Van Ootegem
我只是链接到正确的主题,而不是重复文本。 - Piotr Zierhoffer
是的,也许在这里使用“次要”一词并不合适。 - Piotr Zierhoffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接