【问题标题】:Passing array of pointers to a function accepting 2d array将指针数组传递给接受二维数组的函数
【发布时间】:2021-04-15 00:53:32
【问题描述】:

我在 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

【问题讨论】:

  • 是什么让你选择了原型void func(char str[][8])?您是如何编译代码的 - 您是否收到任何警告?
  • 例如,如果使用gcc,则使用gcc -Wall -Werror -Wextra -g 编译并解决显示的所有错误。当您运行无效代码时,您不能期望某种行为
  • 如果你用我建议的命令编译的话,你会立即看到错误:incompatible pointer type ... expected ‘char (*)[8]’ but argument is of type ‘char **’

标签: arrays c pointers output


【解决方案1】:

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 会尝试打印表示指针的字节,就好像它们是字符串一样。

【讨论】:

    【解决方案2】:

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

    #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],你知道它会返回这个对象的第一个地址str+1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多