c语言 - 传递给函数的结构数组,取消引用 -> 和 * 之间的差异



我有一个结构,这个结构的指针在main((中被mallocated,所以我可以制作一个结构的动态数组,我想使用这个函数填充数组:

void LoadData ( STRUCTURE ** str ){

所以我的问题是,当我使用这个概念时,为什么我的程序会抛出分段错误:

scanf( " %d", &str[i]->len ) 

当我使用时,一切都很好

scanf( " %d", &(*str)[i].len )

我认为(*str(.len相当于str->len。同样,这两种方法都适用于数组的第一个元素。提前谢谢。

正如您所描述的,在LoadData()函数中,str是指向标量的指针,而该标量恰好是另一个指针。因此,当i不同于0时,str[i]会产生越界数组访问,因为出于此目的,标量等效于单个元素数组。

另一方面,另一个指针*str指向数组的第一个元素。因此,假设该数组包含n元素,表达式(*str)[i]访问0和n - 1(包括0和10(之间的任何i的有效数组元素(类型为STRUCTURE(。因为它指定的是STRUCTURE,而不是STRUCTURE *,所以必须通过.运算符而不是通过->访问其成员。

为了更清楚地看到您的两个表达式是不同的,让我们根据身份a[b] == *((a) + (b))p->x == (*p).x对它们进行转换。一方面,我们有

&str[i]->len == &(str[i]->len)
== &((*str[i]).len)
== &((**(str + i)).len)

而另一方面我们有

&(*str)[i].len == &(((*str)[i])).len)
== &((*(*str + i)).len)

观察到**(str + i)并不等同于*(*str + i)

您正确地认为(*str(.len等同于str->len(对于结构指针str(。但是,数组索引和成员访问具有相同的优先级,并且保持关联。因此,您的第一个示例被解释为

scanf( " %d", &((str[i])->len) )

而你的第二个例子被解释为

scanf( " %d", &(((*str)[i]).len) )

对所有内容都使用具体索引,第一个版本是写入str[i][0].len,而第二个版本则是写入str[0][i].len。

最新更新