ぷるぷるの雑記

低レイヤーがんばるぞいなブログ. 記事のご利用は自己責任で.

invalid array assignment の意味

一言でいうと配列名をポインタとしてアドレスを再代入することは出来ないというエラーである.

配列名とポインタの区別がつく場合

C言語では配列名はポインタと区別がつかないといわれるが、それは関数の実引数として配列名が渡されたとき呼び出された方の関数内での話であり、その配列を定義したブロック内ではコンパイラはちゃんと配列とポインタを区別している.

そしてコンパイラが配列だと判断できる範囲では、配列の先頭アドレスの再代入はできないのである.

配列名とポインタの区別がつかない典型例

コールした関数内ではアドレスが交換できる(ただし、この例はスワップできない)

#include<stdio.h>

void swap(int* a, int* b){
    a=b;
}

int main()
{
    int a[100],b[100];
    printf("%p\n",a);    //0xffffca70
    printf("%p\n",b);    //0xffffc8e0
    swap(a,b);
    printf("%p\n",a);    //0xffffca70
    printf("%p\n",b);    //0xffffc8e0
    return 0;
}

コールした関数内では配列の要素数が取得できない

以下のような例はC言語の典型的な特徴を表している. 配列を定義したブロック内では配列の要素数を取得できているのに対し、コールした関数内では要素数がおかしなことになっている.

つまり、コール先の関数では配列名とポインタを同等に扱えるのではなく、区別できないだけである. このような場合は、関数の引数に要素数も明示的に渡してやる必要がある.

#include<stdio.h>

void swap(int* a){
    printf("%d\n",sizeof(a)/sizeof(int));  //2、おかしい
}

int main()
{
    int a[100],b[100];
    printf("%d\n",sizeof(a)/sizeof(int));  //100、正しい
    return 0;
}