aは局所変数なので、初期値は全て不定である.
aは大域変数なので、0に初期化される.
bsortとswapがソートを行う関数、genがテストデータ生成、
printが出力関数である.
bsortは配列(の先頭要素へのポインタ)とその要素数を
引数とする. 詳しくは4章で学習するが、C言語では
配列全体をそのまま関数の引数や戻り値にすることはできない.
ソートのアルゴリズムは最も単純なバブルソートを使用しているが、 Nが1万でも数秒以内に終了するため実用上問題にならない. 31行目は乱数の系列を変えるおまじないである. これを忘れると関数randの戻り値が毎回同じ順序になるので、 実行結果が変わらない. 戻り値はint型なので、33行目で 値を1-100の範囲にするために剰余を使用している.
引数はchar *a[]であるから文字列の配列である. 文字列の配列は0で終端されている. while文では終端の 検出を行っている. a[i]はi番目の要素であるから、 これは文字列配列の各要素を順に出力する関数であり、 戻り値は配列の要素数である.
int foo(char **a) { char **s = a; while (*s) { printf("%s\n", *s++); } return (s-a); }
文字列配列の先頭アドレスは文字列への2重ポインタで表される.
解答3.4ではiを変化させることで要素を走査したが、
解答3.5では別の2重ポインタ変数sを使用する.
*sがa[i]に相当するように、whileの本体で
sを増加させる必要がある点に注意.
*s++はsを参照した後で値を1単位だけ増加させる.
すなわちポインタの大きさ分(4バイトまたは8バイト)
がsに加算され、次の要素を指すようになる.
要素の個数はsがaから何回増加されたかで決まる.
ポインタ同士の減算は間の要素の個数を返す.
すなわちs-aが要素の個数である.
解答3.4と解答3.5が同じ動作をするかは、 以下のようなプログラムで確認できる.
arg.c24行目を有効にしたプログラムと 25行目を有効にしたプログラムを別々に作成し、結果を比較する. #ifdefとmakeを使用して両方を自動的に作成することもできる.
解答3.7のみ示す. 0か1のみを返すように変更すれば解答3.6になる.
strcon.c外側のforループでs2の各文字についてs1の先頭文字と一致するかを判定し、 一致する文字があればその位置(i2)を基準にして、 内側のforループでs1全体について一致を判定している. すなわちs1[i1]が0(文字列終端)に達するまでs1[i1]とs2[i2+i1]以降が すべて一致すれば(13行目)、s1がs2に含まれることになる. 一致しなければi2を変更してこれを繰り返す.