第49回 プログラミングについて『C言語の文字列』

C言語を初めて使ったときに面食らったことに文字列があります。慣れてしまえばなんでもないことなのですが、FORTRANにあまりにも毒されていた私にとっては最初は非常に扱いにくいものでした。
誰でも知っていることなのですがC言語の文字列は配列の扱いです。基本的に文字列というものは、文字の連続したものですから配列には違いないのですが、この言語の場合は配列そのもので、文字の配列として扱うことになっています。言ってしまえば1バイトの型の変数の配列に単純に文字を1つづつ代入しているもので、末尾を示すためにヌルを使用しているだけなので、C言語では本来は文字列を扱う特別な型の変数などはないと考えられます。要するにC言語の基本的な型は、実数型、整数型の2つの型しかなく、その整数型の中で1バイトの型のものは文字を代入して使用することが多いのでchar などと文字型が特別に存在するような宣言をするようになっているのです。
もっともFORTRAN77が制定される前のFORTRANも同じような事情で、整数の変数に文字を代入していました。例えば、
INTEGER I(2)
I(1)='ABCD'
I(2)='EFGH'
WRITE(6,'(1H,2A)')I
END
などとして扱っていました。FORTRANはご存知のように数値を計算するのが得意な言語でしたので文字に関する操作は殆どサポートされておらず、このような力仕事が必要でした。この当時は世の中にパソコンなどというものは存在せず、あったとしても現在のものと比較すれば情けない程に非力なものでしたので、CADソフトなどは汎用機やミニコンで苦心惨澹の末に作り上げていたようです。実際にFORTRAN77以前の使用で書かれた古いCADソフトのソースを見たことがありますが、この事情が理解できるまではチンプンカンプンだったのを覚えています。
FORTRANではこのような文字列の操作に対する不都合から、FORTRAN77では文字型がサポートされるようになりました。FORTRAN77の文字型はC言語とは違い1バイトの変数を単純に配列にしたものではなく、その型とは独立した別の型として文字型が使用できるようになったのです。このFORTRANの文字変数は言語としてサポートされていますので、
CHARACTER TEXT*10
TEXT='12345678901234567890'
と記述しても10バイトの長さの変数に11バイト以上の文字は代入することはできないので、C言語のように配列のサイズを越えて他の値を破壊するようなことはないのです。また文字の連結や部分文字列の参照などはいたって簡単で、
CHARACTER S1*10,S2*10,S3*20
S1='1234567890'
S2='ABCDEFGHIJ'
S3=S1//S2 !連結
PRINT *,S3
PRINT *,S3(5:15) !部分文字列
END
数式と同様な扱いで操作することができるのです。また文字列の末端を示すためにC言語のようなヌル文字を挿入する必要もありませんので10バイトの文字変数には10文字を代入することができるのです。その上、文字変数にバイナリの値を代入しておいてそのままWRITE文でファイルに出力したりすることも問題なくできますので、文字変数に様々な値を代入して構造体代わりに使用することもよく行なった手法でした。
C言語では先にも述べましたが、基本の型は実数と整数しかありません。言語の仕様自体も文字列を操作することについては殆どありません(文字定数の末尾にはヌル文字が挿入されるとかいった類)。また文字列もポインタと配列のごく単純な約束事に従って操作することになります。
そのC言語のポインタと配列の基本的な約束事とは、配列の名称はポインタであるということです。ですので文字列の定数は配列ですので、文字型のポインタとなります。だからといって、
char a[10];
a="abcde";
と記述することはできません。この例では a は配列の名称ですのでポインタとなるのですが、右辺値と左辺値の規定があるのでコンパイラに叱られてしまいます。
char *a;
a="abcde";
のようにすれば問題はありません。
文字列の連結も、
char *a;
a="abcde"+"12345";
などとすることもできません。これは右辺がポインタとポインタの加算になる訳で、実質的にポインタにポインタを加算することはありえないことですのでこれもコンパイラに叱られてしまいます。
FORTRANのように部分文字列も使用できませんので、文字変数 A の3~5文字と、B の8~10文字を連結して文字変数 C に代入するとき、FORTRANでは、
C=A(3:5)//B(8:10)
と記述できるのに、C言語ではこのように記述することはできません。
とにもかくにもCの国の文字列はFORTRANの国からやって人には面倒なものなのでした。
あまり文句ばかり言っているとC言語を嫌いになってしまう方がいるかも知れませんのでこれくらいにしましょう。あくまでも慣れの問題で、慣れてしまえば別に不自由ではありません。
C言語は高級言語の中のアッセンブラと呼ばれることもあるくらいに、低レベルでのデータの操作ができるように設計された言語です。無駄な機能は極力捨て去ることでコンパクトで柔軟性のあるコードを記述できるようにしたものですので、OSの記述も一般のアプリケーションの記述も可能なのです。UNIXにしてもその誕生のときにはアッセンブラだったものがC言語に書き換えられ、最新のWindowsNTもこの言語で記述されているのです。
でも... やっぱり文字列の操作がもう少し楽になるようにしてくれればよかったのにと思うのは自分だけなのでしょうか...
ではまた次回。