将指针数组传递给接受二维数组的函数

Passing array of pointers to a function accepting 2d array

我在 C 中有以下代码

#include <stdio.h>
 
char *gstr[] = { "Hello", "World" };
 
void func(char str[][8]) {
    printf("%p\n", (void *)str);
    printf("%p\n", (void *)(str + 1));
    printf("%s\n", *(str + 1));
}
 
int main(void) {
    printf("%p\n", (void *)gstr);
    printf("%p\n", (void *)(gstr + 1));
    printf("%s\n", *(gstr + 1));
 
    printf("Calling Function\n");
 
    func(gstr);
    return 0;
}

下面是输出

0x556f11ddd010
0x556f11ddd018
World
Calling Function
0x556f11ddd010
0x556f11ddd018
$��oU

我无法理解为什么函数 func 中的 printf("%s\n", *(str+1)); 不打印字符串 world.

char *gstr[] = {"Hello", "World"};gstr 声明为指向 char.

的指针数组

char str[][8] 本身将 str 声明为一个由八个 char 组成的数组。但是,作为函数参数,它会自动从数组调整为指针:它声明 str 为指向八个数组的指针 char.

指向数组的指针不同于指针数组。

您的编译器应该警告您 func(gstr)gstr 的类型与 void func(char str[][8]) 中的参数类型不兼容。注意来自编译器的消息。

要将 gstr 正确传递给 func,请将 func 的声明更改为 func(char *str[]) 或等效的 func(char **str).

func(gstr)gstr 的第一个元素的地址传递给函数。由于 gstr 是一个指针数组,它的第一个元素的地址是指针的地址(即指向 "Hello" 的第一个字符的指针)。

func 中,该函数需要一个指向八 char 数组的指针。如果它使用为其指定的地址,则它指向一个指针而不是八个 char 的数组。将其传递给 printf 尝试打印表示指针的字节,就好像它们是字符串一样。

您可以编译下面的代码以查看输出。

#include <stdio.h>
 
char *gstr[] = {"Hello", "World"};
 
void func(char str[][8]) {
    printf("%p\n", (void*) str);
    printf("%p\n", (void*) *str);
    printf("%p\n", (void*) (str+1));
    printf("%p\n", (void*) *(str+1));
    printf("%s\n", *(str+1));
}
 
int main(void) {
    printf("%p\n", (void *) gstr);
    printf("%p\n", (void *) *gstr);
    printf("%p\n", (void*) (gstr+1));
    printf("%p\n", (void*) *(gstr+1));
    printf("%s\n", *(gstr+1));
 
    printf("Calling Function\n");
 
    func(gstr);
    return 0;
}
0x100402010
0x100403000
0x100402018
0x100403006
World
Calling Function
0x100402010
0x100402010
0x100402018
0x100402018
0@

编译器知道 gstr 是一个指针数组,所以在函数 main 中,gstr + 1 处的对象将被解释为 char* 并且您得到预期的结果。

然而在函数func中,str + 1处的字节将被解释为char [8],你知道它将return这个对象的第一个地址是str+1