【问题标题】:Accessing a one-dimensional array as a two-dimensional array将一维数组作为二维数组访问
【发布时间】:2014-06-16 09:28:40
【问题描述】:

我有一个一维数组int *data,我知道有效存储在其中的rowscols 的数量。也就是说,我可以使用data[i*cols+j] 之类的东西访问二维矩阵(i,j) 的元素。

具体来说,这些存储在一个结构中:

typedef struct {
    int *data;
    int rows;
    int cols;
} matrix_t;

在过去的某个时候,我也写了这个巫毒代码:

#define MATRIXP(m) __typeof__(__typeof__(__typeof__(*((m).data))[(m).cols]) *)
#define MATRIXD(m) ((MATRIXP(m)) ((m).data))

有了这些定义,我可以做到:

MATRIXP(matrix) m = MATRIXD(matrix);

然后我可以使用矩阵m作为二维矩阵指针来访问data

m[3][2] = 5; /* assign the element in row 3 and column 2 */

这非常好,意味着我不需要记住总是有一个像data[i*cols+j] 这样的表达式。但是,这段代码是我前段时间写的,现在我不记得它是如何工作的了。

  1. 谁能解释一下所有__typeof__ 运算符是如何工作的,以及如何阅读类似的表达式?变量m的类型是什么?

    我知道它会扩展为:

    __typeof__(__typeof__(__typeof__(*((matrix).data))[(matrix).cols]) *) m = ((__typeof__(__typeof__(__typeof__(*((matrix).data))[(matrix).cols]) *)) ((matrix).data));
    
  2. 这种访问data 的方法安全吗?这是最好的方法吗?

【问题讨论】:

  • +1,但是你知道c99 和更高版本允许你为像int (*data)[cols] = malloc(sizeof(int[rows][cols])); 这样的多暗淡数组分配连续内存,我的意思是你做的很好,但看起来有更好的方法。
  • 在 C99 之前的版本中,您仍然可以使用 int(*data)[cols] = malloc(sizeof(int)*rows*cols);
  • 您不能在结构定义中放置像int (*data)[cols] 这样的字段。我并不是真的在问如何在它使用的同一范围内分配这样的东西。我需要能够将它传递给其他函数并轻松访问它。

标签: c arrays matrix multidimensional-array typeof


【解决方案1】:

问题一:

MATRIXP(matrix) mmatrix 应该是 matrix_t 类型的变量)将扩展为

__typeof__(__typeof__(__typeof__(*((matrix).data))[(matrix).cols]) *) m

从里到外

  1. __typeof__(*((matrix).data))*((matrix).data)的类型,根据matrix_t的定义是int

  2. 所以(__typeof__(*((matrix).data))[(matrix).cols]) 等于(int [cols])

  3. 所以__typeof__(__typeof__(*((matrix).data))[(matrix).cols]) *) 等于(int [cols] *)

  4. 这就是MATRIXP(matrix)给出的类型。

因此,MATRIXP(matrix) 等于 (int [(matrix).cols] *)。换句话说,

MATRIXP(matrix) m

有效

int (*m)[matrix.cols]

正如@codebeard 指出的那样

问题 2:

对我来说看起来很安全。

【讨论】:

  • 感谢您的回答。所以MATRIXP(matrix) m 实际上是int (*m)[matrix.cols]?为什么这会导致堆栈上的大量分配?
  • @codebeard 哦,不会的。我的错误,答案已更新。感谢您指出这一点。
  • 我认为我的部分困惑是,虽然 __typeof(int *)__ xint *x 相同,但 __typeof(int [5] *)__ x 不是 int [5] *x 而是 int (*x)[5],而且还不是 100% 清楚我为什么会这样。
  • @codebeard __typeof 是原因。 __typeof(int [5]) 是一个由五个 ints 组成的数组的类型,但是,int [5] 不是有效的 C 类型,因此您不能像 int [5] *x 那样定义指向该类型的指针,而必须使用 int (*x)[5] .还注意到__typeof(int [5] *)是无效的,你必须写成__typeof(__typeof(int [5]) *)
猜你喜欢
  • 2013-06-29
  • 2017-04-06
  • 2018-11-20
  • 2016-02-18
  • 2018-02-19
  • 2014-03-25
  • 1970-01-01
相关资源
最近更新 更多