第2章の3 文字と文字列

1. 文字データとは

人間「A」という文字データを表すのに ‘A’ と記述する
コンピュータは ‘A’ という記述を 65 というコードで扱う

つまり、’A’ と 65 は等しいのです。 この ‘A’ に対応する 65 というコードを「ASCIIコード」と言い、ASCIIコードを表にしたものを「ASCIIコード表」と言います。

文字コードにはたくさんの種類が存在しますが、コンピュータ用の英数字のコードとして最も広く用いられているのはASCIIコードです。このサイトでも、文字コードはASCIIコードを基に記述してあります。

char型を何故「文字型」と呼ぶのでしょう。
char型は 整数を扱う型ですが、整数を扱うにもかかわらず、「文字型」と呼ばれています。
これは、アルファベットや数字、記号などの半角文字が1バイトで表現可能なためです。(漢字など全角の文字は2バイトで扱い、この限りではありません。)

2. 文字データと文字列データ

C言語では、文字データと文字列データとは以下のように区別されます。

(1) 文字

  • メモリ上の1バイトに格納される。
  • ‘ ‘(一重引用符)で囲む。
char ch1 = 'A';
char ch2 = 'B';

(2) 文字列

  • メモリ上の複数バイトに格納され、終了コードとして、‘\0’ が最後につく。
  • 文字列は、文字型配列で宣言して扱う。
  • ” “(二重引用符)で囲む。
char str[] = "ABC";
// 省略しない場合は4以上の要素数を記述

(3) 文字列データの初期化

  1. { } を使って初期化リストを書いてやる。(一般の配列と同様)
    この場合、文字列終了コードの’\0’(コード:0)が必要。
char str[10] = { 'H','E','L','L','O','\0' };  // '\0'(コード:0)を忘れないように注意
  1. ” ” を使って、文字列専用の初期化を行う。
    この場合、終了コードの’\0’はコンパイラが自動的につける
char str[10] = "HELLO";
  • 1, 2 とも要素数は省略可
    ただし、要素数が省略できるのは、初期化データを宣言しているときのみです。
    単に
    char str[];
    とすると、コンパイラは配列の大きさがわからず、エラーを出します。
  • 文字列データの初期化は上記 1、2 のどちらを用いてもかまいませんが、2 を用いた方が簡単です。

(4) 文字と文字列宣言時の注意

【注意1】

char str[] = 'A';  …(1)
char str = "A";    …(2)

コンパイル時に(1)はエラーとなり、(2)はエラーもしくは警告を出力します。

【注意2】

char str[] = "A";

は文法上正しく、正常に動作します。このときメモリ上に2バイト分のエリアが確保され、文字列として扱われます。

【注意3】

char str[] = "";

のようにすると、下記のように中身が ‘\0’ のみの文字列を宣言することができます。
これは、文字列の連結などのときに用いると便利です。(ただし、文字列連結時には、配列は十分な大きさを確保してください。)

文字列の扱い方 サンプルプログラム

#include <stdio.h>

int main(void)
{
    char str1[128];                          // 文字列 str1 を宣言
    char str2[10] = {'A', 'B', 'C', '\0'};   // 文字列 str2 を宣言後初期化
    char str3[] = {'a', 'b', 'c', '\0'};     // 文字列 str3 を宣言後初期化
    char str4[10] = "computer";              // 文字列 str4 を宣言後初期化
    char str5[] = "hello";                   // 文字列 str5 を宣言後初期化

    printf("str1 = %s\n", str1);     // 文字列の出力
    printf("str2 = %s\n", str2);
    printf("str3 = %s\n", str3);
    printf("str4 = %s\n", str4);
    printf("str5 = %s\n", str5);

    return 0;
}

【実行結果例】
str1 =      —> str1は宣言しただけなので不定値
str2 = ABC
str3 = abc
str4 = computer
str5 = hello

〇 演習問題

問題

文字型配列strに次のデータが初期設定されている。 このstrのデータを実行結果例のようになるように、(省略部)を埋めて英大文字 ⇒ 英小文字に変換しなさい。ただし、文字コードはASCIIとする。

#include <stdio.h>

int main( void )
{
    char str[] = "ABCD";

    (省略部)

    printf("str = %s\n", str);

    return 0;
}

【実行結果例】
str = abcd

解答例

#include <stdio.h>

int main( void )
{
    char str[] = "ABCD";

    str[0] = str[0] + 'a' - 'A';
    str[1] = str[1] + 'a' - 'A';
    str[2] = str[2] + 'a' - 'A';
    str[3] = str[3] + 'a' - 'A';

    printf("str = %s\n", str);

    return 0;
}

上記の ‘a’ – ‘A’ は ‘a’:97 から’A’:65 を引いた差の32を求めている部分です。
ただし、このような計算により大文字を小文字に変換できるのは、ASCIIコードのように
大文字と小文字のコードの差が一定のときに限られます。
学習が進んだ段階では、tolower関数を用いるようにしてください。

● 補足:’¥0’

文字列データは必ず終了コードとして値 0 を付けます。文字列を格納する配列の大きさは宣言時に決まりますが、文字列はこの配列いっぱいに格納する必要はありません。値 0 を使って終端を示せばよいのです。この値 0 は文字列専用の初期化を使って、

char str[] = "HELLO";

のようにすれば、コンパイラが付加してくれます。(ただし、一般の配列と同じように初期化すると付加されませんので、プログラム上で設定する必要があります。)

この値 0 の文字をエスケープシーケンスを用いて ‘\0’ のように表記します。また、この値 0 の文字を呼ぶときには「NUL」と呼びます。「NUL」は空ポインタ定数の NULL(ヌルと読むのが一般的です)と区別するために「ナル」と読むことが多いようです。

なお、上記「注意3」の ‘\0’ だけの文字列は「空文字列」や「NUL文字列」と呼ぶようです。

※ この NUL と NULL との区別や読み方にはいろいろな見解がありますが、いずれにしても文字列の終端には値 0 の文字を付けることをしっかりと覚えておいてください。

コメント