配列の初期化について

こんちにちは。

マイコン初心者なので初歩的な質問かもしれませんが、アドバイスいただけると幸いです。
時間のある時にHEWの環境でR8C/15をいじっているのですが、内臓ADCの値を10回よむというプログラムをつくろとおもっているのですが、
配列の宣言の初期値0はどのように処理すべきでしょうか。アドバイス頂けると助かります。
質問事項を下記にまとめました。
============================================
#1、unsigned int adc_data[10]=0;
 これで初期値が全て0になるのか?それともadc_data[0]=0となるのか?

#2、unsigned int adc_data[10]={0};
 ネストは無視されるので#1と同じ意味になるのか?

#3、開発環境が大域変数の初期値を0にしてくれるものなのでしょうか?

============================================
ちなみにWebで調べて見るとfor文で配列数分ループでゼロにするように皆様しているようです。
unsigned int adc_data[10];
あとで
 char i;
 for(i=0; i>10; i++)
 {
 adc_data[i]=0
 }

C言語的の文法的な話になりこのカテゴリーで投稿するのが正しいのかわかりませんが、
よろしくお願い致します。

 

Parents
  • 配列の宣言の初期値0はどのように処理すべきでしょうか。

    初心者ならば、書き方の違いによるメリット/デメリットまで考えが及ばないと思いますので、まずは自分の分かりやすい書き方をされるべきと思います。

    ちなみに、

     char i;
     for(i=0; i>10; i++)
     {
     adc_data[i]=0
     }
    

    これでは初期化はされません。

  • fujitaさん答えを教えてあげましょうよ(笑)

    私は、sizeof()を使うのが好きです。配列の大きさを考えずに、定型にできるので。

    unsigned int adc_data[10];
    unsigned int i;
    for(i=0; i<sizeof(adc_data); i++)
    {
     adc_data[i]=0;
    }

    ちなみに、変数が勝手に初期化されるかどうかはコンパイラ(初期化ルーチンの記述)によるので、あてにしない方がいいと思います。

  • sizeof(adc_data) だと adc_data の要素数ではなく adc_data のバイト数となるので

    for(i=0; i<sizeof(adc_data); i++)
    

    は正しくありません。

    for(i=0; i<(sizeof(adc_data) / sizeof(adc_data[0])); i++)
    

    とするか、

    #define AdcSamples 10
    unsigned int adc_data[AdcSamples];
    for(i=0; i<AdcSamples; i++)
    

    等とするべきですが、将来的に adc_data が配列ではなく unsigned int へのポインタかなんかに変更されてヒープかどっかからメモリを割くようプログラムが変更とかされた場合には、前の例では発見しづらいバグの原因にもなりかねないため、後の例のほうがどちらかというと望ましいと思います。

  • fujitaさん

    ご指摘ありがとうございます。

    なにげに、今までint型でも、変数サイズで割り忘れていたことがあるかも・・・・。やばい、メモリ破壊するコードをどこかに埋め込んでしまった?!

  • 皆様ありがとうございます。

    たしかに私の投稿のfor文は符号が逆でした。。。。しかも「;」も忘れている。。。

    size0のことは全然しりませんでした。どのような時に有効に使えるものなのかわかっていませんが、Webで調べてみます。

    またマクロでサンプル数を定義しておくとあとで変更もらくになりそうですね。新しい発見です。

    下記の意味はあまりわかっていませんが、まずは一歩一歩勉強していきます。。。。

    >unsigned int へのポインタかなんかに変更されてヒープかどっかからメモリを割くようプログラムが変更とかされた場合

  • 勉強、ご苦労様です。

    自分の場合は結果オーライなので、その場しのぎで済みそうならこんな書き方をしてます。

    memset(adc_data, 0, 20);

    「20」の部分に拘りたいのなら色々と工夫があるとは思いますが(^^;

  • Webで調べてみます

    Web にはけっこうデタラメなことも書かれていたりするので、何か1冊紙の本の入門書を読まれることをお勧めします。

    自分はC言語を勉強したのは随分昔なのでいまどきはどういう本があるのか分からないのですが、Amazonで「C言語 入門」等で検索し、レビューの数がある程度あって評価の高いものを選べばそう変な本には当たらないと思います。

Reply
  • Webで調べてみます

    Web にはけっこうデタラメなことも書かれていたりするので、何か1冊紙の本の入門書を読まれることをお勧めします。

    自分はC言語を勉強したのは随分昔なのでいまどきはどういう本があるのか分からないのですが、Amazonで「C言語 入門」等で検索し、レビューの数がある程度あって評価の高いものを選べばそう変な本には当たらないと思います。

Children
  • 入門書は手元に「やさしいC」というのがあります。今は時間が開いた時にマイコンをいじりながらわからないことがあったら参考書を読むようにしています。いずれにせよいろいろと本も探していますね。ありがとうございます。

  • おくればせながら。

    >#1、unsigned int adc_data[10]=0;
    > これで初期値が全て0になるのか?それともadc_data[0]=0となるのか?

    >#2、unsigned int adc_data[10]={0};
    > ネストは無視されるので#1と同じ意味になるのか?

    #1の書き方は無いと思います。#2が正解で意味は、後者(adc_data[0]=0)。
    adc_data[10]={1};と書いてみると判りやすいと思います。最初の要素だけ指定
    して、後を省略しているのです。で、省略した場合は0(ゼロ)とみなす約束にな
    っているので、adc_data[10]={0};は結果的にすべての要素が0(ゼロ)になるのです。

    >#3、開発環境が大域変数の初期値を0にしてくれるものなのでしょうか?

    はい。初期値のない大域変数は0(ゼロ)に初期化されます。これも約束事です。

    ただ、皆さん言っていますが、組み込み用のコンパイラはしばしば約束どおりに
    初期化してくれません。自分でスタートアップを書いて直す手もありますが、
    そんなことをするより、自前の初期化関数を書くほうが手間がかからないと。

    でも本当はコンパイラの仕事なんですよ、本当は。

    いつも訊いてばかりなので、恩返し(笑)

  • YUKITOさん、

    ご返信ありがとうございます!!