2

编辑 - 用 2 星指针更新以获得更多相关性

假设我有一个指向一个结构的两星指针,该结构也包含一个指针。

typedef struct{
    nodeT *ptr;
}nodeT; 

nodeT example; 
nodeT *test1 = &example;
nodeT *test = &test1; 

如果我想要结构中指针的地址,语法是什么?我试过这个:

&(*test->ptr)

有人认为括号将减少为实际指针,然后使用 & 运算符返回地址。

相反,我通过反复试验发现这是正确的语法:

&(*test)->ptr;

此外,我很困惑为什么下面的语法甚至不能取消test对结构指针的引用:

*test->ptr;

根据我的经验,如果没有围绕*test编译器的括号,则返回一条语句,通知我我正在尝试访问不属于结构或联合的内容。

它必须与分配给我不完全了解的各种格式元素的优先级有关。

有任何想法吗?

4

4 回答 4

4

test->ptr是一样的(*test).ptr

所以,我认为你想要&(test->ptr)(我不确定哪个运营商具有更高的优先级)。

于 2013-10-29T17:32:40.620 回答
3

后缀运算符(如.->组件选择运算符)的优先级高于一元*&。因此,*foo->bar将被解释为*(foo->bar);运算符*将应用于foo->bar. 同样,&bar.foo将被解释为&(bar.foo)

因此,给定以下声明:

nodeT example;
nodeT *test1 = &example;
nodeT **test2 = &test1;

ptr您将按如下方式访问该成员:

  1. example.ptr- 子表达式example的类型为nodeT; 不需要间接,因此我们只需使用.组件选择运算符;
  2. test1->ptr- 子表达式test1的类型为nodeT *; 有一层间接,所以我们需要在访问成员之前取消引用。 我们可以通过使用运算符(隐式地引用)来做到这一点,或者我们可以显式地取消引用自己并编写. test1ptr->test1test1(*test1).ptr
  3. (*test2)->ptr- 子表达式test2的类型为nodeT **; 有两个间接级别,所以我们需要取消引用test2 两次才能访问该ptr成员。如果我们想使用->操作符,我们需要显式地取消引用它一次,或者我们取消引用它两次以使用.操作符 - (**test2).ptr

.如果左侧操作数是structorunion类型,例如exampleor(*test1)或,则使用组件选择运算符(**test2)->如果左侧操作数是指向astructunion类型的指针,例如test1or ,则使用运算符(*test2)

现在为了真正的乐趣 -ptr成员有类型nodeT *,所以如果你想得到ptr那个example.ptr指向,你会写example.ptr->ptr。子表达式example具有 type nodeT,因此我们使用了.组件选择运算符。然而 subexpressionexample.ptr有 type 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已经是 type nodeT *,所以它更简单一些:

test1->ptr
(*test1).ptr
test1->ptr->ptr
(*(*test).ptr).ptr
test1->ptr->ptr->ptr
(*(*(*test1).ptr).ptr).ptr

最后,test2

(*test2)->ptr
(**test2).ptr
(*test2)->ptr->ptr
(*(**test2).ptr).ptr
(*test2)->ptr->ptr->ptr
(*(*(**test2).ptr).ptr).ptr
于 2013-10-29T19:03:05.387 回答
1

由于test是指针,因此您无法使用.运算符访问它的字段,您必须首先取消引用指针才能直接获取结构:

*test

之后,您可以使用.运算符访问该字段:

(*test).ptr

->运算符是取消引用结构指针的快捷方式:

test->ptr

这将获得 ptr 变量,就像最后一个表达式一样。如果你想要ptr指向的地址,那么你就设置好了。

如果您想要 ptr 变量的地址,则需要使用以下命令获取其地址&

(&test)->ptr

或者

&(*test).ptr

于 2013-10-29T17:40:26.097 回答
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
于 2013-10-29T17:46:09.790 回答