簡體   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