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

連結リスト

ドキュメント内 表紙 (ページ 50-55)

第 3 章 GLib 31

3.3 連結リスト

3.2.4 その他の便利な関数

g get home dir

ユーザのホームディレクトリを取得する関数です.

G _ C O N S T _ R E T U R N g c h a r* g _ g e t _ h o m e _ d i r (v o i d) ;

g get current dir

現在のディレクトリを取得する関数です.

g c h a r* g _ g e t _ c u r r e n t _ d i r (v o i d) ;

g path get basename

パスから最後のファイル名を返します. パスがディレクトリを指す場合には最後のディレクトリ名を返 します.

g c h a r* g _ p a t h _ g e t _ b a s e n a m e (c o n s t g c h a r * f i l e _ n a m e ) ;

g path get dirname

パスから最後のファイル名を取り除いたディレクトリ部分を返します. g c h a r* g _ p a t h _ g e t _ d i r n a m e (c o n s t g c h a r * f i l e _ n a m e ) ;

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 , . . . ) ;

リストにデータを追加する関数です. 引数listにNULLを与えると新しいリストを作成してデータを追 加します.

G L i s t* g _ l i s t _ a p p e n d (G L i s t * l i s t , g p o i n t e r d a t a ) ;

g list insert

指定した位置にデータを挿入する関数です. 指定した位置がリストの範囲内にない場合にはリストの最 後尾にデータを追加します.

G L i s t* g _ l i s t _ i n s e r t (G L i s t * l i s t , g p o i n t e r d a t a , g i n t p o s i t i o n ) ;

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 _ ) ;

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 ) ;

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 ) ;

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 ) ;

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 ) ;

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 ) ;

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 )

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 )

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 ) ;

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 ) ;

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 ) ;

ノードをソートするための関数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 ) ;

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

ここでGListを用いたリスト操作の例を見てみましょう. ソース3–3は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

変数の初期化(14–16行目)

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

dataはリスト用の文字列データです.

リストの作成(19行目)

関数g list appendを用いて,リストを作成します.

初期リストの表示(20–23行目)

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

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

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

リストの表示(26行目)

関数g list foreachを用いて,昇順にソートされたリストのデータを表示します. 先ほどはfor文を使ってリ ストの全てのデータにアクセスしましたが,ここではそれを関数g list foreachで代用しました.

リストの解放(29行目)

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

ソース 3–3 リストのソート: list sort.c

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

2

3 g i n t 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 ) {

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

5 }

6

7 v o i d p r i n t _ d a t a (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 ) {

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

9 }

10

11 i n t m a i n (i n t ar g c ,

12 c h a r * a r g v [ ] ) {

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

14 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 " , " J u n e " ,

15 " 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 " , " N o v e m b e r " ,

16 " D e c e m b e r " } ;

17 i n t n ;

18

19 f o r ( n = 0 ; n < 1 2 ; n + + ) 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 ] ) ;

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

21 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 ) ) ;

22 }

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

24

25 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 ) ;

26 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 ) ;

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

28

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

30

31 r e t u r n 0 ;

32 }

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

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

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

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

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

リストの挿入(16行目)

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

リストの削除(22–23行目)

このリストは関数g strdupで動的に確保したメモリ領域をデータとして使用していますので, ノードを削 除する前に, 関数g freeにより領域を解放します. 4番目(添字は3)のノードのデータを取得するには,関数 g list nth dataを使います. 削除するノードは関数g list nthを使って取得します.

リストの解放(29–30行目)

リストデータは動的に確保したメモリ領域を使用していましたので, 関数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

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

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

2

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

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

5 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 " } ;

6 i n t n ;

7

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

9 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 ] ) ) ;

10 }

11 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 ) ) {

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

13 }

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

15

16 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 ) ;

17 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 ) ) {

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

19 }

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

21

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

23 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 ) ) ;

24 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 ) ) {

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

26 }

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

28

29 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 ) ;

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

31

32 r e t u r n 0 ;

33 }

ドキュメント内 表紙 (ページ 50-55)