読者です 読者をやめる 読者になる 読者になる

配列はポインタ?

確かにC言語の素の配列は単純に
「必要なサイズだけメモリを連続的に確保しただけ」
であって、
関数に対して配列を(そのまま)渡すことすらできない訳で、
結局サイズとか色々なものの面倒を見なければならない点ではまさにポインタそのもの同等ではありますよね。


あえて未定義値を表示するプログラム、

void f(int array[])
{
    int i;
    for (i = 0; i < 10; ++i) {
        printf("%d?n", *array );
        ++array;
    }
}

void ff(int* array)
{
    int i;
    for (i = 0; i < 10; ++i) {
        printf("%d?n", array[i] );
    }
}

int main()
{
    int a[10];
    f(a);
    ff(a);
    ...

を書いてみたけど、
上は関数に配列を渡している*1がポインタのように扱っている。
下は関数に配列の先頭のアドレスを渡しているが中では(他言語における)配列のように扱っている。*2


こういう風に書けてしまう。
それがC言語


要するに素のコンピュータにはただメモリという空間があるに過ぎなくて、
C言語の配列はそれを確保しているだけ。
あとは配列の型情報に従ってその単位毎にアクセスすることができるだけ。
それ以上でもそれ以下でもない。


配列=ポインタではないけど、
(念のため追記)
C FAQ 1に詳しい。
言葉を借りるなら
「配列宣言は領域を確保しその領域を指定した名前と型で識別する事を要求する」
「ポインタ宣言は指定した型による領域を指し示すための場所を要求する。単一の要素、配列(の先頭)、ないしはどこでも指すことができる。指さないこともできる」

ただ、両者の扱いとも「同等」の低レベルのメモリ操作を行っているには違いなく、
今時
「関数に配列の要素数を渡さないといけないなんてありえないっしょ」
とか言われても仕方がない言語ではある。
(自分も間違いがあるかもしれないですが)
要するにrawすぎる。
でも、アセンブリと較べたら超高級。

*1:厳密に言えば「配列」は渡していない

*2:実際にはSyntaxSugar