前回は、構造体タグ名を使わずに定義する場合が多いことを取り上げました
(参照: よく使う構造体宣言の形)。
しかし、構造体タグ名を書かなければならないときもあります。
構造体をポインタでつないで、リスト構造やツリー構造にする場合です。
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(今回のクイズです)
[ 関連記事 ] 宣言:構造体宣言
構造体配列:読み込み, 関数操作, ソート, ポインタソート
構造体へのポインタ,
リスト構造,
構造体を関数の戻り値に
[ ご案内 ] 構造体の要点を学習できるコース:要点講座 [ 構造体編 ]
//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} };