C99指向结构的指针,该结构包含指向结构的指针

时间:2013-03-12 22:08:45

标签: c pointers struct

K& R“The C Programming Language”第2版在第131页上给出了a 因此变量集:

struct rect r, *rp = &r;

其中:

struct rect {
    struct point pt1;
    struct point pt2;
};

struct point {
    int x;
    int y;
}

然后这四个表达式是等价的:

r.p1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x

在同一页面上,我们看到了这一点:

p->member_of_structure

被描述为“指特定成员”。

我将连字符更改为下划线,以确保我们不会混淆 一个减号。

太棒了,我可以看到我们将其称为嵌套结构,因为 struct rect包含一个struct point。

那么rect的定义是什么,pt1和pt2都是指针 到结构点?

这是我用以下代码位解决问题的地方:

typedef struct some_node {
    struct timespec *tv;
    struct some_node *next;
} some_node_t;

显然我会在这里制作链表,这没问题。

这是一个非常大的问题:

struct timespec some_tv;
clock_gettime( CLOCK_REALTIME, &some_tv )
/* set up the head node */
struct some_node *node_head =
                ( struct some_node * ) malloc( sizeof( some_node_t ) );
node_head->tv = calloc ( (size_t) 1, sizeof ( struct timespec ) );

一切都很好,我的node_head就好了。我甚至得到了我的嵌套 struct timespec node_head-> tv很好。

真正的问题是试图找出如何设置内部tv.sec some_tv.sec中的值,如下所示:

((struct timespec *)(*node_head.tv)).tv_sec = some_tv.tv_sec;

我收到错误:

line 22: error: left operand of "." must be struct/union object

所以我正在寻找K& R,我看到书中的例子没有 有一个指向struct rect中结构的指针。

我已经使用了反复试验来获得我想要的东西,但这令人抓狂。 我可以创建一个类型为“struct timespec temp”的临时变量然后 设置temp =& node_head.tv ...但是没有...那将无效。那就是 更糟糕的是我想。

我在这里缺少什么?

答案很简单,当然,只需使用foo-> bar-> here语法。

修改代码以删除malloc上的强制转换并使用正确的语法:

/* set up the node list */
struct some_node *node_head =
                calloc( (size_t) 1, sizeof( some_node_t ) );

node_head->tv = calloc ( (size_t) 1, sizeof ( struct timespec ) );
node_head->tv->tv_sec = some_tv.tv_sec;
node_head->tv->tv_nsec = some_tv.tv_nsec;
node_head->next = NULL;

调试器确认了这一点:

(dbx) print *node_head
*node_head = {
    tv      = 0x1001453e0
    next    = (nil)
}

(dbx) print *node_head.tv
*node_head->tv = {
    tv_sec  = 1363127096
    tv_nsec = 996499096
}

效果很好。显然,我需要咖啡。 : - )

5 个答案:

答案 0 :(得分:5)

这不够吗?

node_head->tv->tv_sec

答案 1 :(得分:2)

其他答案都有,但如果不清楚,->与自己使用*进行“取消引用”相同。

所以

 rp->pt1
 (*rp).pt1

是等价的。

这意味着你有经验法则“在处理指针时使用->”。

所以,如果你有,

node_head->tv->tv_sec

会做你想要的,相当于

(*node_head).tv->tv_sec
(*(*node_head).tv).tv_sec

答案 2 :(得分:0)

您应该将(*node_head.tv)更改为(*node_head).tv(或Oli写的node_head->tv),因为.的优先级高于*

答案 3 :(得分:0)

从您的开场示例中,如果您改为:

struct rect {
    struct point *pt1;
    struct point *pt2;
};

struct point {
    int x;
    int y;
};

你有

struct rect *rp;

然后访问x,您只需使用:

rp->pt1->x

编译器可以弄清楚发生了什么。如果你有无效指针等,你只需要进行投射。

答案 4 :(得分:0)

最初的评论:您(struct timespec *) tv的{​​{1}}演员表不是必需的,因为这已经是tv的声明。

正如其他人所说,您实际上只需要在此处使用ptr->field表示法:node_head->tv->tv_sec->符号是一种语法糖,以避免所有(*rp).(*pt1).x笨拙,否则将需要。

你问,

  

那么rect的定义是什么,pt1和pt2是这样的   两个指向结构点的指针?

在这种情况下,@ teppic的解决方案就是您想要的,但要记住的一个微妙之处在于分配数据结构的实际内存:在您的示例中,实际内存分配在rect,在@ teppic中,它是point。对于C的新手而言,这一点有时很棘手,尤其是在长时间运行的程序中多次分配和释放内存时(避免内存泄漏)。