• 検索結果がありません。

連結リスト

ドキュメント内 ÆþÌçGTK+ (ページ 68-73)

第 4 章 GLib 49

4.3 連結リスト

g build filename

引数に与えた文字列をファイル名用の区切り文字(例えば/)で結合して,1つの文字列を作成します.引数の最後は NULLで終わる必要があります.

g c h a r* g _ b u i l d _ f i l e n a m e (c o n s t g c h a r * f i r s t _ e l e m e n t , . . . ) ; 第1引数以降 文字列.

戻り値 生成されたパス.

const gchar *dirname = "/home/gtk";

const gchar *basename = "sample.c";

gchar *filename;

filename = g_build_filename (dirname, basename, NULL);

g_print ("filename = %s\n", filename);

g_free (filename);

g list delete link

リストから指定した位置のノードを削除する関数です.リストのデータが動的に領域を確保したものである場合には,こ の関数を呼び出す前に,削除するノードのデータ領域を解放しておく必要があります.

G L i s t* g _ l i s t _ d e l e t e _ l i n k (G L i s t * l i s t , G L i s t * l i n k _ ) ; 第1引数 リスト.

第2引数 削除するノードの先頭アドレス.

戻り値 リストの先頭アドレス.

g list free

リストを解放する関数です.リストのデータが動的に領域を確保したものである場合には,この関数を呼び出す前に,そ れらの領域を解放しておく必要があります.

v o i d g _ l i s t _ f r e e (G L i s t * l i s t ) ; 第1引数 リスト.

g list foreach

リストの各ノードに対して関数funcを実行する関数です.

v o i d g _ l i s t _ f o r e a c h (G L i s t * l i s t , G F u n c f u n c , g p o i n t e r u s e r _ d a t a ) ; 第1引数 リスト.

第2引数 ノードに対して適用する関数.

第3引数 第2引数の関数の引数に与えるデータ.

GFuncは次のように定義されています.この関数の第1引数にはリストのデータが渡されます.第2引数には,関数

g list foreachの第3引数に指定した変数が渡されます.

v o i d ( *G F u n c) (g p o i n t e r d a t a , g p o i n t e r u s e r _ d a t a ) ;

g list length

リストの長さを返す関数です.

g u i n t g _ l i s t _ l e n g t h (G L i s t * l i s t ) ; 第1引数 リスト.

戻り値 リストの長さ.

g list first

リストの先頭のノードを返す関数です.

G L i s t* g _ l i s t _ f i r s t (G L i s t * l i s t ) ; 第1引数 リスト.

戻り値 先頭ノードのアドレス.

g list last

リストの末尾のノードを返す関数です.

G L i s t* g _ l i s t _ l a s t (G L i s t * l i s t ) ; 第1引数 リスト.

戻り値 末尾ノードのアドレス.

g list previous

現在のノードの前のノードを返します.

# d e f i n e g _ l i s t _ p r e v i o u s ( l i s t ) \

( ( l i s t ) ? ( ( (G L i s t * ) ( l i s t ) ) - >p r e v ) : N U L L ) 第1引数 リスト.

戻り値 前のノードのアドレス.

g list next

現在のノードの次のノードを返します.

# d e f i n e g _ l i s t _ n e x t ( l i s t ) ( ( l i s t ) ? ( ( (G L i s t * ) ( l i s t ) ) - >n e x t ) : N U L L ) 第1引数 リスト.

戻り値 次のノードのアドレス.

g list nth

n番目のノードを返します.

G L i s t* g _ l i s t _ n t h (G L i s t * l i s t , g u i n t n ) ; 第1引数 リスト.

第2引数 ノード番号.

戻り値 指定したノードのアドレス.

g list nth data

n番目のリストのデータを返します.

g p o i n t e r g _ l i s t _ n t h _ d a t a (G L i s t * l i s t , g u i n t n ) ; 第1引数 リスト.

第2引数 ノード番号.

戻り値 指定したノードのデータ.

