10−3.ポインタと文字列

普通ポインタを用いるときには、配列などのアドレスをポインタに設定して用いますが、 文字列の場合には、配列を使わずにメモリ上に取られた文字列のアドレスを直接ポインタに指定することができます。

(1)1つの文字列をポインタで表す

(書き方)
  1. char *p = "ABC";
  2. char *p;

    p = "ABC";

まずメモリ上のどこかに文字列 "ABC" がとられ、その先頭番地がポインタに設定される。

1、2 のどちらも同じこと

(2)複数の文字列をポインタの配列で表す

(書き方)
char *mnthp[3] = {
	"January",
	"February",
	"March"
};

まずメモリ上のどこかに文字列 "January"、"February"、"March" がとられ、 それぞれの先頭番地がポインタの配列の mnthp[0]mnthp[1]mnthp[2] に設定されます。

各文字列は隙間無くメモリ上に格納されるため(但し、連続して格納されるとは限りません)、 2次元配列で文字列を設定するより、メモリの節約になります。

(例)
char *mnthp[4] = {
	"January", "February", "March", "April"
};
int i;

for (i = 0; i < 4; i++) {
	printf("%s\n", mnthp[i]);
}
(実行結果)
January
February
March
April
演習

【文字列リテラル】

"January" や "February" のように " " で囲んだ文字列を「文字列リテラル」又は「文字列定数」と呼びます。

文字列リテラルは「定数」であり、本質的に値を変えないものです。

しかし、値を変えないはずの文字列リテラルですが、この単元で説明したようにポインタを用いて指定をした場合、その変更が可能になってしまいます。そのため、ANSI規格では文字列リテラルを「定数」とは呼びません。

たとえば、

char *p = "ABC";

strcpy(p, "DEF");

とした場合、処理系によっては文字列の書き換えが可能になります。(処理系によっては動作不能になります。)

文字列リテラル内の文字列を変更してよいかどうかは、処理系に依存しますが、 ANSI規格では、文字列リテラルの変更は未定義(何が起こるかわからないということ)です。

つまり、書き換える必要のある文字列は、一旦文字型配列に格納してから処理をするのが無難だと言えます。

char str[] = "ABC";

strcpy(str, "DEF");
◆◆前ページ  ▲TOP▲  次ページ◆◆

banner
「初心者のためのポイント学習C言語」
Copyright(c) 2000-2004 TOMOJI All Rights Reserved