#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;
}
为什么只能打印names[i]
而不是*names[i]
?有人可以提供一个记忆图来澄清吗?
答案 0 :(得分:2)
格式说明符%s
需要类型为(char*)
的参数,即指向字符数组的指针。
在char* names[]
中,每个元素都是指向字符数组的指针;初始化后,names[0]
保存一个指向字符串文字"Zara Ali"
开头的内存地址。因此,将这样的指针作为参数传递给printf("%s", ...)
。
但是,如果您编写*names[0]
,那么您实际上取消引用此指针,产生char
- 值,在这种情况下为'Z'
。这就像您编写printf("%s", 'Z')
一样,预期数据类型char*
和实际数据类型char
不匹配并产生编译器警告,并且 - 当忽略它们时 - 未定义的行为。
答案 1 :(得分:0)
我不认为记忆图是必要的。
c中带*的任何内容都是内存中的指针。
所以,
int *a = 3;
a = 3;
*a = memory address
printf("result = %d, result 2 =%d\n", a, *a);
输出:
result = 3, result 2 = 9023923 (this is a random memory address)
你必须记住这个!
答案 2 :(得分:0)
char是一个8位字符,我们通过使用第一个char的地址使用一个未知长度的char数组来表示c中的字符串,所以对于我们使用的单个字符串
char * name
含义 name 包含第一个字符的内存地址(指针),我们可以通过增加内存地址 name + 1 来获取第二个字符。 如果我们想要一个字符串数组,我们实际上做的是拥有多个字符串的内存地址(指针)数组,那么
char * names[] = ...
是一个指向字符串第一个字符的指针数组,你必须指定c数组中的元素数,但因为你已经为它提供了值,编译器可以为你推断出元素的数量。
您指向 names 中每个元素的每个字符串都可以位于内存中的任何位置,它只是一个内存地址数组, names [0] 可以等于10000和名称[1] 可以等于10,这意味着字符串0从地址10000开始,字符串1从地址10开始,但由于你声明它的方式,编译器很可能将它们放入内存按顺序依次排列,但稍后您可以为任何一个值分配不同的内存地址。
names[2] = "New Values";
并且 names [2] 的值将成为内存中的一个不同位置,其中&#34; New Values&#34;存在且原始字符串&#34; Nuha Ali&#34;仍将位于内存中未触及的原始位置。
如果你想要,你可以创建一个像这样的字符数组
char names[] = "Zara Ali\0Hina Ali\0...
然后 names 将被创建足够长的时间以包含整个字符串,并且字符串将被复制到数组中,而不是复制到数组中的每个字符串的第一个char内存地址。 names 然后只指向一个字符数组,并且名称[1]将返回第二个字符,并且您将无法确定字符串结束的位置,任何str函数将采用字符串终止于第一个&#39; \ 0&#39;。
(注意:你的编译器可能不会让你真正放置一个字符串终结符&#39; \ 0&#39; mid string,我还没有尝试过,但我认为如果不是,那应该是合法的,但是你可以了解内存的布局方式。)
答案 3 :(得分:-1)
这是因为*
中包含[]
。
看看Array subscripting:
下标运算符[]的定义是E1 [E2]与(*((E1)+(E2)))相同