C言語の配列を宣言した変数とポインタ変数の扱い方が同じになることをサンプルプログラムを作って確認してみました。具体的には以下の変数(aとp)は、ポインタでも配列(添字)でもどちらでも操作できるということです。ただし注意書きあり(最後に後述)。
char a[ ];
char *p;
サンプルプログラムは以下です。左側の数字は行数です。
コピペ用です。
#include <stdio.h>
void funcB( char a1[] );
void funcC( char a2[] );
void main( void )
{
char s[] = "Apple";
char i;
/* ポインタ変数 */
char *p1;
char *p2;
/* ポインタp1をポインタで操作する */
p1 = s;
for( ; *p1; p1++ )
printf( "%c", *p1 );
printf( "\n" );
/* ポインタp2を配列で操作する */
p2 = s;
for( i = 0; p2[i]; i++ )
printf( "%c", p2[i] );
printf( "\n" );
/* 配列a1をポインタで操作する */
funcB( s );
/* 配列a2を配列で操作する */
funcC( s );
}
/* 引数が配列である関数funcB */
void funcB( char a1[] )
{
for( ; *a1; a1++ )
printf( "%c", *a1 );
printf( "\n" );
}
/* 引数が配列である関数funcC */
void funcC( char a2[] )
{
char i;
for( i = 0; a2[i]; i++ )
printf( "%c", a2[i] );
printf( "\n" );
}
このサンプルプログラムの実行結果は以下となります。
$ ./a.out
Apple
Apple
Apple
Apple
ソースの説明をします。
15〜19行目は、ポインタ変数p1を通常のポインタの扱い方で操作しています。「Apple」という文字が印字されます。
21〜25行目は、ポインタ変数p2を配列(添字)で操作しています。結果はポインタで操作したときと同じになります。
27、28行目は、文字列sの先頭ポインタをfuncB関数に渡しています。funcB関数ではポインタを配列の形で受け取ります(35行目)。funcB関数の中では、配列宣言a1をポインタ変数の扱い方で操作して文字を印字しています。
30、31行目も、文字列sの先頭ポインタをfuncC関数に渡しています。funcC関数ではポインタを配列の形で受け取ります(43行目)。funcC関数の中では、配列宣言a2を通常の配列(添字)として操作しています。
ポインタ変数なのに配列(添字)で操作できる(21〜25行目)、配列の宣言なのにポインタで操作できる(27、28行目)というところがポイントかと思います。
注意点を記載しておきます。
配列の宣言(char a1[ ]; や char a2[ ]; など)は呼ばれる関数の引数には使用できますが、main関数内に書くことはできません。書くとコンパイルエラーになります。main関数内に書けるのは配列の定義となります。配列の定義とは、初期化した配列や領域を確保した配列のことです。
配列の定義
char s[ ] = “Apple”; //初期化した配列
char a[10]; //領域を確保した配列
配列の宣言
char b[ ]; //main関数内に書くとコンパイルエラーになります
また、配列の定義である変数はポインタのような操作はできません(あくまでも配列なので)。
つまり、
char a[10];
とした場合の、a++ や a=p(ポインタの代入)などはできません。