C中访问指针数组值的两种方法

2 ways of accessing value of an array of pointers in C

第一块

#include <stdio.h>

const int MAX = 3;

int main() {

    int  var[] = { 10, 100, 200 };
    int i, *ptr[MAX];

    for (i = 0; i < MAX; i++) {
        ptr[i] = &var[i]; /* assign the address of integer. */
    }

    for (i = 0; i < MAX; i++) {
        printf("Value of var[%d] = %d\n", i, *ptr[i]);
    }

    return 0;
}

很容易理解,因为 ptr 是一个 int 指针数组。因此,当您需要访问第 i 个元素时,您需要将其值取消引用为 *ptr[i].

现在第二个块,还是一样的,只是现在它指向了一个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;
}

这次我们需要访问它的元素时,为什么不先加一个*呢?

我试图形成一个正确的语句来打印这个值,似乎如果你取消引用,它将是一个字符。为什么?

printf("%c", *names[1]) // Z

我知道C里面没有字符串,是char数组。我知道指针,但仍然不了解这里的语法。

对于带有 %s 格式说明符的 printf(),引用 C11,章节 §7.21.6.1

s
If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type. [...]

在你的情况下,

 printf("Value of names[%d] = %s\n", i, names[i] );

names[i] 指针,按%s的要求。这就是为什么您不取消引用指针的原因。

FWIW,

  • %c 需要一个 int 类型的参数(转换为 unsigned char,), 所以你需要取消引用指针来获取值。
  • %d 还需要一个 int 参数,因此您必须继续并取消引用指针,如问题中所述。

%d 转换说明符期望其相应参数的类型为 intptr[i] 的类型为 int *,因此需要取消引用。

%s 转换说明符期望其相应参数的类型为 char *;也就是说,一个指向 char 指针 。所以 names[i] 已经是正确的类型。 %s 说明符告诉 printf 从给定位置开始打印字符的 序列 ,直到它看到字符串终止符。

如果要打印 char:

的每个数组的第一个字符,您将在第二个示例中使用相同的语法
    printf("Value of names[%d] = %c\n", i, *names[i]);

但是因为你想打印 C 字符串,所以你传递 names 数组元素的值,它们是正确的类型,char *

printf() 有自己的处理格式类型说明符的方法。对于字符串,即字符数组,它需要 %s 说明符和类型 char * 的指针作为相应的参数。当 printf() 接收到这个指针时,它谨慎地取消引用它以打印 char 类型的字符。所以,这就是为什么在要打印字符串时传递指针而不取消引用的原因。