我可以将指向 char 指针的指针直接分配给字符串文字吗?

Zeb*_*ish 4 c++ pointers string-literals

我想知道是否可以将指向 char 的指针直接分配给字符串文字,而无需先将字符串文字分配给左值指针。通常,如果参数采用指向某个对象的指针,则可以使用 & 传递对象的地址,并且字符串文字似乎是(或至少衰减为) char 指针,因为您可以将它们分配给 char 指针。这就是为什么我期望以下其中一项能够发挥作用:

const char ** ppchar = &"StringLiteral"; // This doesn't compile

const char ** ppchar = (const char **)&"StringLiteral"; // This compiles, but...

std::cout << *ppchar;   // Throws an exception
Run Code Online (Sandbox Code Playgroud)

我预计至少其中第二个可以工作,因为在我看来“StringLiteral”至少会衰减为指针,因此:

const char** ppchar = (const char**) &"StringLiteral";
Run Code Online (Sandbox Code Playgroud)

第一个指针将指向字符串文字的地址。如果首先将字符串文字分配给左值指针,则第一个指针将指向第二个指针,该指针本质上保存着其地址。对我来说似乎是一样的。

编辑:另外,我似乎可以这样做:

const char * _pptr = (const char*)&"StringLiteral";
std::cout << _pptr; // Prints "Hello"
Run Code Online (Sandbox Code Playgroud)

因此,似乎没有禁止直接分配给字符串文字的规则。

编辑:正如对许多人来说显而易见的那样,我的间接级别是错误的。来自莫斯科的弗拉德在他的回答中解释了这一点。在:

const char ** pptr = (const char**)&"StringLiteral";
Run Code Online (Sandbox Code Playgroud)

编译器期望 pptr 指向存储字符地址的内容,而我已将其分配给“StringLiteral”本身的地址,这意味着当我 cout 时,它会取消引用第一个指针以查找哪个地址找到该字符。问题是它直接指向“StringLiteral”的地址,这意味着它使用“StringLiteral”的第一个字母的值作为要查找字符的地址,基本上它会使用“S”作为地址要去。讨厌这么厚。

Vla*_*cow 5

这个表情

&"StringLiteral"
Run Code Online (Sandbox Code Playgroud)

const char( * )[14]在 C++ 和C 中具有类型char ( * )[14],因为字符串文字分别具有类型const char[14]char[14]

因此,您可能不会将这样的指针分配给该类型的对象const char **,或者char **因为指针不兼容。

如果您尝试使用此声明中的强制转换

const char** ppchar = (const char**) &"StringLiteral";
Run Code Online (Sandbox Code Playgroud)

然而,像这样取消引用此指针*ppchar是没有意义的,因为char * 您将获得与字符串文字的第一个字符的值相对应的值,而不是预期的类型对象,而不是地址值。

例如,您可以首先按以下方式将字符串文字转换为类型const char *(或C 语言)char *

StringLiteral + 0
Run Code Online (Sandbox Code Playgroud)

因为在这样的表达式中,字符串文字被转换为指向其第一个字符的指针。但是,您不能将一元运算符应用于&此表达式,例如

&( StringLiteral + 0 )
Run Code Online (Sandbox Code Playgroud)

获取该类型的对象,const char **因为您可能无法将运算符应用于rvalue.

所以你可以做的是以下

const char *pchar = "StringLiteral";
const char **ppchar = &pchar;
Run Code Online (Sandbox Code Playgroud)