如何将数组的“几何”从一维更改为二维(从线性数组到平方矩阵)?
在我的代码中,我有一个函数返回data
,定义为:
unsigned long *data = malloc(sizeof(unsigned long) * 9);
接收data
的函数正在使用该指针作为调用另一个函数的参数:
sumOfColTwo(data);
但我希望该函数能够访问数组,就好像它是一个3x3矩阵一样。例如,要计算我希望能够执行的列的总数:
void sumOfColTwo(<some-declaration-here>) {
for (i=0; i<3; i++)
sum += data[1][i]
}
换句话说,给定一个线性数组:
A B C D E F G H I
我想以逻辑方式“访问”以下两种形式之一:
A B C A D G
D E F or B E H
G H I C F I
[我正在使用ANSI C(C89)]
修改
根据评论中的要求,以下是我如何生成原始data
:
unsigned long *load_input(void) {
unsigned long *data = malloc(sizeof(unsigned long) * 9);
unsigned char i, parsed;
for (i=0; i<9; i++) {
parsed = scanf("%lu", &data[i]);
}
/* Return the appropriate value (eventually freeing unused memory) */
if (parsed == 1) {
return data;
} else {
free(data);
return NULL;
}
}
答案 0 :(得分:2)
虽然我认为不是“改变”几何,而是“重新解释”它,但是遵循一些方法。
这样做:
void print1dAs2d(unsigned long * _data)
{
unsigned long (*data)[3][3] = (unsigned long (*)[3][3]) _data; /* Hide away the dirty cast. */
for (size_t i = 0; i < 3; ++i)
{
for (size_t j = 0; j < 3; ++j)
{
printf("%lu ", (*data)[i][j]);
}
printf("\n");
}
}
比如这样称呼:
int main(void)
{
unsigned long data[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
print1daAs2d(data);
return 0;
}
为NxM矩阵设置这个通用(假设至少为C99)是这样的:
void print1dAs2d_NxM(size_t n, size_t m, unsigned long * _data)
{
unsigned long (*data)[n][m] = (unsigned long (*)[n][m]) _data; /* Hide away the dirty cast. */
for (size_t i = 0; i < n; ++i)
{
for (size_t j = 0; j < m; ++j)
{
printf("%lu ", (*data)[i][j]);
}
printf("\n");
}
}
对于C89,使用纯指针算术的经典方法:
void print1dAs2d_NxM(size_t n, size_t m, unsigned long * data)
{
for (size_t i = 0; i < n; ++i)
{
for (size_t j = 0; j < m; ++j)
{
printf("%lu ", *(data + i*m + j);
}
printf("\n");
}
}
这种老式的C89兼容方法在没有任何演员的情况下相处得很好......但是有趣的是。 ; - )
答案 1 :(得分:1)
样品
#include <stdio.h>
#include <stdlib.h>
unsigned long sumOfColTwo(unsigned long *data){
unsigned long sum = 0;
unsigned long (*datap)[3] = (unsigned long (*)[3])data;
int i;
/*
for (i=0; i<3; i++)
sum += datap[i][1];
*/
for (i=0; i<3; i++){
printf("%d %lu \n", i, datap[i][1]);
sum += datap[i][1];
}
return sum;
}
int main(){
unsigned long *data = malloc(sizeof(unsigned long) * 9);
int i;
for(i = 0 ; i < 9 ; ++i)
data[i] = i;
printf("%lu\n", sumOfColTwo(data));
free(data);
return 0;
}
答案 2 :(得分:1)
如果您想以下列之一访问9值数组:
A B C A D G
D E F or B E H
G H I C F I
然后你将自己简化为计算数组下标。这是C89代码,它将完成这项工作。它被硬编码为3x3矩阵,因为这是给出的示例。要概括为NxM矩阵并不是很难。
#include <stdio.h>
static void sum_by_rows(int data[9])
{
int i, j;
for (i = 0; i < 3; i++)
{
int sum = 0;
for (j = 0; j < 3; j++)
sum += data[i*3+j];
printf("Sum row %d = %d\n", i, sum);
}
}
static void sum_by_cols(int data[9])
{
int i, j;
for (i = 0; i < 3; i++)
{
int sum = 0;
for (j = 0; j < 3; j++)
sum += data[j*3+i];
printf("Sum col %d = %d\n", i, sum);
}
}
int main(void)
{
int data[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' };
int i, j;
printf("By rows\n");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
printf("A[%d][%d] = %c (%d)\n", i, j, data[i*3+j], data[i*3+j]);
}
printf("By cols\n");
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
printf("A[%d][%d] = %c (%d)\n", i, j, data[j*3+i], data[j*3+i]);
}
sum_by_cols(data);
sum_by_rows(data);
return 0;
}
输出:
By rows
A[0][0] = A (65)
A[0][1] = B (66)
A[0][2] = C (67)
A[1][0] = D (68)
A[1][1] = E (69)
A[1][2] = F (70)
A[2][0] = G (71)
A[2][1] = H (72)
A[2][2] = I (73)
By cols
A[0][0] = A (65)
A[0][1] = D (68)
A[0][2] = G (71)
A[1][0] = B (66)
A[1][1] = E (69)
A[1][2] = H (72)
A[2][0] = C (67)
A[2][1] = F (70)
A[2][2] = I (73)
Sum col 0 = 204
Sum col 1 = 207
Sum col 2 = 210
Sum row 0 = 198
Sum row 1 = 207
Sum row 2 = 216
使用3x4阵列的更一般情况:
#include <stdio.h>
enum { N_ROWS = 3, N_COLS = 4 };
static void sum_by_rows(int data[N_ROWS * N_COLS])
{
int i, j;
for (i = 0; i < N_ROWS; i++)
{
int sum = 0;
for (j = 0; j < N_COLS; j++)
sum += data[i*N_COLS+j];
printf("Sum row %d = %d\n", i, sum);
}
}
static void sum_by_cols(int data[N_ROWS * N_COLS])
{
int i, j;
for (i = 0; i < N_COLS; i++)
{
int sum = 0;
for (j = 0; j < N_ROWS; j++)
sum += data[i*N_ROWS+j];
printf("Sum col %d = %d\n", i, sum);
}
}
int main(void)
{
int data[N_ROWS * N_COLS];
int i, j;
for (i = 0; i < N_ROWS * N_COLS; i++)
data[i] = 'A' + i;
printf("By rows\n");
for (i = 0; i < N_ROWS; i++)
{
for (j = 0; j < N_COLS; j++)
printf(" %c", data[i*N_COLS+j]);
putchar('\n');
}
printf("By cols\n");
for (i = 0; i < N_COLS; i++)
{
for (j = 0; j < N_ROWS; j++)
printf(" %c", data[j*N_ROWS+i]);
putchar('\n');
}
sum_by_cols(data);
sum_by_rows(data);
return 0;
}
输出:
By rows
A B C D
E F G H
I J K L
By cols
A D G
B E H
C F I
D G J
Sum col 0 = 198
Sum col 1 = 207
Sum col 2 = 216
Sum col 3 = 225
Sum row 0 = 266
Sum row 1 = 282
Sum row 2 = 298
我注意到必须使用古老的C89标准会让你感到困惑。如果可以使用C99和VLA(可变长度数组),则可以执行更多有趣的数组操作。
答案 3 :(得分:1)
给定x个行数和y个列数并假设偏移量为零(对于行和列都将第一个索引设为零),然后计算行顺序偏移量(问题中的左矩阵)为:
row_order offset = <row index> * x + <column index>
按列顺序执行的计算(问题中的右边矩阵)将是:
column order offset = <column index> * y + <row index>
where <row index> is the index into the row you want to access and
<column index> is the column you want to access.
然后,您可以通过指针(*(数据+偏移))或索引(数据[偏移])访问数据。