在C语言中,这是什么意思?char *array[] = {"**", "**", "**"};

6
在我阅读的一些代码中,有一个初始化语句如下:
char *array[]= { "something1", "something2", "something3" };

这是什么意思?那个指针实际指向什么? 它在内存中如何分配,我如何访问数组中的每个元素和每个字符?

--- 编辑 --- 请问在这个例子中 char array[3]; 和 char *array[3]; 有什么区别? --- 编辑 ---


2
将其视为字符的二维数组,或者更好地说,是字符串的数组。 - dchhetri
+1 谁脑抽给这个问题点了踩?这是一个合理的问题,有明确的答案。 - Chazt3n
@user814628,这是一维数组,不是二维数组。尝试使用 printf("%d\n", sizeof(array[0]));。它将打印出指针的大小——4。可以将其想象成:AddressType array[] = { 0xXXXXXXXX, 0xXXXXXXXX, 0xXXXXXXXX }; - user1129665
@Sp。这取决于您的解释方式,我知道它是char *的数组,但为了更容易理解,OP可以将其视为2D数组,以便在他给出的示例中,array [0] [0] == 's' 成立。因此,尽管技术上它可能不是2D数组,但它几乎可以像一个模拟一样。 - dchhetri
5个回答

8

这是什么意思?

它正在初始化一个字符串数组(char *),其中包含三个值(三个指向以 null 结尾的字符串的指针)。

那指针指向什么?

它应该指向 char* 数组中的第一个元素。

这在内存中是如何分配的?

它将分配足够的内存来存储三个字符串和以 null 结尾的字符,以及指向这些字符串的三个指针:

array --> pointer to three sequential memory addresses

array[0] --> something1{\0}
array[1] --> something2{\0}
array[2] --> something3{\0}

请注意,这些字符串可能不一定在顺序内存中。如果您指的是“元素”即字符串,则可以通过循环指针来访问每个元素。
for(int i=0; i<3; i++)
{
    char* element = array[i];
}

以及数组中每个元素的字符

你可以使用数组语法(element[i])访问这些字符,但我建议使用C字符串函数来确保安全(这样就不必担心访问超出字符串范围的内存)。


非常感谢,那真的很有用 :) - Muhammad Barrima

6
这是一种在创建数组时同时初始化的方法。
这段代码:
char *array[]= { "a", "b", "c" };

这段代码的结果与此代码相同。
char *array[3];

array[0] = "a";
array[1] = "b";
array[2] = "c";

以下是更多信息的良好来源。

http://www.iu.hio.no/~mark/CTutorial/CTutorial.html#Strings

编辑:

char array[3]; 是一个包含 3 个 char 的数组。 char *array[3]; 是一个包含 3 个指向 char 的指针的数组。


1
好的,非常感谢。 但是 char arr[3]; 和 char *arr[3]; 有什么区别呢? - Muhammad Barrima
char array[3]; 是一个包含3个字符的数组。char *array[3]; 是一个包含3个指向字符的指针的数组。 - Nakul Tiruviluamala

4

char * 在C语言中表示字符串。

array 是正在声明的变量名称。

[] 表示它是一个数组。

{ "something1", "something2", "something3" } 初始化了数组的内容。

访问元素的方法如下:

array[0] 给出第一个元素 - "something1"。

array[1] 给出第二个元素 - "something2"。

等等。

注意:

就像在评论中指出的那样,char * 技术上不是一个字符串。

它是指向 char 的指针。您可以通过以下方式可视化内存中的字符串:

<-------------------------->
..134|135|136|137|138|139|..
<-------------------------->
  'H'|'e'|'l'|'l'|'o'|'\0'
<-------------------------->

这块内存(位置134-139)保存了字符字符串。

例如:

array[0]实际上返回的是指向“something1”中第一个字符的指针。

您可以利用字符在内存中是顺序排列的事实,以各种方式访问字符串的其余部分:

/* ch points to the 's' */
char* ch = array[0];

/* ch2 points to the 'e' */
char* ch2 = ch + 3;

/* ch3 == 'e' */
char ch3 = *ch2;

/* ch4 == 'e' */
char ch4 = *(ch + 3);

/* ch5 == 'e' */
char ch5 = ch[3];

char * 是指向 char 的指针。一个字符串是它可以指向的内容,但不一定是它当前或将来指向的内容。 - Alexey Frunze
请再次解释一下 char a[3]; 和 char * a[3]; 之间的区别。 - Muhammad Barrima
char a[3]; 表示创建了一个由三个 char 组成的数组。char * a[3]; 表示创建了一个由三个 char* 组成的数组。char* 意味着“指向 char 的指针”。 - Bertie Wheen

3
这定义了一个字符指针数组(也称为“c字符串”)。
要访问内容,可以执行以下操作:
for (int i=0; i<sizeof(array)/sizeof(char*); i++) {
    printf("%s", array[i]);
}

@AlexeyFrunze 对不起,我忘记了除以 sizeof(char*) - bikeshedder
使用 sizeof(array)/sizeof(char*) 一开始可能看起来很奇怪,但对于 C 数组来说真的非常好用,因为你不需要硬编码它的长度。由于 sizeof 在编译时确定,因此在这里使用常量和使用它一样快。 - bikeshedder

1
它将array声明为一个包含3个指向char的指针数组,并将其3个元素初始化为指向各自字符串的指针。该数组本身(3个指针)和字符串的内存都被分配了。字符串的内存是静态分配的。如果声明在所有函数之外,则数组的内存是静态分配的;如果声明在函数内部,则数组的内存通常是动态分配的(在CPU的执行堆栈上)。

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