我知道在C语言中,数组只是按顺序存储的数据的指针。但是,在使用[]和*符号时,有什么不同之处?我的意思是在所有可能的使用上下文中。
例如:
char c[] = "test";
如果您在函数体中提供此指令,则会在堆栈上分配该字符串。
char* c = "test";
将指向一个数据(只读)段。
你能列出这两种表示法在所有使用情况下的区别,以形成清晰的概览吗?
char s[] = "abc", t[3] = "abc";
char s[] = { 'a', 'b', 'c', '\0' }, t[] = { 'a', 'b', 'c' };
是相同的。数组的内容是可修改的。另一方面,声明
const char *p = "abc";
定义了类型为指向常量char
的指针的p,并将其初始化为指向一个类型为常量字符数组(在C++中)的对象,该数组长度为4,其元素用字符字符串字面值进行初始化。如果尝试使用p
修改数组内容,则行为未定义。
根据6.3.2.1 数组下标,解引用和数组下标是相同的:
下标运算符
[]
的定义是E1[E2]
等同于(*((E1)+(E2)))
。
数组和指针的区别在于:
关于这个主题,更多有用的信息可以在http://www.cplusplus.com/forum/articles/9/找到。
char [4]
。然而,试图修改它会导致未定义行为。可能需要指出这种差异。 - Daniel Fischerchar c[] = "test";
这将创建一个包含字符串“test”的数组,因此您可以修改/更改任何字符。c[2] = 'p';
但是,char * c = "test"
这是一个字符串字面量——它是一个const char类型。
因此,对这个字符串字面量进行任何修改都会导致段错误。所以
c[2] = 'p';
现在是非法的,并且会导致段错误。
char * c = "test"
这段 C 代码是不好的,会产生警告:deprecated conversion from string constant to 'char*' [-Wwrite-strings]。应该使用 const char*
。请改为:const char* c = "test"
。 - Sergey K.char []
表示“未知长度的char数组”,而char *
表示“指向char的指针”。正如您所观察到的,当类型为“未知长度的char数组”的变量定义被初始化为字符串文字时,类型将转换为“array[N] of char”,其中N是适当的大小。同样适用于从数组聚合进行初始化的情况:
int arr[] = { 0, 1, 2 };
arr 被转换为类型 "array[3] of int"。
在用户定义类型的定义中(如 struct
、class
或 union
),C++ 中禁止使用未知大小的数组类型,虽然在某些版本的 C 语言中,它们被允许作为结构体的最后一个成员,以便可以访问超出结构体末尾分配的内存;这种用法称为"灵活数组"。
递归类型构造是另一个区别;可以构造指向和数组类型的 char *
(例如,char **
、char (*)[10]
),但是对于未知大小的数组就不行了;不能写成 char []*
或 char [][10]
(尽管 char (*)[]
和 char [10][]
是可以的)。
最后,cv-qualifiying 的操作方式也不同;给定 typedef char *ptr_to_char
和 typedef char array_of_unknown_bound_of_char[]
,限定指针版本的行为与预期相同,而限定数组版本将使 cv-qualification 迁移到元素类型上:也就是说,const array_of_unknown_bound_of_char
等效于 const char []
,而不是虚构的 char (const) []
。这意味着在函数定义中,在构造原型之前将对参数执行数组指针衰减。
void foo (int const a[]) {
a = 0;
}
是合法的;没有办法使未知边界数组参数不可修改。
实际上,数组等同于常量指针。
此外,char c[]为数组分配内存,其基地址为c本身。没有单独的内存用于存储该地址。
写char *c会为字符串分配内存,其基地址存储在c中。同时,还使用单独的内存位置来存储c。
MyClass
和int
也不是等价的。 - tenfour
sizeof c
。顺便说一句,在阅读了你的整个问题后,我不认为我准备好列出所有的差异,因为它们基本上是不同的类型,就是这样。你可能需要阅读标准。 - Michael Krelin - hackerchar* c = "test";
这段代码是非标准的,正确的写法应该是const char* c = "test";
。请注意,翻译后的内容保持原意不变且易于理解,不包含任何额外的解释或信息。 - Sergey K.