C 通过指针的二维数组
我想创建一个动态数组来存储置换序列,这样C 通过指针的二维数组,c,pointers,C,Pointers,我想创建一个动态数组来存储置换序列,这样 order[0][]={1,2,3} order[1][]={2,1,3} order[2][]={2,3,1} 假设顺序[m][n],m=排列数,n=项数,m和n被实时识别 我做了以下操作,发现指针地址重叠,导致不正确的值存储。如何通过双指针正确使用动态数组 void permute(int num_permute, int num_term, int** order) { int x, y; int term[5]; /*
order[0][]={1,2,3}
order[1][]={2,1,3}
order[2][]={2,3,1}
假设顺序[m][n],m=排列数,n=项数,m和n被实时识别
我做了以下操作,发现指针地址重叠,导致不正确的值存储。如何通过双指针正确使用动态数组
void permute(int num_permute, int num_term, int** order) {
int x, y;
int term[5];
/* debug only */
for(y=num_term, x=0; y>0; y--, x++){
term[x] = y;
}
fprintf(stderr, "\n");
printf("order%12c", ' ');
for (x=0; x<num_permute; ++x) {
printf(" %-11d", x);
}
printf("\n");
for(y=0; y<num_permute; y++){
printf("%-5d%12p", y, (order+y));
memcpy(&(order[y]), term, sizeof(term));
for (x=0; x<num_term; x++)
printf(" %12p", order+y+x);
printf("\n");
}
}
int main(){
int y, z;
int** x;
x = (int*) malloc(5*5*sizeof(int*));
permute(5, 5, x);
printf("\n");
printf("x ");
for(z=0; z<5; z++){
printf(" %2d ", z);
}
printf("\n");
for(y=0; y<5; y++){
printf("%-4d", y);
for(z=0; z<5; z++){
printf(" %2d ", *(x+y+z));
}
printf("\n");
}
free(x);
return 0;
}
void排列(int num\u排列,int num\u术语,int**order){
int x,y;
整数项[5];
/*仅调试*/
对于(y=num_项,x=0;y>0;y--,x++){
项[x]=y;
}
fprintf(标准格式,“\n”);
printf(“订单%12c”,”;
对于(x=0;x源代码:
代码将类似于:
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
if(array == NULL)
{
fprintf(stderr, "out of memory\n");
/*exit or return*/
}
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
/*exit or return*/
}
}
以下代码段为给定的行和列创建二维矩阵。请将其用作调试程序的参考
#include <stdio.h>
#include <stdlib.h>
int main()
{
int row, column;
int **matrix;
int i, j, val;
printf("Enter rows: ");
scanf("%d", &row);
printf("Enter columns: ");
scanf("%d", &column);
matrix = (int **) malloc (sizeof(int *) * row);
if (matrix == NULL) {
printf("ERROR: unable to allocate memory \n");
return -1;
}
for (i=0 ; i<row ; i++)
matrix[i] = (int *) malloc (sizeof(int) * column);
val=1;
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
matrix[i][j] = val++;
}
}
for (i=0 ; i<row ; i++) {
for (j=0 ; j<column; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
return 0;
}
/*
Allocation of 2d matrix with only one call to malloc and
still get to access the matrix with a[i][j] format
the matrix is divided into headers and data.
headers = metadata to store the rows
data = actual data storage - buffer
allocate one contigious memory for header and data
and then make the elements in the header to point to the data are
<- headers -----><----------- data -----------
-----------------------------------------------------------------
| | | | | | .. |
| | | | | | .. |
-----------------------------------------------------------------
| ^
| |
|-----------------|
header points to data area
*/
/*
Output:
$ gcc 2darray.c
$ ./a.out
Enter rows: 10
Enter columns: 20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
$
*/
#包括
#包括
int main()
{
int行,列;
int**矩阵;
int i,j,val;
printf(“输入行:”);
scanf(“%d”行和第行);
printf(“输入列:”);
scanf(“%d”列和列);
矩阵=(int**)malloc(sizeof(int*)*行);
if(矩阵==NULL){
printf(“错误:无法分配内存\n”);
返回-1;
}
对于(i=0;i,代码示例仅模拟多维数组,但操作不正确。若要查看出现了什么问题,请从声明多维数组时发生的情况开始:
int foo[3][5];
这将分配大小为3*5*sizeof(int)的连续内存区域。在诸如foo[i]
之类的表达式中,foo
被转换为int[5]
指针,然后应用索引运算符。换句话说,foo[i]
相当于*((int(*)[5])foo)+i)
。每个foo[i]
将被视为大小为5*sizeof(int)
x、 y:0,0,10,20,30,41,0
foo-->1 | 2 | 3 | 4 | 5 | 1 |。。。
在示例代码中创建x
时,您正在复制这种类型的多维数组。因此,您使用的索引表达式(*(order+y+x)
)是错误的,因为它不能正确处理order[y]的大小
:order+1+0==order+0+1
,这就是您在示例输出中看到的问题
正确的表达式是:(order+num\u term*y)
用于yth排列,而*(order+num\u term*y+x)
用于元素顺序[y][x]
这表明示例中存在另一类错误。对于这种模拟多维数组,数组类型实际上是指向一维数组的指针。x
和order
的声明类型应该是int*
,而不是int**
。这应该通过示例代码中的类型警告得到加强应产生:
- 为
x
分配空间时,指针的类型(int*
)与x
的类型不匹配
- 打印
x
的元素时,*(x+y+z)
的类型与格式“%d”不匹配
但是,虽然模拟多维数组可以节省空间,但在使用时更容易出错(除非您编写一个函数来处理索引)。像Als这样的解决方案可能更安全,因为您可以使用标准的索引运算符。如果您有C99(或C11),则使用指针数组模拟二维数组完全是一种过激行为。只需使用
void permute(size_t num_permute, size_t num_term, unsigned order[][num_term]);
作为函数签名,并在main
中分配矩阵
unsigned (*order)[m] = malloc(sizeof(unsigned[n][m]));
此外,正如您在上面的示例中所看到的,我建议您使用语义正确的类型。大小总是与size\u t
一起提供的,并且您的排列值在我看来似乎永远不会是负数。也许对于这些,您也应该从0
开始计数,谢谢!!我忘记了这个概念!!我同意在这里使用真正的2D数组可能是最好的。只有对于OP,维度是动态的,在编译时不知道。使用C99可以直接在堆栈上执行VLA,但当维度未知时这有点危险。这就是为什么我在回答中使用malloc
ed数组的原因。@JensGustedt:twfx不应该使用2D数组我只是用它来解释代码中发生了什么。注意:所以使用Q&a格式。问题不应该包含答案。
x,y: 0,0 0,1 0,2 0,3 0,4 1,0
foo --> | 1 | 2 | 3 | 4 | 5 | 1 |...
<- 5 * sizeof(int) ->
void permute(size_t num_permute, size_t num_term, unsigned order[][num_term]);
unsigned (*order)[m] = malloc(sizeof(unsigned[n][m]));