【C言語】
配列要素数の求め方

最終更新日 2025年11月18日

warning: expression does not compute the number of elements in this array

警告:この計算式では配列の要素数は求まりません。
[-Wsizeof-array-div]


■この記事の概要

この記事では、C言語で配列の要素数を求める際に、sizeof(配列の型)ではなくsizeof(配列名[0])を使用する重要性を解説しています。配列の型変更時にも正しく要素数を取得でき、型の誤りを防止できます。具体例を用いて正しい使い方を説明しています。


■配列要素数の求め方

#include <stdio.h>
typedef unsigned short  U2 ;
typedef unsigned int    U4 ;
int  main(void) {
    U4      ary[10] ;

    size_t  len = sizeof(ary)/sizeof(ary[0]);
    for(size_t i = 0; i < len; i++){
        ary[i] = i ;
        printf("ary[%zu]=%u\n",i,ary[i]); 
    }    
}

配列の要素数は
要素数=配列全体サイズ/配列一個のサイズ
なので
sizeof(配列)/sizeof(配列[0]) 
で求まります。


■間違いやすい要素数の求め方

//ダメ:intとshortの型が違うので要素数は求まらない
#include <stdio.h>
int main(void) {
    int     ary[10];

    size_t  len = sizeof(ary)/sizeof(short);
    for(size_t i = 0 ;i < len ;i++){
        ary[i] = i ;
        printf("ary[%zu]=%d\n",i,ary[i]);
    }  
}

上記のコードの場合
配列の型 intと分母の型short が違うので
意図した要素数は求まりません。

sizeof(配列の型)を使うのではなくて
sizeof(配列名[0])を使うようにしましょう。

こうすると改版時配列の型を変更しても
配列の要素数を求める式は変更しなくてすみ、
思い込みによる型の間違いも避けれます。


参考:

sizeof()よりもsizeof(変数名)を使いましょう。

https://ttsuki.github.io/styleguide/cppguide.ja.html#sizeof

■sizeof(ポインタ引数)の間違い

warning: division ‘sizeof (int *) / sizeof (int)’ does not compute the number of array elements

警告:’sizeof (int *) / sizeof (int)’ は、配列の要素数を計算しません。
[-Wsizeof-pointer-div]


#include <stdio.h>
void    func(int *ary) 
{    
    //期待する配列の要素数にならない   
    size_t num = sizeof(ary)/sizeof(ary[0]);
    printf("%zu\n",num); 
}
int main(void) {
    int ary[128];
    func(ary);
}

sizeof(配列)/sizeof(配列[0])で要素数を求める技は
ポインタには使えません 。
配列に対して使ってください。

※呼び元のmain( )では ary は配列でしたが
 呼び先のfunc( )では aryはポインタです。


■sizeof(配列形式引数)の間違い

warning: ‘sizeof’ on array function parameter ‘buf’ will return size of ‘char *’

警告:sizeof(配列形式の関数引数)では配列サイズは得られない

[-Wsizeof-array-argument]

#include    <stdio.h>
void    func(int ary[128]) 
{
    //NG:期待する配列のサイズにならない
    printf("%zu\n",sizeof(ary));
}
int main(void) {
    int ary[128];
    func(ary);
}

void func(int ary[128])

128という数字をコンパイラは無視

void func(int ary[])と同じ

関数仮引数は配列形式もポインタ形式も同じ

void func(int *buf)と同じ

このため
sizeof(ary)は
配列のサイズではなくて
ポインタのサイズが求まります。

※プログラマが期待しているのは恐らく
配列のサイズでしょう。

配列のサイズが欲しい場合は別途引数を用意して親関数からサイズを教えてもらう必要があります。

参考:

ARR01-C. 配列のサイズを求めるときに sizeof 演算子をポインタに適用しない

https://www.jpcert.or.jp/sc-rules/c-arr01-c.html