K&R "The C Programming Language" 第 2 版では、131 ページで次のように一連の変数が指定されています。
struct rect r, *rp = &r;
どこ :
struct rect {
struct point pt1;
struct point pt2;
};
と
struct point {
int x;
int y;
}
これらの 4 つの式は同等です。
r.p1.x
rp->pt1.x
(r.pt1).x
(rp->pt1).x
同じページの前半で、次のように表示されます。
p->member_of_structure
これは「特定のメンバーを指す」と記述されています。
マイナス記号と混同しないように、ハイフンをアンダースコアに変更しました。
構造体rectには構造体ポイントが含まれているため、ネストされた構造体と呼ばれるものがあることがわかります。
さて、pt1 と pt2 が両方とも構造体ポイントへのポインターであったような rect の定義は何ですか?
ここで、次のコードビットで問題が発生しました。
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を見ています.本の例には、構造体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
}
よく働く。明らかに、コーヒーが必要です。:-)