将字符串分配给指针数组

Assign string to the pointer array

我可以知道为什么当我声明一个指针数组时像

char *suits[]={"abc","cab","bca"}

即使我将字符串而不是地址分配给指针也没有错误? 因为据我了解,指针只能由地址(&)或另一个指针(*)赋值。更令人费解的部分是当我打印出指针数组

cout<<suits[1]; 

我得到了字符串 "cab",而不是地址,即使我不使用取消引用运算符。当我使用取消引用运算符时

cout<<*suits[1];

我只得到了'c'。

总结起来问题是1)为什么我可以将字符串分配给char类型指针而不是地址或指针,以及2)为什么当我打印出char类型指针时,而不是给我地址,它显示了字符串。 3)最后,为什么当我取消引用 char 类型指针时,它会给我字符串中第一个 char 的值。

真的很想知道为什么 char 类型指针与其他类型的指针如此不同?

根据 C++ 标准

4.2 Array-to-pointer conversion [conv.array]

1 An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

在此声明中

char *suits[]={"abc","cab","bca"}

所有字符串文字都具有类型 const char[4],并且基于这些字符串文字的初始化表达式被转换为指向字符串文字第一个元素的指针。在 C++ 中,它们的类型为 const char *。因此,将数组声明为

会更正确
const char *suits[]={"abc","cab","bca"}

对于指向 char operator << 的指针,显式重载并执行指针指向的输出字符,直到遇到零终止字符。也就是说,如果您在运算符 << 中使用指向 char 的指针,那么您将输出该指针指向的字符串。

至于这条记录

cout<<*套装[1];

那么根据suits作为指针数组的定义,suits[1]是数组的第二个元素,它是指向字符串文字第一个元素的指针"cab"。因此取消引用指针,您将获得字符串文字的第一个元素,即字符 'c'.

您似乎对 C 中的字符串是什么感到困惑。

字符串是一个字符数组,其中最后一个字符是 '[=14=]'.

如果你在源代码中的任何地方写 "abc",那么编译器会为你创建一个数组,就好像你声明了一个全局变量一样:

char abc_string[4] = {'a', 'b', 'c', '[=10=]'};

(虽然实际上不会叫abc_string)。

"cab" 和 "bca" 相同。

那么,你的定义等同于:

char *suits[]={abc_string, cab_string, bca_string};
// where abc_string, cab_string and bca_string are the arrays created by the compiler.

现在,当您在 C 中使用数组名称时,大多数时候它会自动转换("decays")为指向其第一个元素的指针。所以在上面的定义中,abc_string实际上意味着&abc_string[0]——指向abc_string的第一个元素的指针。

char *suits[] = {&abc_string[0], &cab_string[0], &bca_string[0]};

现在应该清楚 suits 的元素指向什么了——它们指向每个字符串的第一个字符。

这不是数组特有的——如果你写:

char *thing = "hello world";

然后编译器生成一个包含 {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', '[=21=]'} 的数组,并设置 thing 指向它的第一个元素。