【发布时间】:2021-06-18 10:09:30
【问题描述】:
我正在尝试移动二维数组的行:
#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");
}
}
我收到一条警告,告诉我函数 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)
当我将函数的原型从 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]' 在此上下文中与 'int (*b)[4]' 相同
-
您刚刚发现了为什么使用 1D 数组和模拟 2D 几乎总是比实际使用 2D 数组或数组数组更好。您可以一次性复制一维数组,非常简单。不需要循环。
-
提示:不要使用
*(x+n),而是使用x[n]。语法更加整洁,对于熟悉 C 指针以及它们如何像数组一样工作的人来说更有意义。 -
@tstanisl 将括号放在 b 周围解决了这个问题! int b[4] 是一回事, int (*b)[4] 是另一回事。 memcpy 是怎么回事?