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

C 以下2D数组声明之间有什么区别?,c,arrays,C,Arrays,我似乎无法在脑海中清楚地理解这一点,尤其是在试图将数组作为参数传递给函数时 char *array[x][y]; 及 我知道这两个都是2D数组,我可以将第二个声明作为函数参数传递,如下所示: 原型 void check(char**); 然后用它作为 void check(char array[][]) {} 第一个是一个二维数组,由char*-即char指针组成,通常在C中用作stings。第二个是一个二维数组,由chars-即单个字符组成。第一个是一个二维数组,由char*-即。,ch

我似乎无法在脑海中清楚地理解这一点,尤其是在试图将数组作为参数传递给函数时

char *array[x][y];

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

void check(char**);
然后用它作为

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

第一个是一个二维数组,由
char*
-即
char
指针组成,通常在C中用作stings。第二个是一个二维数组,由
char
s-即单个字符组成。

第一个是一个二维数组,由
char*
-即。,
char
指针,通常在C中用作Sting。第二个是二维数组的
char
s,即单个字符。

第一个是二维数组的
char*
,即
char
指针,第二个是一个由
char
s组成的二维数组,即单个字符。

第一个是一个由
char*
-组成的二维数组,即
char
指针,在C中经常用作sting。第二个是一个由
char
s-组成的二维数组,即。,单个字符。

这里有一些代码来说明作为参数的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;
}
样本输出:

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]>>
2D数组:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 
三指针:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 

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

这里有一些代码来说明作为参数的2D指针数组与作为参数的字符***参数之间的差异

#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;
}
样本输出:

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]>>
2D数组:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 
三指针:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 

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

这里有一些代码来说明作为参数的2D指针数组与作为参数的字符***参数之间的差异

#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;
}
样本输出:

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]>>
2D数组:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 
三指针:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 

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

这里有一些代码来说明作为参数的2D指针数组与作为参数的字符***参数之间的差异

#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;
}
样本输出:

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]>>
2D数组:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 
三指针:
[0,0] = 
[0,1] = 
[0,2] = 
[0,3] = 
[1,0] = 
[1,1] = 
[1,2] = 
[1,3] = 
[2,0] = 
[2,1] = 
[2,2] = 
[2,3] = 


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

一个是
字符的2D数组
;另一个是
char*
(字符指针)的2D数组。他们完全不同!因此,在
char数组[x][y]
数组中,我无法用字符串填充它?而且,2D数组不会作为指向指针的指针传递。使用
char数组[x][y][code>,您最多可以复制
x
字符串,每个字符串的长度不超过
y-1
字节(以允许在
strlen()
中不包含的终止null)进入数组-使用
strcpy()
或类似函数。然后可以使用
for(inti=0;i
(例如)打印数组中存储的每个
n
字符串(
n好的,hanks,但是
char*array[x][y]
?一个是
char
的2D数组;另一个是
char*
(字符指针)的2D数组。它们完全不同!因此在
char数组[x][y]中
array我不能用字符串填充它?另外,2D数组不能作为指向指针的指针传递。使用
char array[x][y]
,您最多可以复制
x
字符串,每个字符串的长度不超过
y-1
字节(以允许在
strlen()
中不包含终止null)