访问字符串数组的char**vschar*c[]

char** vs char* c[] for accessing a string array

本文关键字:vschar char 字符串 数组 访问      更新时间:2023-10-16

为什么我不能将字符**指向C字符串数组??

int main(int argc, char *argv[]) {
    char* c1[] = {"Hey","Hello"};
    printf("%s",c1[1]);
} //works fine

int main(int argc, char *argv[]) {
    char** c1 = {"Hey","Hello"};
    printf("%s",c1[1]);
} //error

我认为这里的混淆源于认为{"Hey","Hello"}是一个数组。事实并非如此。它根本不是一个物体。这只是一种特殊的初始化器语法,可以用来初始化数组。不能用它初始化char**,因为char**是指针,而不是数组。它不会自动创建一个可以转换为指针的数组对象。

也许您认为它像Python中的[...]列表或JavaScript中的{ ... }对象。一点也不像。这些表达式实际上创建了该类型的对象,并且可以在可以接受这些对象的表达式中的任何位置使用。我们在C++中使用的语法只是一种初始化语法。

例如,可以执行以下操作:

const char* array[] = {"Hey","Hello"};
const char** p = array;

然而,你不能做这样愚蠢的事情:

std::cout << {"Hey", "Hello"}[1];

在这里,我们实际上已经创建了数组对象,指针将存储在该对象中。只有这样,我们才能将该数组转换为const char**

更改为

char** c1 = (char *[]){"Hey","Hello"};

为什么我不能将char**指向C字符串数组?

正如您所说,c1是一个数组。因此,您必须将其声明为指向char指针数组。

由于"Hey""Hello"字符串丢弃,因此每个c1[i]字符串都指向一个匿名字符串。这就是为什么可以使用指向char的指针而不是char的数组。

但是,要生成指向char的指针数组,就不能使用char **

int main(int argc, char *argv[]) {
    char** c1 = {"Hey","Hello"};
    printf("%s",c1[1]);
} //error

在上面的代码中,您试图将一个指针设置为指向一组两个字符串的指针。分别包含"嘿"answers"你好"地址的两个指针的存储在哪里?无处

你可以做:

 char *a = "Hey";
 char *b = "Hello";
 char *c[] = { a, b };     // This MAY not compile due to a and b not being compile time constants. 
 char **c1 = c;

(我已经将它分解为比实际需要的更多的单个变量,但我认为它非常清楚地解释了代码的"错误"(。

另一个例子是,如果我们将char *更改为int:

 const int a = 1;
 const int b = 2;
 int c[] = { a, b };
 int *c = { a, b };   // Doesn't work, there is nowhere to store a copy of a and b. 

这是一样的,除了整数。

"char**c1",告诉编译器它是指向类型为char的指针的指针,是标量类型(一个值(。

使用值列表进行初始化仅适用于聚合类型。