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

时间:2013-04-29 21:16:31

标签: c arrays pointers const c99

考虑以下两行代码:

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

对于指针定义,"Hello"字符串文字本质上是不可变,但ptr变量本身可以更改并保存不同的地址。

对于数组定义,"Hello"字符串文字被复制到数组的位置,但arr 不能指向不同的地点;但是,数组保存的字符串是可变的,因此可以更改。

现在考虑以下两行代码:

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

这里,由于const char限定符,两个字符串都是不可变的 - 更有趣的是:将ptr定义为常量指针,不能指向不同的地址。

这两行代码会导致相同的行为吗?如果最终效果相同,那么实现中是否存在理论差异 - 例如,指针方法是否为匿名数组分配内存以保存除指针本身之外的字符串,而数组方法仅为内存分配内存阵列

5 个答案:

答案 0 :(得分:4)

这里有一些差异。

首先,这可能适用于某些实现,因为指针可以指向同一个内存:

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

ptr1 == ptr2;

但是使用数组表单不可能是真的。

无论如何,真正的区别在于它们的类型不同。特别是,char[]版本在数组类型中保留其大小。因此sizeof(arr)为您提供数组的大小,而不是指针,您还可以创建指向arr的数组的指针。

答案 1 :(得分:3)

两者之间存在差异:他们的地址。具有相同内容的所有字符串文字可以(但不一定)指向相同的地址。如果数组定义在函数作用域中,则定义一个新对象,该对象不同于字符串文字,也不同于具有相同内容的任何其他此类对象。因此地址必须不同。

如果您的函数是递归的,那么尤其如此。然后,函数的所有嵌套调用都将定义一个新变量,每个变量都有不同的地址。

答案 2 :(得分:3)

const char *ptr = "Hello";

这将ptr声明为const指向char,初始化为指向字符串文字“Hello”。指出 NOT 有一个const类型,尽管允许实现将它放在只读存储器中。

char arr[] = "Hello";

这将arr声明为char的数组[6],初始化为{'H', 'e', 'l', 'l', 'o', '\0'}

const char * const ptr = "Hello";

这将ptr声明为const指向const-char,初始化为指向字符串文字“Hello”。尽管此指针被声明为指向const内存,但字符串文字本身仍然没有const类型,尽管仍允许实现将其放在只读内存中。

const char arr[] = "Hello";

将arr声明为char的const数组[6],再次初始化为{'H', 'e', 'l', 'l', 'o', '\0'}

所有不同,但我看到其他人已经为你的问题提供了更好的答案。

答案 3 :(得分:2)

嗯,&ptr&arr之间存在至少一个语义差异,它将产生不同的类型 - 一个是指向指针的指针,另一个是指向数组的指针。在任何地方实际上重要当然取决于你如何使用它们。检查编译器的输出机器代码以获得特定结果。

答案 4 :(得分:1)

  

对于数组定义,"Hello"字符串文字被复制到数组的位置,但是arr不能指向不同的位置

字符串不会被复制到数组中,它不会被创建并存储在只读位置,如字符串文字(可以隐式转换为指针),但它只是

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

正如标准所说:

  

字符类型数组可以用字符串文字或UTF-8字符串文字初始化,可选择用大括号括起来。

数组没有“指向”,arrays are not pointers

  

这两行代码会导致相同的行为吗?

不,出于同样的原因,它们的类型完全不同。

  

指针方法是否为匿名数组分配内存以保存除指针本身之外的字符串,而数组方法只为数组分配内存?

是的,如果使用相同的字符串文字,则可以在另一个地方再次使用“匿名”创建的数组(但在一般情况下,您无法知道编译器实际执行的操作):

  

如果这些数组的元素具有适当的值,则未指定这些数组是否是不同的。

同样,第二行只是初始化数组的同步糖。