RGBTRIPLE (*image)[width] = calloc(height, width * sizeof(RGBTRIPLE))
我不完全理解代码。我的理解是:
calloc(height, width * sizeof(RGBTRIPLE))
- 我们在堆内存中的某处为特定数据组织一个特定大小的位置,并将该内存中的所有值设置为 0
RGBTRIPLE (*image)[width]
表示变量图像是一个指针,指向一个长宽为 RGBTRIPLE 的数组。RGBTRIPLE
是一个包含3个变量的数据结构:BYTE rgbtBlue
; BYTE rgbtGreen
; BYTE rgbtRed
;为什么不为两个值创建数组:
width
和 length
但只为 width
。对我来说,这段代码表明我们只创建了数组 [1d] 而不是应该的 [2d],图像是 2d ...
下面发一张我自己推理的图
试图理解 pset CS50 笑脸中的代码行。
其实在这一行
RGBTRIPLE (*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
为
RGBTRIPLE[height][width]
类型的二维数组分配了一块内存,其地址分配给声明的指针image
。分配给二维数组的内存是零初始化的。
注意,如果你有一个二维数组,例如
RGBTRIPLE array[height][width];
然后声明并初始化指向数组第一个元素的指针
RGBTRIPLE ( *image )[width] = array;
即用作初始化表达式的数组指示符被隐式转换为指向其第一个元素的指针。
在您的情况下,不是为指针分配数组,而是为这样的数组分配动态分配的内存地址。
如果编译器支持可变长度数组那么这一行
RGBTRIPLE (*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
可以改写成
RGBTRIPLE (*image)[width] = calloc(height, sizeof( RGBTRIPLE[width] ) );
从中可以看出,为
height
(s) 类型的一维数组分配了内存
因此像
RGBTRIPLE[width]
一样取消引用指针图像,您将获得二维数组的第一“行”。要访问第一行的元素,您可以编写例如
RGBTRIPLE[height][width]
或 ( *image )
等。如果每个“行”的元素都有结构类型,那么您可以编写例如问题中所示的内容
( *image )[0]
.
下表中的 RGB 变量是随机选择的。 如果例如hight = 6 和
( *image )[1]
|{{255, 255, 255},| {0, 0, 0},| {255, 0, 0},| {0, 255, 0},| {0, 0, 255}},|{{255, 255, 255},| {0, 0, 0},| {255, 0, 0},| {0, 255, 0},| {0, 0, 255}},