指针包含对象的地址(或是一个不指向任何对象的空指针)。指针有特定类型,表示它所指向的对象的类型。
数组是一系列有序相邻元素的集合;每个元素都是一个对象,所有元素都是同一类型。
字符串被定义为“由第一个空字符终止并包括在内的一系列连续字符”。C 没有字符串类型。字符串是一种数据布局,而不是数据类型。
数组和指针之间的关系可能会令人困惑。我知道的最好的解释是由comp.lang.c FAQ第6节提供的。最重要的是要记住:数组不是指针。
在 C 和 C++ 中,数组在某种程度上是“二等公民”。它们不能被赋值、作为函数参数传递或用于比较相等性。处理数组的代码通常使用指向数组各个元素的指针,并使用某些显式机制来指定数组的长度。
混淆的一个主要来源是事实:在大多数情况下,具有数组类型的表达式(例如数组对象的名称)会被隐式转换为指针值。转换后的指针指向数组的初始(零)元素。如果数组是以下情况之一,则不会发生这种转换:
为避免混淆,在您的示例中我会做出一些更改:
const char *ptr = "hello"
字符串字面值"hello"
在C中创建一个类型为char[6]
的匿名对象,或在C++中创建一个类型为const char[6]
的匿名对象,包含字符{ 'h', 'e', 'l', 'l', 'o', '\0' }
。
在这种情况下,该表达式的求值产生该数组初始字符的指针。这是一个指针值;没有隐式创建指针对象。该指针值用于初始化指针对象ptr
。
在任何时候都不会将数组“视为”指针。数组表达式被转换为指针类型。
另一个引起困惑的来源是看起来是数组类型的函数参数实际上是指针类型;类型在编译时调整。例如:
void func(char param[10]);
真正的意思是:
void func(char *param);
数字 10
会被静默地忽略。因此你可以写出如下的代码:
void print_string(char s[]) {
printf("The string is \"%s\"\n", s);
}
print_string("hello");
看起来像是对数组进行操作,但实际上字符串"hello"
被转换为指针,并将该指针传递给函数print_string
。
const
。 - Keith Thompson