g list sort

ノードをcompare funcに従ってソートする関数です.

G L i s t* g _ l i s t _ s o r t (G L i s t * l i s t , G C o m p a r e F u n c c o m p a r e _ f u n c ) ; 第1引数 リスト.

第2引数 ソート関数.

戻り値 ソートされたリストの先頭アドレス.

ノードをソートする関数GCompareFuncは次のように定義された関数です.

g i n t ( *G C o m p a r e F u n c) (g c o n s t p o i n t e r a , g c o n s t p o i n t e r b ) ;

4.3.2 リスト操作の例 : ソート

ここでGListを用いたリスト操作の例を見てみましょう.ソース4–2は“January”から“December”までの文字列をデータ

に持つリストを作成し,文字列を昇順にソートして表示するものです.実行結果を以下に示します.ソート後の表示を見ると,

文字列が辞書順にソートされているのがわかります.

$ gcc list-sort.c -o list-sort ‘pkg-config --cflags --libs glib-2.0‘

$ ./list-sort

January February March April May June July August September October November December April August December February January July June March May November October September

変数の初期化(18–21行目)

GList型の変数は最初に関数g list appendを呼び出すときのためにNULLに初期化しておきます.変数dataはリスト用の

文字列データです.

リストの作成(24–27行目)

関数g list appendを用いて,リストを作成します.基本的に関数の第1引数に与えた変数に関数の戻り値を代入してリスト

を作成していきます.

初期リストの表示(28–31行目)

関数g list nth dataを用いて,リストのn番目のデータを順に取得し,表示します.

リストのソート(34行目)

関数g list sortを用いて,リストのデータを昇順にソートします.データのソートには単純に関数strcmpを使用します.

リストの表示(35行目)

関数g list foreachを用いて,昇順にソートされたリストのデータを表示します.先ほどはfor文を使ってリストのすべての

データにアクセスしましたが,ここではそれを関数g list foreachで代用しました.

リストの解放(38行目)

最後に関数g list freeにより,リストの領域を解放します.

ソース4–2 リストのソート: list-sort.c

1 # i n c l u d e <g l i b . h >

2

3 s t a t i c g i n t

4 c o m p a r e _ f u n c t i o n (g c o n s t p o i n t e r a , g c o n s t p o i n t e r b )

5 {

6 r e t u r n s t r c m p ( (g c h a r * ) a , (g c h a r * ) b ) ;

7 }

8

9 s t a t i c v o i d

10 p r i n t _ d a t a (g p o i n t e r da t a , g p o i n t e r u s e r _ d a t a )

11 {

12 g _ p r i n t ( " % s " , (g c h a r * ) d a t a ) ;

13 }

14 15 i n t

16 m a i n (i n t a r g c , c h a r * a r g v [ ] )

17 {

18 G L i s t * l i s t = N U L L ;

19 g c h a r * d a t a [ ] = { " J a n u a r y " , " F e b r u a r y " , " M a r c h " , " A p r i l " , " M a y " ,

20 " J u n e " , " J u l y " , " A u g u s t " , " S e p t e m b e r " , " O c t o b e r " ,

21 " N o v e m b e r " , " D e c e m b e r " } ;

22 i n t n ;

23

24 f o r ( n = 0 ; n < 1 2 ; n + + )

25 {

26 l i s t = g _ l i s t _ a p p e n d ( l i s t , (g p o i n t e r) d a t a [ n ] ) ;

27 }

28 f o r ( n = 0 ; n < 1 2 ; n + + )

29 {

30 g _ p r i n t ( " % s " , (g c h a r * ) g _ l i s t _ n t h _ d a t a ( l i s t , n ) ) ;

31 }

32 g _ p r i n t ( " \ n " ) ;

33

34 l i s t = g _ l i s t _ s o r t ( l i s t , c o m p a r e _ f u n c t i o n ) ;

35 g _ l i s t _ f o r e a c h ( l i s t , (G F u n c) p r i n t _ d a t a , N U L L ) ;

36 g _ p r i n t ( " \ n " ) ;

37

38 g _ l i s t _ f r e e ( l i s t ) ;

39

40 r e t u r n 0 ;

41 }

