我正在研究 c 中指向数组的指针,一切都很好,直到我遇到这段代码 *names 是指针数组,它应该存储那些指向 char 的地址,但它存储字符串,有人可以向我解释一下吗
#include <stdio.h>
const int MAX = 4;
int main () {
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
int i = 0;
for ( i = 0; i < MAX; i++) {
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
output
Value of names[0] = Zara Ali
Value of names[1] = Hina Ali
Value of names[2] = Nuha Ali
Value of names[3] = Sara Ali
在此声明中
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
具有数组类型
char[9]
和用作初始值设定项的静态存储持续时间的字符串文字被隐式转换为指向其第一个元素的char *
类型的指针。
你甚至可以等价地写
char *names[] = {
&"Zara Ali"[0],
&"Hina Ali"[0],
&"Nuha Ali"[0],
&"Sara Ali"[0]
};
注意,例如字符串文字
"Zara Ali"
在内存中存储为数组,如
{ 'Z', 'a', 'r', 'a', ' ', 'A', 'l', 'i', '\0' }
字符串文字的类型是char[N].
但是除非数组与 & 或 sizeof 运算符一起使用,否则它会转换为指向其元素的指针。
所以,如果你写
char *str = "Hello, World!"
实际类型的“Hello, World!”是 char[14],它存储在内存中的某个地方。它正在存储指针....字符串(字符串文字)位于名称之外的一些内存中。编译器负责这个。
你可以想到这样的代码:
// Strings as global variables
char str1[] = "Zara Ali";
char str2[] = "Hina Ali";
char str3[] = "Nuha Ali";
char str4[] = "Sara Ali";
int main () {
char *names[] = {
&str1[0], // Storing pointers
&str2[1],
&str3[2],
&str4[3]
};
这里的 4 个字符串显然存储在除
names
之外的其他内存中,并且 names
保存指向字符串第一个字符的指针。
当你做
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
这有点相同。编译器只是在幕后处理它。
顺便说一句:
因为你有一个指针数组,你可以这样做:
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
size_t MAX = sizeof names / sizeof names[0];
而不是硬编码
const int MAX = 4;
。然后MAX
会在数组中加入新的字符串时自动得到正确的值
这个:
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
声明 names 为指向
char
的指针数组,并使用四个字符串的第一个元素的地址初始化其元素。
用双引号括起来的字符串是一种写指向无名数组的指针的简写方式,该数组已用引号之间的字符和标记字符串结尾的额外空字节进行了初始化。
names 是指针数组,它应该存储那些指向 char 的地址,但它存储字符串。
是的,的确如此。它是一个指向
char
s的指针数组,而不是指向字符串的指针,它的元素指向字符串的第一个元素,即char
s。
在内存中,数组的第一个元素看起来像这样:
+-------+
names[0]: | * |
+---|---+
|
V
+---+---+---+---+---+----+---+---+---+
|'Z'|'a'|'r'|'a'|' '|'A'|'l'|'i'|'\0'|
+---+---+---+---+---+----+---+--+----+
请注意,此内存是不可变的,即您可以将指针更改为指向其他地方,但您不能更改指向数据的指针。否则,您的代码将调用未定义的行为。出于这个原因,最好使用
const
限定符声明指向字符串文字的指针:
const char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};