以下2D数组声明之间有什么区别?

时间:2014-10-12 21:05:28

标签: c arrays

我似乎无法明白这一点,特别是在尝试将数组作为参数传递给函数时

char *array[x][y];

char array[x][y];

我知道这两个都是2D数组,我可以将第二个声明作为函数参数传递,如下所示: 原型

void check(char**);

然后将其用作

void check(char array[][]) {}

2 个答案:

答案 0 :(得分:2)

以下是一些代码,用于说明作为参数的2D数组与char ***参数之间的差异。

#define _XOPEN_SOURCE 700  // Declare strdup() on Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void function_taking_2d_array(int x, int y, char *array[x][y])
{
    printf("2D array:\n");
    for (int i = 0; i < x; i++)
        for (int j = 0; j < y; j++)
            printf("[%d,%d] = <<%s>>\n", i, j, array[i][j]);
}

static void function_taking_triple_pointer(int x, int y, char ***array)
{
    printf("Triple pointer:\n");
    for (int i = 0; i < x; i++)
        for (int j = 0; j < y; j++)
            printf("[%d,%d] = <<%s>>\n", i, j, array[i][j]);
}

int main(void)
{
    int x = 3;
    int y = 4;
    char *array[x][y];

    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < y; j++)
        {
            char buffer[32];
            snprintf(buffer, sizeof(buffer), "fixed string [%d][%d]", i, j);
            array[i][j] = strdup(buffer);
        }
    }

    function_taking_2d_array(x, y, array);

    char **aux[x];
    for (int i = 0; i < x; i++)
        aux[i] = array[i];

    function_taking_triple_pointer(x, y, aux);

    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < y; j++)
            free(array[i][j]);
    }

    return 0;
}

干净利落地编译:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -Werror c3d.c -o c3d
$

示例输出:

2D array:
[0,0] = <<fixed string [0][0]>>
[0,1] = <<fixed string [0][1]>>
[0,2] = <<fixed string [0][2]>>
[0,3] = <<fixed string [0][3]>>
[1,0] = <<fixed string [1][0]>>
[1,1] = <<fixed string [1][1]>>
[1,2] = <<fixed string [1][2]>>
[1,3] = <<fixed string [1][3]>>
[2,0] = <<fixed string [2][0]>>
[2,1] = <<fixed string [2][1]>>
[2,2] = <<fixed string [2][2]>>
[2,3] = <<fixed string [2][3]>>
Triple pointer:
[0,0] = <<fixed string [0][0]>>
[0,1] = <<fixed string [0][1]>>
[0,2] = <<fixed string [0][2]>>
[0,3] = <<fixed string [0][3]>>
[1,0] = <<fixed string [1][0]>>
[1,1] = <<fixed string [1][1]>>
[1,2] = <<fixed string [1][2]>>
[1,3] = <<fixed string [1][3]>>
[2,0] = <<fixed string [2][0]>>
[2,1] = <<fixed string [2][1]>>
[2,2] = <<fixed string [2][2]>>
[2,3] = <<fixed string [2][3]>>

需要特别注意的是,两个函数之间的区别在于函数名称和签名以及标识消息中 - 其余函数体的源是相同的。不过,如果你查看两个函数的汇编代码(假设它们没有为你内联),你会看到它们生成不同的指令 - 因为参数的类型不一样。

答案 1 :(得分:1)

第一个是char*的二维数组 - 即char 指针,它们通常用作C中的叮咬。第二个是二维数组char s - 即单个字符。