4.3.3 リスト操作の例 : データの追加・削除

先の例では,リストの生成とソートを扱いました.次の例では,データの追加と削除の例を見てみましょう(ソース4–3).こ の例では,データの追加(挿入)に関数g list insertを,データの削除に関数g list delete linkを使用しています.

初期リストの作成(10–13行目)

はじめに,January,February,Aprilの文字列をデータに持つリストを作成します.先ほどの例とは違い,文字列を関数

g strdupを使ってコピーして,それをデータとして使用します.

リストの挿入(20行目)

2番目と3番目のノードの間に新しいデータMarchを持つノードを挿入します.

リストの削除(27–28行目)

このリストは関数g strdupで動的に確保したメモリ領域をデータとして使用しているので,ノードを削除する前に,関数

g freeにより領域を解放します.4番目(添字は3)のノードのデータを取得するには,関数g list nth dataを使います.削除

するノードは関数g list nthを使って取得します.

リストの解放(35–36行目)

リストデータは動的に確保したメモリ領域を使用していたので,関数g list freeを使用する前に,関数g list foreachを使っ て各データ領域を関数g freeで解放しています.

$ gcc list-operation.c -o list-operation ‘pkg-config --cflags --libs glib-2.0‘

$ ./list-operation January February April January February March April January February March

ソース4–3 リストの追加・削除: list-operation.c

1 # i n c l u d e <g l i b . h >

2 3 i n t

4 m a i n (i n t ar g c , c h a r * a r g v [ ] )

5 {

6 G L i s t * l i s t = N U L L , * w o r k ;

7 g c h a r * d a t a [ ] = { " J a n u a r y " , " F e b r u a r y " , " A p r i l " } ;

8 i n t n ;

9

10 f o r ( n = 0 ; n < 3 ; n + + )

11 {

12 l i s t = g _ l i s t _ a p p e n d ( l i s t , (g p o i n t e r) g _ s t r d u p ( d a t a [ n ] ) ) ;

13 }

14 f o r ( w o r k = l i s t ; w o r k ; w o r k = g _ l i s t _ n e x t ( w o r k ) )

15 {

16 g _ p r i n t ( " % s " , (g c h a r * ) w o r k - >d a t a ) ;

17 }

18 g _ p r i n t ( " \ n " ) ;

19

20 l i s t = g _ l i s t _ i n s e r t ( l i s t , (g p o i n t e r) g _ s t r d u p ( " M a r c h " ) , 2 ) ;

21 f o r ( w o r k = l i s t ; w o r k ; w o r k = g _ l i s t _ n e x t ( w o r k ) )

22 {

23 g _ p r i n t ( " % s " , (g c h a r * ) w o r k - >d a t a ) ;

24 }

25 g _ p r i n t ( " \ n " ) ;

26

27 g _ f r e e ( g _ l i s t _ n t h _ d a t a ( l i s t , 3 ) ) ;

28 l i s t = g _ l i s t _ d e l e t e _ l i n k ( l i s t , g _ l i s t _ n t h ( l i s t , 3 ) ) ;

29 f o r ( w o r k = l i s t ; w o r k ; w o r k = g _ l i s t _ n e x t ( w o r k ) )

30 {

31 g _ p r i n t ( " % s " , (g c h a r * ) w o r k - >d a t a ) ;

32 }

33 g _ p r i n t ( " \ n " ) ;

34

35 g _ l i s t _ f o r e a c h ( l i s t , (G F u n c) g _ f r e e , N U L L ) ;

36 g _ l i s t _ f r e e ( l i s t ) ;

37

38 r e t u r n 0 ;

39 }

ドキュメント内 ÆþÌçGTK+ (ページ 68-73)