简体   繁体   English

char *字符串文字如何有效?

[英]how is char * to string literal valid?

So from my understanding pointer variables point to an address. 因此,根据我的理解,指针变量指向一个地址。 So, how is the following code valid in C++? 那么,以下代码在C ++中如何有效?

char* b= "abcd"; //valid
int *c= 1; //invalid

The first line 第一行

 char* b= "abcd";

is valid in C, because "string literals", while used as initializer, boils down to the address of the first element in the literal, which is a pointer (to char ). 在C中有效,因为“字符串文字”在用作初始化程序时会归结为文字中第一个元素的地址,该元素是指针(指向char )。

Related, C11 , chapter §6.4.5, string literals, 相关内容, C11 ,第§6.4.5章,字符串文字,

[...] The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. [...]然后,使用多字节字符序列来初始化一个足以容纳序列的静态存储持续时间和长度数组 For character string literals, the array elements have type char , and are initialized with the individual bytes of the multibyte character sequence. 对于字符串文字,数组元素的类型为char ,并使用多字节字符序列的各个字节进行初始化。 [...] [...]

and then, chapter §6.3.2.1 ( emphasis mine ) 然后是第6.3.2.1节( 重点是我的

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array , an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. 除非它是sizeof运算符, _Alignof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字 ,否则类型为“ array of type”的表达式转换为带有键入“指向类型的指针” ,它指向数组对象的初始元素,而不是左值。

However, as mentioned in comments, in C++11 onwards, this is not valid anymore as string literals are of type const char[] there and in your case, LHS lacks the const specifier. 但是,正如注释中提到的,从C++11开始,这不再有效,因为字符串文字在那里的类型为const char[] ,在您的情况下,LHS缺少const说明符。

OTOH, 太太

 int *c= 1;

is invalid (illegal) because, 1 is an integer constant, which is not the same type as int * . 无效(非法),因为1是整数常量,与int *类型不同。

In C and very old versions of C++, a string literal "abcd" is of type char[] , a character array. 在C和非常老的C ++版本中,字符串文字"abcd"的类型为char[] (字符数组)。 Such an array can naturally get pointed at by a char* , but not by a int* since that's not a compatible type. 这样的数组自然可以由char*指向,但不能由int*指向,因为这不是兼容类型。

However, C and C++ are different, often incompatible programming languages. 但是,C和C ++是不同的,通常是不兼容的编程语言。 They dropped compatibility with each other some 20 years ago. 大约20年前,他们彼此之间失去了兼容性。

In standard C++, a string literal is of type const char[] and therefore none of your posted code is valid in C++. 在标准C ++中,字符串文字的类型为const char[] ,因此,您发布的任何代码在C ++中均无效。 This won't compile: 这不会编译:

char* b = "abcd";        //invalid, discards const qualifier

This will: 这将:

const char* c = "abcd";  // valid

"abcd" is actually a const char[5] type, and the language permits this to be assigned to a const char* (and, regrettably, a char* although C++11 onwards disallows it.). "abcd"实际上是const char[5]类型,并且该语言允许将其分配给const char* (遗憾的是,尽管C ++ 11开始不允许使用char* )。

int *c = 1; is not allowed by the C++ or C standards since you can't assign an int to an int* pointer (with the exception of 0 , and in that case your intent will be expressed clearer by assigning nullptr instead). C ++或C标准不允许这样做,因为您不能将int分配给int*指针( 0除外,在这种情况下,通过分配nullptr可以更清楚地表达您的意图)。

"abcd" is the address that contains the sequence of five bytes 97 98 99 100 0 -- you cannot see what the address is in the source code, but the compiler will still assign it an address. "abcd"是包含五个字节的序列的地址97 98 99 100 0您无法在源代码中看到该地址,但是编译器仍将为其分配一个地址。

1 is also an address near the bottom of your [virtual] memory. 1也是[虚拟]内存底部附近的地址。 This may not seem to be useful to you, but it is useful to other people , so even though the "standard" might not want to permit this, every compiler you are ever likely to run into will support this. 这可能对您似乎没有用,但对其他人有用 ,因此,即使“标准”可能不想允许这样做,您可能会遇到的每个编译器都将支持此功能。

While all other answers give the correct answer of why you code doesn't work, using a compound literal to initialize c , is one way you can make your code work, eg 尽管所有其他答案给出了为什么您的代码无法正常工作的正确答案,但是使用复合文字初始化c却是使代码正常工作的一种方式,例如

int *c= (int[]){ 1 };
printf ("int pointer c : %d\n", *c);

Note, there are differences between C and C++ in the use of compound literals, they are only available in C. 请注意,C和C ++在复合文字的使用方面有所不同,它们仅在C中可用。

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

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