在 C 中将多维数组作为参数传递

Posted

技术标签:

【中文标题】在 C 中将多维数组作为参数传递【英文标题】:Passing a multidimensional array as an argument in C 【发布时间】:2022-01-09 08:49:45 【问题描述】:

我正在尝试在辅助函数中初始化矩阵,但在访问辅助函数中的矩阵时收到警告,我无法弄清楚如何修复。我正在阅读有关多维数组的内容,甚至在多个示例中看到了用于传递和访问矩阵的相同表示法,但我的会产生警告,我不太清楚为什么。

据我所知,这个错误意味着参数不是函数所期望的类型,但在将初始化重新定位到它自己的函数之前,我在主函数中使用它很好。这让我认为在将矩阵传递给辅助函数时我做错了。

passing argument 1 of 'memmove' makes pointer from integer without a cast [-Wint-conversion] 

这是我的初始化程序代码。 p 是指向要初始化到矩阵中的数组内的数据的指针。我正在使用这种类型的嵌套 for 循环将来自 p 的 16 个字节的数据传播到我的矩阵中,每个单元格 1 个字节。

void initialize(const unsigned char *p, unsigned char (*matrix)[4]) 

   for (unsigned int i = 0; i < 4; i++)
       for (unsigned int j = 0; j < 4; j++)
           memmove(matrix[i][j], p + (4*i+j), 1);    <--- Warning here
       ;
   ;
;

正在另一个函数中调用初始化,如下所示:

void func(const unsigned char *p) 
    unsigned char matrix[4][4] = 
        0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0
    ;
    initialize(p, matrix);
;

【问题讨论】:

考虑matrix[i][j] = p[4*i+j] @Darkonode 显示 p 是如何定义和初始化的。 显示您真正想要归档的内容。很难理解p is a pointer to data inside an array that I want to initialize into my matrix. 是什么意思。 【参考方案1】:

传递 'memmove' 的参数 1 使指针从整数而不进行强制转换 [-Wint-conversion]

而不是传递一个整数作为目的地:

unsigned char (*matrix)[4]
...
//         v----------v This is an integer of type unsigned char   
// memmove(matrix[i][j], p + (4*i+j), 1);

传递整数的地址作为目的地:

memmove(&matrix[i][j], p + (4*i+j), 1);
//      ^-----------^ This is an address

void *memmove(void *s1, const void *s2, size_t n); 期望 s1 是一个地址。


func() 中的matrix 一个矩阵,也就是“二维数组”。

initialize() 中的matrix 并不是真正的矩阵,而是指向unsigned chararray[4] 的指针。


从 C99 开始以及以后有选择地,代码可以使用可变长度数组表示法。

void initialize(size_t rows, size_t cols, unsigned char (*m)[rows][cols],
    const unsigned char *p) 
  printf("%zu %zu %zu\n", rows, cols, sizeof *m);
  for (size_t r = 0; r < rows; r++)
    for (size_t c = 0; c < cols; c++)
      (*m)[r][c] = *p++;
    
  



#define ROW 5
#define COL 7
int main(void) 
  unsigned char matrix[ROW][COL];
  unsigned char bytes[sizeof matrix] = "Something abcde fghij klmno pqrst uvwxy z";

  size_t r = sizeof matrix / sizeof matrix[0];
  size_t c = sizeof matrix[0] / sizeof matrix[0][0];
  printf("%zu %zu %zu\n", r, c, sizeof matrix);
  initialize(r, c, &matrix, bytes);

【讨论】:

【参考方案2】:

函数memmove() 将指针作为第一个参数。而matrix[i][j] 是一个char,它是整数族的一个类型。将常量 0 以外的整数分配给指针需要强制转换。否则会引发警告。

因此,我希望为了复制单个 char,您应该将 指针 传递给元素 matrix[i][j]。通过将&amp; 运算符应用于对象来形成指针。

memmove(&matrix[i][j], p + (4*i+j), 1);

但是它可以写​​得更简单、更易读并且可能更优化:

matrix[i][j] = p[4 * i + j];

甚至通过复制整个数组而不使用任何循环:

memmove(matrix, p, 16);

【讨论】:

"指针是通过应用形成的"... 说"对象的地址可以通过应用@987654331得到@(地址)运算符” ? 哇,这太有帮助了。我也一直忘记,即使是多维数组也使用连续内存,我可以完全放弃 for 循环。我确定我测试了您提供的第一个选项,但我想没有。我有点困惑,根据我找到的示例,您可以使用不带 & 的数组表示法,就像这里的第 5 个示例中使用的一样:geeksforgeeks.org/pass-2d-array-parameter-c

以上是关于在 C 中将多维数组作为参数传递的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中将不同大小的常量数组作为函数参数传递

在c ++中将多维数组初始化为类成员

将多维数组传递给函数 C

C++ 数组与字符串⁽²³⁾|函数与数组

C语言中当二维数组和多维数组作为函数参数时[重复]

参数传递之传递多维数组