c - 如何更改数组的 "geometry"?

标签 c arrays pointers ansi

如何将数组的“几何形状”从一维更改为二维(从线性数组到方阵)?

在我的代码中,我有一个函数返回data,定义为:

unsigned long *data = malloc(sizeof(unsigned long) * 9);

接收数据的函数正在使用该指针作为调用另一个函数的参数:

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)]

编辑

根据评论中的要求,以下是我生成原始数据的方式:

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;
    }
}

最佳答案

虽然我觉得这不是“改变”几何而是“重新解释”它,但是遵循了一些方法。

这样做:

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 兼容方法无需任何强制转换就可以使用……- 虽然很有趣。 ;-)

关于c - 如何更改数组的 "geometry"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20816195/

相关文章:

c++ - 返回指向intent(in)参数的指针

c - 使用 LD_PRELOAD 和 IFS 利用 SUID 文件

c - igraph_vector_init_finally 和 igraph_vector_cumsum

arrays - 将字符串、整数和数组的 JSON 对象解码到映射中

java - 将 m.group(1) 转换为字符串数组

为算术转换指针 - C

c - scanf 不等待输入就返回 0

在 Mac OS X 下编译 Linux 程序

C - 使用 scanf 将字符串扫描到数组中

在函数内部更改指针不会反射(reflect)在函数外部