考虑以下两行代码:
const char *ptr = "Hello";
char arr[] = "Hello";
对于指针定义,"Hello"
字符串文字本质上是不可变,但ptr
变量本身可以更改并保存不同的地址。
对于数组定义,"Hello"
字符串文字被复制到数组的位置,但arr
不能指向不同的地点;但是,数组保存的字符串是可变的,因此可以更改。
现在考虑以下两行代码:
const char * const ptr = "Hello";
const char arr[] = "Hello";
这里,由于const char
限定符,两个字符串都是不可变的 - 更有趣的是:将ptr
定义为常量指针,不能指向不同的地址。
这两行代码会导致相同的行为吗?如果最终效果相同,那么实现中是否存在理论差异 - 例如,指针方法是否为匿名数组分配内存以保存除指针本身之外的字符串,而数组方法仅为内存分配内存阵列
答案 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。
这两行代码会导致相同的行为吗?
不,出于同样的原因,它们的类型完全不同。
指针方法是否为匿名数组分配内存以保存除指针本身之外的字符串,而数组方法只为数组分配内存?
是的,如果使用相同的字符串文字,则可以在另一个地方再次使用“匿名”创建的数组(但在一般情况下,您无法知道编译器实际执行的操作):
如果这些数组的元素具有适当的值,则未指定这些数组是否是不同的。
同样,第二行只是初始化数组的同步糖。