[英]Pointer to an array of structure in C
我要求使用指向如下定义的结构数组的指针:
typedef void (*fptr)(uint8 arg);
typedef struct sTest
{
uint8 u8Mem1;
uint8 u8Mem2;
fptr fptr1;
}tTest;
现在,我定义了此结构的数组,如下所示:
tTest sTestStructure[20];
因此,现在我想定义一个指针,并将stuct {sTestStructure [20]}数组分配给该指针。然后使用指针定义访问此结构的成员。 因此,请让我知道如何定义该指针以及如何使用指针访问成员。
请记住,除非它是sizeof
或一元&
运算符的操作数,或者是用于在声明中初始化字符数组的字符串文字,否则类型为“ T
N元素数组”( T [N]
)的表达式将是转换(“衰减”)为类型“指向T
指针”( T *
)的表达式,该表达式的值将为数组第一个元素的地址。
这自然导致我们得出以下结论:
tTest *ptr = sTestStructure; // note no & operator!
表达式 sTestStructure
隐式地从类型“ tTest
20个元素的数组”转换为“指向tTest
指针”,并且表达式的值与&sTestStructure[0]
。 要访问sTestStructure
任何元素,您可以像sTestStructure
一样简单地索引到ptr
中:
ptr[i].u8Mem1 = some_value; // sTestStructure[i].u8Mem1 = some_value
printf( "%" PRIu8 "\n", ptr[j].u8Mem2 );
请记住,下标运算a[i]
定义为*(a + i)
; 给定地址a
,从该地址偏移i
元素 ,并取消引用结果。 因此, []
运算符隐式取消引用ptr
,这就是为什么我们使用.
原因.
操作员访问每个结构成员。
或者,您也可以使用->
运算符访问结构成员,并根据需要推进指针:
tTest *ptr = sTestStructure;
while( ptr->u8Mem1 != some_value ) // no subscript operation here
ptr++;
表达式ptr->u8Mem1
等效于(*ptr).u8Mem1
1 ,等效于ptr[0].u8Mem1
。
那么,如果我们决定改用&sTestStructure
会发生什么呢? 由于sTestStructure
是一元&
运算符的操作数,因此上面的转换规则不适用; 而不是获得指向tTest
的指针,我们得到了一个指向20个元素的tTest
数组的tTest
,或者:
tTest (*arrPtr)[20] = &sTestStructure;
这带来了更多的挑战,因为我们必须先取消引用arrPtr
才能对其进行索引:
(*arrPtr)[i].u8Mem1 = some_value;
printf( "%" PRIu8 "\n", (*arrPtr)[j].u8Mem2 );
因为a[i]
被定义为*(a + i)
,所以表达式*arrPtr
也可以写为arrPtr[0]
( *arrPtr == *(arrPtr + 0) == arrPtr[0]
)。 所以这些行也可以写成
arrPtr[0][i].u8Mem1 = some_value;
printf( "%" PRIu8 "\n", arrPtr[0][j].u8Mem2 );
从最后两行中可以明显看出,除非要处理多维数组,否则通常不会看到这种形式的数组指针。 还记得我们的转换规则吗,其中类型T [N]
的表达式转换为类型T *
的表达式? 好吧,用Q[M]
类的数组类型替换T
,我们得到从“ Q
的M元素数组的N元素数组”( Q [N][M]
)到“指向M元素数组的指针”的转换的Q
“( Q (*)[M]
):
tTest sTestStructure[10][20];
tTest (*arrPtr)[20] = sTestStructure;
.
具有比一元*
高的优先级,因此*ptr.u8Mem1
将被解析为*(ptr.u8Mem1)
,这不是您想要的。 他们已经告诉您如何定义指针,现在,如果您要访问属性,将是* pointer-> property .....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.