此声明中定义的数组
const char* a[][3] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
类型为const char *[3][3]。
考虑到数组有三个“列”,在数组声明中明确指定了 3 列。
const char* a[][3] =....
^^^
最后一列中的元素由NULL 初始化。
当在表达式中使用数组作为参数时,它会显式转换为指向其第一个元素的指针。
也就是说,如果您使用上面显示的数组作为参数,那么它将被转换为类型
const char * ( * )[3]
和char ***不一样
所以函数应该像这样声明
void print( const char * ( *products )[3], size_t rows );
或喜欢
void print( const char * products[][3], size_t rows );
函数应该像这样调用
print( a, 3 );
你可以再指定一个参数来设置你想要输出的列数
void print( const char * ( *products )[3], size_t rows, size_t cols );
在这种情况下,函数可以像这样调用
print( a, 3, 2 );
但是无论如何数组本身都有 3 列。:)
或者如果编译器支持可变长度数组,例如
void print( size_t rows, size_t cols, const char * ( *products )[cols] );
为了可读性
void print( size_t rows, size_t cols, const char * products[rows][cols] );
也可以这样称呼
print( 3, 3, a );
这是一个演示程序,显示了函数声明的两种方式
#include <stdio.h>
#include <string.h>
#define N 3
void print1( const char *product[][N], size_t rows )
{
for ( size_t i = 0; i < rows; i++ )
{
for ( const char **p = product[i]; *p; ++p )
{
printf( "%s ", *p );
}
printf( "\n" );
}
}
void print2( size_t rows, size_t cols, const char *product[rows][cols] )
{
for ( size_t i = 0; i < rows; i++ )
{
for ( const char **p = product[i]; *p; ++p )
{
printf( "%s ", *p );
}
printf( "\n" );
}
}
int main( void )
{
const char * a[][N] =
{
{ "abc", "1" },
{ "def", "2" },
{ "ghi", "3" }
};
print1( a, N );
printf( "\n" );
size_t n = N;
const char * b[n][n];
memcpy( b, a, sizeof( a ) );
print2( n, n, b );
printf( "\n" );
}
它的输出是
abc 1
def 2
ghi 3
abc 1
def 2
ghi 3
考虑到可变长度数组(如果编译器支持它们)可能不会被初始化然后它们被定义。