简体   繁体   English

char ** vs char * c []用于访问字符串数组

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

Why can't I point a char** to array of C strings?? 为什么我不能将char **指向C字符串数组?

int main(int argc, char *argv[]) {

    char* c1[] = {"Hey","Hello"};
    printf("%s",c1[1]);

} //works fine

vs VS

int main(int argc, char *argv[]) {

    char** c1 = {"Hey","Hello"};
    printf("%s",c1[1]);

} //error

I think the confusion here stems from the belief that {"Hey","Hello"} is an array. 我认为这里的混乱源于相信{"Hey","Hello"}是一个数组。 It's not. 不是。 It's not an object at all. 它根本不是一个对象。 It's just a special initializer syntax that can be used to initialize an array. 它只是一种特殊的初始化语法,可用于初始化数组。 You can't use it to initialise a char** because a char** is a pointer, not an array. 您不能使用它来初始化char**因为char**是指针而不是数组。 It doesn't automatically create an array object that you can convert to a pointer. 它不会自动创建可以转换为指针的数组对象。

Perhaps you were thinking of it like a [...] list in Python or a { ... } object in JavaScript. 也许你是一个喜欢思考的是[...]列表在Python或{ ... }在JavaScript对象。 It's not like those at all. 它根本不像那些。 Those expressions actually create objects of that type and can be used anywhere in an expression that can take those objects. 这些表达式实际上创建了该类型的对象,并且可以在可以接受这些对象的表达式中的任何位置使用。 The syntax we're using in C++ is just an initialization syntax. 我们在C ++中使用的语法只是一种初始化语法。

For example, you could do this: 例如,您可以这样做:

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

You, however, cannot do something silly like this: 但是,你不能做这样的傻事:

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

Here we have actually created the array object in which the pointers will be stored. 这里我们实际创建了存储指针的数组对象。 Only then can we convert that array to a const char** . 只有这样我们才能将该数组转换为const char**

改成

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

Why can't I point a char** to array of C strings? 为什么我不能将char**指向C字符串数组?

As you said, c1 is an array. 如你所说, c1是一个数组。 So you have to declare it as an array of pointers to char . 所以你必须将它声明为char的指针数组

Since "Hey" and "Hello" are string litterals , each c1[i] string is pointing to an anonymous string. 由于"Hey""Hello"字符串litterals ,因此每个c1[i]字符串都指向一个匿名字符串。 That's why you can use pointers to char instead of arrays of char . 这就是为什么你可以使用char而不是char数组的指针。

To make an array of pointers to char , however, you can't use a char ** . 但是,要创建指向char的指针数组,则不能使用char **

"char **c1", tells compiler that it is a pointer to a pointer for type char, is scalar type (one value). “char ** c1”告诉编译器它是一个指向char类型指针的指针,是标量类型(一个值)。

Initializing with a list of values only works for aggregate types. 使用值列表进行初始化仅适用于聚合类型。

int main(int argc, char *argv[]) {

    char** c1 = {"Hey","Hello"};
    printf("%s",c1[1]);

} //error

In the code above, you are trying to set a pointer to a pointer to a set of two strings. 在上面的代码中,您尝试设置指向指向一组两个字符串的指针。 Where is the storage for the two pointers that contain the address of "Hey" and "Hello" respectively? 哪两个指针的存储分别包含“Hey”和“Hello”的地址? Nowhere. 无处。

You could do: 你可以这样做:

 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;

(I've split it up into more individual variables than it actually needs, but I think it explains what is "wrong" with your code quite clearly). (我把它分成了比实际需要更多的单个变量,但我认为它很清楚地解释了代码的“错误”)。

Another example would be if we change the char * to int: 另一个例子是如果我们将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. 

It's the same thing, except with integers. 这是一回事,除了整数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM