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

Can I assign a pointer to char pointer directly to a string literal?

本文关键字:指针 分配 字符串 文本 字符 我可以      更新时间:2023-10-16

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

const char ** ppchar = &"StringLiteral"; // This doesn't compile
const char ** ppchar = (const char **)&"StringLiteral"; // This compiles, but...
std::cout << *ppchar;   // Throws an exception

我希望至少第二个可以工作,因为在我看来,"StringLiteral"至少衰减到一个指针,所以:

const char** ppchar = (const char**) &"StringLiteral";

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

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

const char * _pptr = (const char*)&"StringLiteral";
std::cout << _pptr; // Prints "Hello"

因此,它似乎不是反对直接分配给字符串文字的规则。

编辑:正如许多人所明显的那样,我的间接水平是错误的。莫斯科的弗拉德在他的回答中对此进行了解释。在:

const char ** pptr = (const char**)&"StringLiteral";

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

此表达式

&"StringLiteral"

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

。因此,您不能将此类指针分配给类型为const char **char **的对象,因为这些指针不兼容。

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

const char** ppchar = (const char**) &"StringLiteral";

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

例如,您可以首先通过以下方式将字符串文本转换为const char *类型(或 C 中的char *)

StringLiteral + 0

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

&( StringLiteral + 0 )

获取类型为const char **的对象,因为您不能将运算符应用于rvalue

所以你可以做的是以下几点

const char *pchar = "StringLiteral";
const char **ppchar = &pchar;

除了来自莫斯科的@Vlad很好的答案。

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

几乎。 在 C 语言中,代码可以使用复合文字来形成一个用字符串文字初始化的const char *,然后获取该指针的地址以分配给ppchar

const char **ppchar = &((const char *){"StringLiteral"});
puts(*ppchar);