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
}
效果很好。显然,我需要咖啡。 : - )
答案 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的新手而言,这一点有时很棘手,尤其是在长时间运行的程序中多次分配和释放内存时(避免内存泄漏)。