编辑 - 使用2星指针更新以获得更多相关性
假设我有一个指向同时包含指针的结构的双星指针。
typedef struct{
nodeT *ptr;
}nodeT;
nodeT example;
nodeT *test1 = &example;
nodeT *test = &test1;
如果我想要结构中指针的地址,那么语法是什么? 我试过这个:
&(*test->ptr)
在一个想法中,将parethesis减少到实际指针,之后&运算符用于返回地址。
相反,我通过反复试验发现这是正确的语法:
&(*test)->ptr;
此外,我很困惑,为什么以下语法甚至无法取消引用指向结构指针的test
指针:
*test->ptr;
根据我的经验,如果没有*test
左右的括号,编译器会返回一条语句,通知我我正在尝试访问某些不是结构或联合的一部分。
它必须与分配给我不完全清楚的各种格式元素的优先级有关。
有什么想法吗?
答案 0 :(得分:4)
test->ptr
与(*test).ptr
所以,我认为你想要&(test->ptr)
(我不确定哪个运营商有更多优先权)。
答案 1 :(得分:3)
.
和->
组件选择运算符等后缀运算符的优先级高于一元*
和&
。因此,*foo->bar
将被解释为*(foo->bar)
; *
运算符将应用于foo->bar
的结果。同样,&bar.foo
将被解释为&(bar.foo)
。
因此,给出以下声明:
nodeT example;
nodeT *test1 = &example;
nodeT **test2 = &test1;
您将按如下方式访问ptr
成员:
example.ptr
- 子表达式example
的类型为nodeT
;不需要间接,因此我们只使用.
组件选择运算符; test1->ptr
- 子表达式test1
的类型为nodeT *
;有一个级别的间接,所以我们需要取消引用 test1
才能访问ptr
成员。我们通过使用->
运算符(隐式地引用test1
)来实现这一点,或者我们可以显式地取消引用test1
并编写(*test1).ptr
。 (*test2)->ptr
- 子表达式test2
的类型为nodeT **
;有两个级别的间接,因此我们需要取消引用test2
两次才能访问ptr
成员。如果我们想要使用->
运算符,或者我们取消引用它两次以使用.
运算符 - (**test2).ptr
,我们需要明确地取消引用它一次。 如果左侧操作数是.
或struct
类型,则使用union
组件选择运算符,例如example
或(*test1)
或{ {1}}。如果左侧操作数是指针到(**test2)
或->
类型,则使用struct
运算符,例如union
或{{ 1}}。
现在真正有趣 - test1
成员的类型为(*test2)
,因此如果您想获得ptr
指向的nodeT *
,您可以写{{ 1}}。子表达式ptr
的类型为example.ptr
,因此我们使用了example.ptr->ptr
组件选择运算符。但是,子表达式example
的类型为nodeT
,因此我们需要使用.
组件选择运算符。或者,我们必须写example.ptr
(请记住,nodeT *
被解析为->
)。
更进一步,我们可以写(*example.ptr).ptr
,或
*example.ptr
:
*(example.ptr)
由于example.ptr->ptr->ptr
已经是(*(*example.ptr).ptr).ptr
类型,所以更简单一点:
example.ptr
example.ptr->ptr
(*example.ptr).ptr
example.ptr->ptr->ptr
(*(*example.ptr).ptr).ptr
最后,test
:
nodeT *
答案 2 :(得分:1)
由于test
是一个指针,你无法使用.
运算符访问它的字段,你必须首先取消引用指针以直接获取结构:
*test
之后,您可以使用.
运算符访问该字段:
(*test).ptr
->
运算符是取消引用结构指针的快捷方式:
test->ptr
这将得到ptr变量,就像最后一个表达式一样。如果您想要它是ptr指向的地址,那么您就被设置了。
如果您想要ptr变量的地址,那么您需要使用&
来获取其地址:
(&test)->ptr
或
&(*test).ptr
答案 3 :(得分:1)
假设:
nodeT n0 = { 0 };
nodeT n1 = { &n0 };
nodeT *test = &n1;
您可以使用:
test // Pointer to n1
&test // Pointer to test itself
test->ptr // Pointer to n0
(*test).ptr // Same as test->ptr
&test->ptr // Pointer to the element of n1 (same as n1 because of the struct def'n
test->ptr->ptr // Pointer to null
等
例如:
#include <inttypes.h>
#include <stdio.h>
typedef struct nodeT nodeT;
struct nodeT { nodeT *ptr; };
static void print_addr(char * const tag, void *addr)
{
printf("%-15s = %p\n", tag, addr);
}
int main(void)
{
nodeT n0 = { 0 };
nodeT n1 = { &n0 };
nodeT *test = &n1;
print_addr("test", test);
print_addr("&test", &test);
print_addr("test->ptr", test->ptr);
print_addr("(*test).ptr", (*test).ptr);
print_addr("&test->ptr", &test->ptr);
print_addr("test->ptr->ptr", test->ptr->ptr);
return 0;
}
示例输出:
test = 0x7fff58829b10
&test = 0x7fff58829b20
test->ptr = 0x7fff58829b00
(*test).ptr = 0x7fff58829b00
&test->ptr = 0x7fff58829b10
test->ptr->ptr = 0x0