繁体   English   中英

在 c 语言中将二维数组传递给 function,int* b[4] 和 int b[][4] 有什么区别?

[英]passing a 2d-array to a function in c language, what is the difference between int* b[4] and int b[][4]?

我正在尝试移动二维数组的行:

#include <stdio.h>
#include <string.h>

void shift_to_left(int* b[4], int* new_col){
  for(size_t i=0; i<1; i++)
    memcpy(*(b+i+1), *(b+i), sizeof(int)*4);
  memcpy(*(b+1), new_col, sizeof(int)*4);
}

int main(){
  int a[4] = {1, 2, 3, 4};
  int b[2][4] = {{7, 8, 4, 5}, {8, 9, 5, 1}};

  printf("Before: \n");
  for(int i=0; i<2; i++){
    for(int j=0; j<4; j++)
      printf("%d ", b[i][j]);
    printf("\n");
  }

  shift_to_left(b, a);

  printf("After: \n");
  for(int i=0; i<2; i++){
    for(int j=0; j<4; j++)
      printf("%d ", b[i][j]);
    printf("\n");
  }
}

我收到一条警告,告诉我 function shift_to_left()需要一个双指针,但得到了一个数组:

array_to_pointer.c: In function ‘main’:
array_to_pointer.c:38:17: warning: passing argument 1 of ‘shift_to_left’ from incompatible pointer type [-Wincompatible-pointer-types]
   shift_to_left(b, a);
                 ^
array_to_pointer.c:20:6: note: expected ‘int **’ but argument is of type ‘int (*)[4]’
 void shift_to_left(int* b[4], int* new_col)

当我忽略警告并运行代码时,出现分段错误:

Before: 
7 8 4 5 
8 9 5 1 
Segmentation fault (core dumped)

当我将 function 的原型从void shift_to_left(int* b[4], int* new_col)更改为void shift_to_left(int b[][4], int* new_col)时,分段错误消失了:

Before: 
7 8 4 5 
8 9 5 1 
After: 
7 8 4 5 
1 2 3 4

但在这两种情况下, memcpy(*(b+i+1), *(b+i), sizeof(int)*4); 不起作用(数组 b 的第一行保持不变)。

将数组作为int* b[4]传递和将其作为int b[][4]传递有什么区别?

在这种情况下,memcpy 有什么问题?

int* b[4]是一个包含 4 个int指针的数组。 int (*b)[4]是一个指向由 4 个整数组成的数组的指针, int b[][4]也是如此。

实际上,相同的 memory 被解释为以下两种方式之一:

// int* b[4] (4x 64-bit pointers)
[aaaaaaaabbbbbbbbccccccccdddddddd]
 ^ int* |^ int* |^ int* |^ int*

// int (*b)[4] (Nx 4x int)
[1111222233334444111122223333444411112222333344441111222233334444...]
 ^ int[4]       |^ int[4]       |^ int[4]       |^ int[4]

int[4]视为指针将在取消引用时立即导致分段错误。 这不是一个有效的指针。

如果您打开警告(许多编译器上的-Wall ),您将收到类似这样的消息,提醒您注意问题:

24d.c:21:17: warning: incompatible pointer types passing 'int [2][4]' to parameter of type 'int **' [-Wincompatible-pointer-types]
  shift_to_left(b, a);

如果您对 C 尽力做到这一点感到困惑,请使用像cdecl这样的解码器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM