文字列を指すポインタとchar型配列との違い

C言語では文字列をポインタを使って扱うこともあれば、charの配列として扱う場合もあります。

char *p = “Orange”;
char a[ ] = “Apple”;

上の例では、p は「Orange」という文字列を指すポインタであり、a[ ] は「Apple」を格納している配列です。OrangeもAppleもヌル文字「\0」が終端文字として付加されます。

文字列を扱う方法が違うので以下の差が出てきます。

まず、ポインタの「p」も配列の「a」も文字列の先頭を指し示していますが、「p++」はできても「a++」はできません。a は配列の名前であり配列の名前はその先頭の要素の位置と同義ですが、ポインタの加減算とは異なるものであるため a++ のような使い方は出来ず、コンパイルエラーになります。また a に別のポインタアドレスを代入することも出来ません。「a = p」は間違いです。「p = a」は出来ます。

また、「Apple」という文字列は配列で確保しているため書き換えることができますが「Orange」という文字列の書き換えはできません。「Orange」を書き換えた場合の動きは不定です。僕の環境(ubuntu)で、*pに値を代入(*p = ‘A’)をして実行してみたところコアダンプしてしまいました。

ちなみに、ポインタ「p」は「Orange」の文字列を指し示していますが、ポインタの向き先を「Apple」に変えることは可能です。

これらを確認したプログラムソースを載せておきます。

コピペするなら以下を使ってください。


#include <stdio.h>

int main( void )
{
	char	*p = "Orange";
	char	a[] = "Apple";
	char	*ap;

	printf( "p: %s\n", p );
	printf( "a: %s\n\n", a );

	/* Orangeを指し示すポンタの位置をずらす */
	p++;

	/* Appleを指し示すポンタの位置をずらす。注意: a++ はできません */
	ap = a;
	ap++;

	printf( "p++:  %s\n", p );
	printf( "ap++: %s\n\n", ap );

	/* Orangeの値は書き換えられません( *p に代入はできません)
	   Orangeを指すポインタの向き先を変えることはできます */
	p = a;
	printf( "p: %s\n", p );

	/* Appleの値は書き換えられます */
	*p = 'a';
	*ap = 'P';
	a[4] = 'E';
	printf( "a: %s\n", a );

	return 0;
}

実行結果は以下となります。

$ ./a.out
p: Orange
a: Apple

p++: range
ap++: pple

p: Apple
a: aPplE

スポンサーリンク

コメントを残す

メールアドレスが公開されることはありません。