C言語編 目次

 関数設計

 

・関数名の命名規則
・プログラミングに出る!英単語

 ポインタ

 

・データ型とポインタ

 データ型

 

・char *とconst char *は違う
・符号付きと符号なし

 演算子

 

・三項演算子とデータ型の問題

 制御構文

 

・条件式で代入する
・三項演算子を使ったswitch

 構造体

 

・構造体のサイズとアライメント
・構造体メンバのサイズを知る

 配列

 

・配列使用時の注意
・配列の要素数を知る

 メモリ管理

 

・メモリスタック
・動的メモリ確保とメモリリーク

 モジュール設計

 

・モジュール分割
・汎用モジュールとアプリ依存モジュール

 パフォーマンス
  徹底チューニング

 


・どんな処理に時間がかかるのか
・ファイル入出力の効率化
・アルゴリズムを考える1
・アルゴリズムを考える2

 プリプロセッサの便利機能


・2重インクルード防止

 


トップページへ戻る

配列の要素数を知る

 今回は、配列の要素数が何個分確保されているのかを知る方法です。最初に、次のような配列を使ったプログラムを見てみます。short型の配列idの値を順番に表示するだけの簡単なプログラムです。

#include <stdio.h>

int main(int argc, char *argv[])
{
    short    id[6] = {123, 156, 234, 310, 344, 350};
    int      i;

    for (i = 0; i < 6; i++) printf("%d\n", id[i]);
    
    return 0;
}

 このプログラムでは、配列の大きさを6と固定しています。ここで、後からidの数が6個から5個に減ったとしたら、配列の宣言部とループ部分の2箇所の"6"を"5"に直さなければいけません。もしループ部分を直し忘れたら、配列の要素を越えた不正なアクセスとなってしまいます。初心者はこのようなコードを書きがちです。

 では、次のようにしたらどうでしょうか。配列の要素数を変数にして、要素数の分だけループするようにしました。こうすると、上のプログラムよりもはるかに"まし"になります。配列の要素数が変わったら、宣言部だけ書き直せば済むからです。

#include <stdio.h>

int main(int argc, char *argv[])
{
    short    id[] = {123, 156, 234, 310, 344, 350};
    int      idNum = 6;
    int      i;

    for (i = 0; i < idNum; i++) printf("%d\n", id[i]);
    
    return 0;
}

 しかし、これでもまだ「idを書き直したけど、idNumを直し忘れた」ということが起こりえます。このようなことが起こらないようにするためには、次のようにします。

#include <stdio.h>

int main(int argc, char *argv[])
{
    short        id[] = {123, 156, 234, 310, 344, 350};
    const int    idNum = sizeof id /sizeof id[0];
    int          i;

    for (i = 0; i < idNum; i++) printf("%d\n", id[i]);
    
    return 0;
}

 配列のサイズはsizeof演算子で取得できます。これを配列の1番目の要素のサイズで割れば、必ず配列の要素数になります。さらに要素数は定数なので、書き換えられないようにconstをつけます。これで、配列の添え字に0〜idNumを使用している限り、配列の要素を超えたアクセスは起こらないようになります。また、上のように、要素数が未指定の配列でも、正確な要素数を取得することができます。

 また、次のように関数に配列を渡した場合は、渡された関数側では配列のサイズを取得することはできません。(sizeof演算子でサイズを取ると、short *型のポインタ変数のサイズになるので、4が返ります。)

#include <stdio.h>

void PrintSize(short *id);

int main(int argc, char *argv[])
{
    short        id[] = {123, 156, 234, 310, 344, 350};
    const int    idNum = sizeof id /sizeof id[0];
    int          i;

    for (i = 0; i < idNum; i++) printf("%d\n", id[i]);
    PrintSize(id);

    return 0;
}

void PrintSize(short *id)
{
    int        size = sizeof id;    // size -> 4
    
    printf("size:%d\n", size);
}

 関数に配列を渡すときは、次のように配列とその要素数の2つを渡さないといけないことになります。

#include <stdio.h>

void PrintSize(short *id, const int idNum);

int main(int argc, char *argv[])
{
    short        id[] = {123, 156, 234, 310, 344, 350};
    const int    idNum = sizeof id /sizeof id[0];
    int          i;

    for (i = 0; i < idNum; i++) printf("%d\n", id[i]);
    PrintSize(id, idNum);

    return 0;
}

void PrintSize(short *id, const int idNum)
{
    printf("size:%d\n", sizeof id[0] *idNum);
}