Char *数组混乱

时间:2017-04-23 20:17:01

标签: c arrays string 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;
}

为什么只能打印names[i]而不是*names[i]?有人可以提供一个记忆图来澄清吗?

4 个答案:

答案 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)))相同