简体   繁体   English

const char * const和const char []之间有区别吗?

[英]Is there a difference between const char * const and const char []?

Consider the two following lines of code: 考虑以下两行代码:

const char *ptr = "Hello";
char arr[] = "Hello";

For the pointer definition, the "Hello" string literal is essentially immutable , but the ptr variable itself can change and hold a different address. 对于指针定义, "Hello"字符串文字本质上是不可变的 ,但ptr变量本身可以更改并保存不同的地址。

For the array definition, the "Hello" string literal is copied to the location of the array, but arr cannot point to a different location; 对于数组定义, "Hello"字符串文字被复制到数组的位置,但是arr 不能指向不同的位置; however, the string held by the array is mutable and thus can be changed. 但是,数组保存的字符串是可变的,因此可以更改。

Now consider the following two lines of code: 现在考虑以下两行代码:

const char * const ptr = "Hello";
const char arr[] = "Hello";

Here, both strings are immutable as a result of the const char qualifier -- more interesting though: with ptr defined as a constant pointer, it cannot point to a different address. 这里,两个字符串作为const char限定符的结果是不可变的 - 虽然更有趣:将ptr定义为常量指针,但它不能指向不同的地址。

Would these two lines of code result in the same behavior? 这两行代码会导致相同的行为吗? If the end effect is the same, is there a theoretical difference in implementation -- for example, does the pointer method allocate memory for an anonymous array to hold the string in addition to the pointer itself, while the array method only allocates memory for an array? 如果最终效果相同,那么实现中是否存在理论差异 - 例如,指针方法是否为匿名数组分配内存以保存除指针本身之外的字符串,而数组方法仅为内存分配内存阵列?

Here's a few differences. 这里有一些差异。

First off, this may hold true on certain implementations as the pointers can point to the same memory: 首先,这可能适用于某些实现,因为指针可以指向同一个内存:

const char * const ptr1 = "Hello";
const char * const ptr2 = "Hello";

ptr1 == ptr2;

But it cannot be true using the array form. 但是使用数组形式并不是真的。

Anyway, the real difference is that their types are different. 无论如何,真正的区别在于它们的类型不同。 In particular, the char[] version retains its size in the array type. 特别是, char[]版本在数组类型中保留其大小。 So sizeof(arr) gives you the size of the array, rather than a pointer, and you can also create pointers to arrays to arr . 因此sizeof(arr)为您提供数组的大小,而不是指针,您还可以创建指向arr数组的指针。

There is a difference between the two: their address. 两者之间存在差异:他们的地址。 All string literals with the same contents may (but must not necessarily) point to the same adress. 具有相同内容的所有字符串文字可以(但不一定)指向相同的地址。 The array definition, if it is in function scope defines a new object, different from the string literal and also different from any other such object with the same contents. 如果数组定义在函数作用域中,则定义一个新对象,该对象不同于字符串文字,也不同于具有相同内容的任何其他此类对象。 Thus the addresses must be different. 因此地址必须不同。

This will in particular be the case if your function is recursive. 如果您的函数是递归的,那么尤其如此。 Then all nested invocations of your function would define a new variable, each with a different adress. 然后,函数的所有嵌套调用都将定义一个新变量,每个变量都有不同的地址。

const char *ptr = "Hello";

This declares ptr as a const pointer-to-char, initialized to point at the string literal "Hello". 这将ptr声明为const指向char,初始化为指向字符串文字“Hello”。 What is pointed at does NOT have a const type, although the implementation is permitted to place it in read-only memory. 指向的是没有 const类型,尽管允许实现将其放在只读存储器中。

char arr[] = "Hello";

This declares arr as array[6] of char, initialized to {'H', 'e', 'l', 'l', 'o', '\\0'} . 这将arr声明为char的数组[6],初始化为{'H', 'e', 'l', 'l', 'o', '\\0'}

const char * const ptr = "Hello";

This declares ptr as a const pointer-to-const-char, initialized to point at the string literal "Hello". 这将ptr声明为const指向const-char,初始化为指向字符串文字“Hello”。 Although this pointer is declared as pointing at const memory, the string literal itself still does not have const type, although the implementation is still permitted to place it in read-only memory. 尽管此指针声明为指向const内存,但字符串文字本身仍然没有const类型,尽管仍允许实现将其放在只读内存中。

const char arr[] = "Hello";

This declares arr as a const array[6] of char, again initialized to {'H', 'e', 'l', 'l', 'o', '\\0'} . 这将arr声明为char的const数组[6],再次初始化为{'H', 'e', 'l', 'l', 'o', '\\0'}

All different, but I see that others have already provided better answers to your question. 各种不同,但我看到其他人已经为你的问题提供了更好的答案。

Well, there is at least one semantic difference in that &ptr and &arr will yield different types - one a pointer-to-pointer and the other pointer-to-array. 好吧, &ptr&arr至少有一个语义差异会产生不同的类型 - 一个是指向指针的指针,另一个是指向数组的指针。 Whether that actually matters anywhere will of course depend on how you use them. 这实际上是否重要当然取决于你如何使用它们。 Check the output machine code from your compiler for specific results. 检查编译器的输出机器代码以获取特定结果。

For the array definition, the "Hello" string literal is copied to the location of the array, but arr cannot point to a different location 对于数组定义, "Hello"字符串文字被复制到数组的位置,但是arr不能指向其他位置

The string is not copied into the array, it's not created and stored in a read-only location like string literals (that can be implicitly converted to pointers), but it's just a shorthand for 字符串不会被复制到数组中,它不会被创建并存储在只读位置,如字符串文字(可以隐式转换为指针),但它只是一个简写

char arr[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

As the standard says: 正如标准所说:

An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. 字符类型数组可以由字符串文字或UTF-8字符串文字初始化,可选地用大括号括起来。

And arrays don't "point", arrays are not pointers . 并且数组不“指向”, 数组不是指针

Would these two lines of code result in the same behavior? 这两行代码会导致相同的行为吗?

No, the have completely different types, for the same reason. 不,出于同样的原因,它们的类型完全不同。

does the pointer method allocate memory for an anonymous array to hold the string in addition to the pointer itself, while the array method only allocates memory for an array? 指针方法是否为匿名数组分配内存以保存除指针本身之外的字符串,而数组方法只为数组分配内存?

Yes, and the "anonymous" created array could be used again in another place if the same string literal is used (but in the general case you can't know what the compiler actually does): 是的,如果使用相同的字符串文字,则可以在另一个地方再次使用“匿名”创建的数组(但在一般情况下,您无法知道编译器实际执行的操作):

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. 如果这些数组的元素具有适当的值,则这些数组是否不同是未指定的。

Again, the second line is just synctactic sugar to initialize the array. 同样,第二行只是初始化数组的同步糖。

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

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