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

时间:2018-12-04 23:01:27

标签: c arrays function pointers

我有一个结构,在main()中分配了该结构的指针,因此我可以创建一个动态的结构数组,并且想使用此函数填充该数组:

void LoadData ( STRUCTURE ** str ){

所以我的问题是为什么当我使用此概念时,我的程序为什么会引发分段错误:

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

当我使用这个时一切都很好:

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

我认为(* str).len等同于str-> len。 两者都适用于数组的第一个元素。预先感谢。

2 个答案:

答案 0 :(得分:3)

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

另一方面,另一个指针*str指向数组的第一个元素。假设该数组包含n个元素,因此,表达式(*str)[i]为0到STRUCTURE之间的任何i访问一个有效的数组元素(类型为n - 1) , 包括的。因为那是指定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)

答案 1 :(得分:2)

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

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

第二个示例解释为

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

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