在 C 中定义类型时对指针语法感到困惑
confused about pointer syntax when defining type in C
在一些起始代码中我们有:
/**
* RGBTRIPLE
*
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*
* Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
*/
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
在我们的主程序中我们有:
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
我对 (*image) 感到困惑
如果我要定义一个指向 RGBTRIPLE 的指针,我想我会使用:
RGBTRIPLE *image[width] = ....
是否与以下内容相同:
RGBTRIPLE(*image)[width] = .... ?
这些不一样。
RGBTRIPLE *image[width]
这表示一个大小为 width
的数组,其元素的类型为 RGBTRIPLE *
,即它是一个指针数组。
RGBTRIPLE(*image)[width]
这是一个指向大小为 width
的数组的指针,其成员的类型为 RGBTRIPLE
。
两者都可用于实现二维数组,但方式不同。如果您使用前一个声明,则必须按如下方式分配额外维度:
int i;
for (i=0; i<width; i++) {
image[i] = calloc(height, sizeof(RGBTRIPLE));
}
RGBTRIPLE *image[width];
是一个指向RGBTRIPLE
的指针数组,这个数组将有width
个元素。该数组中的每个指针都能够指向一个 RGBTRIPLE
对象,这使得当您每行有多个这样的对象时可以拥有一个二维数组。
分配比较混乱,因为您需要自己分配指针数组,然后分配每个指针指向的每一行,然后以相反的顺序释放内存。
RGBTRIPLE(*image)[width];
是指向RGBTRIPLE
数组的指针,这个数组必须有width
个元素,既然如此你可以用它来指向一个任意行数的二维数组只要它有 width
列数。
这是实现二维数组的更好方法,因为它有助于分配和释放。
它的工作原理是允许它通过递增指针以 width
字节大小的块移动指针,实际上它让您通过一次递增指针“跳转”到下一行。
例如width
的6个和height
的2个数组:
+-----------+
image[0] -> |0|1|2|3|4|5|
+-----------+
|5|4|3|2|1|0|
+-----------+
+-> image[0][4]
|
+-----------+
|0|1|2|3|4|5|
+-----------+
image[1] -> |5|4|3|2|1|0|
+-----------+
|
+-> image[1][4]
表达式:
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
可能会更好,我会使用更安全的方法:
RGBTRIPLE(*image)[width] = calloc(height, sizeof *image);
在一些起始代码中我们有:
/**
* RGBTRIPLE
*
* This structure describes a color consisting of relative intensities of
* red, green, and blue.
*
* Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
*/
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;
在我们的主程序中我们有:
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
我对 (*image) 感到困惑
如果我要定义一个指向 RGBTRIPLE 的指针,我想我会使用:
RGBTRIPLE *image[width] = ....
是否与以下内容相同:
RGBTRIPLE(*image)[width] = .... ?
这些不一样。
RGBTRIPLE *image[width]
这表示一个大小为 width
的数组,其元素的类型为 RGBTRIPLE *
,即它是一个指针数组。
RGBTRIPLE(*image)[width]
这是一个指向大小为 width
的数组的指针,其成员的类型为 RGBTRIPLE
。
两者都可用于实现二维数组,但方式不同。如果您使用前一个声明,则必须按如下方式分配额外维度:
int i;
for (i=0; i<width; i++) {
image[i] = calloc(height, sizeof(RGBTRIPLE));
}
RGBTRIPLE *image[width];
是一个指向RGBTRIPLE
的指针数组,这个数组将有width
个元素。该数组中的每个指针都能够指向一个 RGBTRIPLE
对象,这使得当您每行有多个这样的对象时可以拥有一个二维数组。
分配比较混乱,因为您需要自己分配指针数组,然后分配每个指针指向的每一行,然后以相反的顺序释放内存。
RGBTRIPLE(*image)[width];
是指向RGBTRIPLE
数组的指针,这个数组必须有width
个元素,既然如此你可以用它来指向一个任意行数的二维数组只要它有 width
列数。
这是实现二维数组的更好方法,因为它有助于分配和释放。
它的工作原理是允许它通过递增指针以 width
字节大小的块移动指针,实际上它让您通过一次递增指针“跳转”到下一行。
例如width
的6个和height
的2个数组:
+-----------+
image[0] -> |0|1|2|3|4|5|
+-----------+
|5|4|3|2|1|0|
+-----------+
+-> image[0][4]
|
+-----------+
|0|1|2|3|4|5|
+-----------+
image[1] -> |5|4|3|2|1|0|
+-----------+
|
+-> image[1][4]
表达式:
RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
可能会更好,我会使用更安全的方法:
RGBTRIPLE(*image)[width] = calloc(height, sizeof *image);