Thinkers'Studio
JavaとC言語の自習ツール
構造体タグ名が必要なケース

 前回は、構造体タグ名を使わずに定義する場合が多いことを取り上げました (参照: よく使う構造体宣言の形)。
 しかし、構造体タグ名を書かなければならないときもあります。
 構造体ポインタでつないで、リスト構造やツリー構造にする場合です。

 自分と同じ形の構造体へのポインタ(ここでは p)をメンバに含めるには、「構造体タグ名」を使う必要があります。
struct 構造体タグ名 {
    (他のメンバ変数の宣言)
    struct 構造体タグ名  *p; //自身と同じ構造体を指すポインタ
};
 構造体定義と同時に typedef する場合も、自己参照するポインタは「構造体タグ名」で書きます。下に例を示します。

リスト構造のプログラム例 】
 構造体のタグ名 list と、typedef したデータ型名 LIST の両方を使う例です。 まずコードを見てください。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct list {
    int n;
    char name[24];
    struct list *next; //もしも LIST *next; と書いたらどうなる?
} LIST;

LIST *mkEntry( int n, char *s )
{
    LIST *p = (LIST*)malloc( sizeof(LIST) );
    if( p == NULL ) exit( 1 );
    p->n = n;
    strcpy( p->name, s );
    p->next = NULL;
    return p;
}
main()
{
    LIST *p1, *p2, *p3, *x;

    p1 = mkEntry( 0, "Kyoto" );
    p2 = mkEntry( 1, "Osaka" );
    p3 = mkEntry( 2, "Kobe" );
    p1->next = p2;
    p2->next = p3;
    for( x = p1; x != NULL; x = x->next )
        printf( "%d : %s\n", x->n, x->name );
}
 mkEntry( ) で構造体 LIST型のデータエントリを 3つ作り、ポインタnext が次のエントリを指すようにしてつないでいます。
 その後、ポインタをたどりながら各構造体データをプリントします。実行結果は次の通りです。
0 : Kyoto
1 : Osaka
2 : Kobe
(今回のクイズです)
 上の青文字コメントのように、「データ型名」で自己参照のポインタを定義した場合、ちゃんと実行できるでしょうか?
 理由も考えましょう。
   (答えは、次回のC言語の Tips で ・・・)

[ 関連記事 ] 宣言:構造体宣言  構造体配列:読み込み, 関数操作, ソート, ポインタソート
        構造体へのポインタ, リスト構造, 構造体を関数の戻り値に
[ ご案内 ] 構造体の要点を学習できるコース:要点講座 [ 構造体編 ]

前回のクイズの答え: 次の3箇所を書き換える (前回の問題を見る
//1箇所目は構造体定義
typedef struct { //座標データの構造体
    double x;    //x座標
    double y;    //y座標
} POINT;
//2箇所目は関数checkPrintの引数の型
void checkPrint( POINT *p )
//3箇所目は、main関数のpnts配列の宣言
POINT pnts[NUMPOINTS] = { {0.1, 0.5}, {0.1, 1.0}, {1.5, 2.0} };