ANSI C通过指针使用2dim数组
很久很久以前,我玩了很多次ANSI C通过指针使用2dim数组,c,arrays,pointers,multidimensional-array,C,Arrays,Pointers,Multidimensional Array,很久很久以前,我玩了很多次C,但都忘了。现在我试图解决简单的任务,但失败了 我想写一个函数,它接受2dim数组或char*并打印它。但是我的代码有缺陷,我不明白为什么。据我所知,products是指向2dim数组的指针,所以将它增加到I*sizeof(char**)我得到指向子数组的指针,增加子数组指针我得到指向char块的指针。但我的代码看起来好像是在寻找不同的内存块 关于产品数组-我知道它有N行和2列 #include <stdio.h> #include <string.
C
,但都忘了。现在我试图解决简单的任务,但失败了
我想写一个函数,它接受2dim数组或char*
并打印它。但是我的代码有缺陷,我不明白为什么。据我所知,products
是指向2dim数组的指针,所以将它增加到I*sizeof(char**)
我得到指向子数组的指针,增加子数组指针我得到指向char块的指针。但我的代码看起来好像是在寻找不同的内存块
关于产品
数组-我知道它有N行和2列
#include <stdio.h>
#include <string.h>
void print(char*** products, size_t rows, size_t cols) {
size_t i;
for(i = 0; i < rows; i++) {
printf("Col1: '%s. Col2: %s'\n",
(products + i * sizeof(char**)),
(products + i * sizeof(char**) + sizeof(char*))
);
}
}
int main(void) {
const char* a[][3] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
print((char***)a, 3, 2);
return 0;
}
#包括
#包括
无效打印(字符***产品、大小行、大小列){
尺寸i;
对于(i=0;i
此声明中定义的数组
const char* a[][3] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
#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" );
}
具有类型常量字符*[3][3]
考虑到数组有三个“列”,在数组声明中显式指定了三个列
const char* a[][3] =....
^^^
最后一列中的元素由NULL
初始化
当数组在表达式中用作参数时,它会显式转换为指向其第一个元素的指针
也就是说,如果使用上面显示的数组作为参数,那么它将转换为类型
const char * ( * )[3]
它与char***
所以函数应该声明为like
void print( const char * ( *products )[3], size_t rows );
或者
void print( const char * products[][3], size_t rows );
函数的调用应该像
print( a, 3 );
print( a, 3, 2 );
print( 3, 3, a );
您可以再指定一个参数来设置要输出的列数(例如)
void print( const char * ( *products )[3], size_t rows, size_t cols );
在这种情况下,可以像这样调用函数
print( a, 3 );
print( a, 3, 2 );
print( 3, 3, a );
但是,数组本身在任何情况下都有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( a, 3 );
print( a, 3, 2 );
print( 3, 3, a );
下面是一个演示程序,它显示了函数声明的两种方式
const char* a[][3] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
#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" );
}
考虑到,如果编译器支持可变长度数组,则可能无法初始化它们,然后定义它们。此声明中定义的数组
const char* a[][3] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
#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" );
}
具有类型常量字符*[3][3]
考虑到数组有三个“列”,在数组声明中显式指定了三个列
const char* a[][3] =....
^^^
最后一列中的元素由NULL
初始化
当数组在表达式中用作参数时,它会显式转换为指向其第一个元素的指针
也就是说,如果使用上面显示的数组作为参数,那么它将转换为类型
const char * ( * )[3]
它与char***
所以函数应该声明为like
void print( const char * ( *products )[3], size_t rows );
或者
void print( const char * products[][3], size_t rows );
函数的调用应该像
print( a, 3 );
print( a, 3, 2 );
print( 3, 3, a );
您可以再指定一个参数来设置要输出的列数(例如)
void print( const char * ( *products )[3], size_t rows, size_t cols );
在这种情况下,可以像这样调用函数
print( a, 3 );
print( a, 3, 2 );
print( 3, 3, a );
但是,数组本身在任何情况下都有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( a, 3 );
print( a, 3, 2 );
print( 3, 3, a );
下面是一个演示程序,它显示了函数声明的两种方式
const char* a[][3] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
#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" );
}
考虑到可变长度数组(如果编译器支持)可能未初始化,则定义它们
const char*a[][3]={{{“abc”,“1”},{“def”,“2”},{“ghi”,“3”}代码>
在这种情况下,您实际上可以编写:
const char* a[][2] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
但是如果你真的想要一个3列数组,你应该告诉print有3列,而不是2列。但是你的打印只能打印前两列当然
然后,任何T
的N维数组都可以看作是T
的简单1D数组。您只需进行一些地址计算即可访问所需的元素。一旦有了指向数组第一项的指针,就可以这样做。下面是一个工作版本:
#include <stdio.h>
#include <string.h>
typedef const char * T;
void print(T *products, size_t rows, size_t cols) {
size_t i;
for (i = 0; i < rows; i++) {
// Each row has cols items so here is the current row (i-th row):
T *row = products + i * cols;
printf("{%s, %s}\n", row[0], row[1]);
}
}
int main(void) {
T a[][3] = { { "abc", "1" }, { "def", "2" }, { "ghi", "3" } };
// Tell print that there are 3 cols, not 2
print(&a[0][0], 3, 3);
return 0;
}
#包括
#包括
typedef const char*T;
无效打印(T*产品、大小行、大小列){
尺寸i;
对于(i=0;i
const char*a[][3]={{{“abc”,“1”},{“def”,“2”},{“ghi”,“3”}代码>
在这种情况下,您实际上可以编写:
const char* a[][2] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
但是如果你真的想要一个3列数组,你应该告诉print有3列,而不是2列。但是你的打印只能打印前两列当然
然后,任何T
的N维数组都可以看作是T
的简单1D数组。您只需进行一些地址计算即可访问所需的元素。一旦有了指向数组第一项的指针,就可以这样做。下面是一个工作版本:
#include <stdio.h>
#include <string.h>
typedef const char * T;
void print(T *products, size_t rows, size_t cols) {
size_t i;
for (i = 0; i < rows; i++) {
// Each row has cols items so here is the current row (i-th row):
T *row = products + i * cols;
printf("{%s, %s}\n", row[0], row[1]);
}
}
int main(void) {
T a[][3] = { { "abc", "1" }, { "def", "2" }, { "ghi", "3" } };
// Tell print that there are 3 cols, not 2
print(&a[0][0], 3, 3);
return 0;
}
#包括
#包括
typedef const char*T;
无效打印(T*产品、大小行、大小列){
尺寸i;
对于(i=0;i
您已经混淆了您所认为的列和行。解决这个问题,然后摆脱三星级的胡说八道,让函数接受可变数量的列,结果如下:
#include <stdio.h>
void print(size_t rows, size_t cols, const char* products[rows][cols])
{
for(size_t r=0; r<rows; r++)
{
for(size_t c=0; c<cols; c++)
{
printf("Col%zu: %s. ", c, products[r][c]);
}
printf("\n");
}
}
int main (void)
{
const char* a[3][2] = {{"abc", "1"}, {"def", "2"}, {"ghi", "3"}};
print(3, 2, a);
return 0;
}
#包括
空白打印(si)