3

考虑以下两行代码:

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

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

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

现在考虑以下两行代码:

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

在这里,由于限定符,两个字符串都是不可变的——不过更有趣的是:定义为常量指针,它不能指向不同的地址。const charptr

这两行代码会导致相同的行为吗?如果最终效果相同,那么在实现上是否存在理论上的差异——例如,指针方法是否为匿名数组分配内存来保存指针本身之外的字符串,而数组方法只为一个大批?

4

5 回答 5

4

这里有一些不同之处。

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

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

ptr1 == ptr2;

但是使用数组形式就不可能了。

无论如何,真正的区别在于它们的类型不同。特别是,char[]版本在数组类型中保留其大小。所以sizeof(arr)给你数组的大小,而不是一个指针,你也可以创建指向数组的指针arr

于 2013-04-29T21:22:26.023 回答
3

两者之间有区别:他们的地址。具有相同内容的所有字符串文字可能(但不一定)指向相同的地址。数组定义(如果它在函数范围内)定义了一个新对象,该对象不同于字符串文字,也不同于具有相同内容的任何其他此类对象。因此地址必须不同。

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

于 2013-04-29T21:23:52.997 回答
3
const char *ptr = "Hello";

这将 ptr 声明为 const 指向字符的指针,初始化为指向字符串文字“Hello”。指向的内容没有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 array[6],再次初始化为{'H', 'e', 'l', 'l', 'o', '\0'}.

一切都不同,但我看到其他人已经为您的问题提供了更好的答案。

于 2013-04-29T21:24:59.773 回答
2

好吧,其中至少存在一种语义差异,&ptr并且&arr会产生不同的类型——一种是指向指针的指针,另一种是指向数组的指针。当然,这在任何地方是否真的重要取决于您如何使用它们。检查编译器的输出机器代码以获得特定结果。

于 2013-04-29T21:21:35.780 回答
1

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

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

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

正如标准所说:

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

并且数组不“指向”,数组不是指针

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

不,出于相同的原因,它们具有完全不同的类型。

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

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

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

同样,第二行只是用于初始化数组的语法糖。

于 2013-04-29T21:46:50.447 回答