• ベストアンサー

全配列に0を入力

c言語で配列を宣言した後に、ループを使わずに 配列全体に0を入力したいのですが、そのような方法はありますか。 あれば、どのようにすればよいか教えてください。お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

整数であればmemsetで0を埋めればよいのですが、浮動小数点数やポインタの場合、内部表現が0とは限らないので、次のような関数を使えば一応ループを回避できます。 void fill(int *array, size_t n) {  if (n > 0)  {   *array = 0;   fill(array + 1, n - 1);  } } ここで、arrayの型は必要に応じて変更してください。 例えば、double型の配列ならdouble *arrayとしてください。 あるいは、もう一つの手として、あらかじめ全要素を0で初期化した配列を別に用意しておいてmemcpyでコピーするなら、どんな型でもOKです。

ashiato-li
質問者

お礼

回答ありがとうございます。 memsetでは計算したときに違った値を出してくるときがあったので助かりました。 回答ありがとうございました。

ashiato-li
質問者

補足

一応使えているのですがポインタの部分とsize_tの指定が、よく理解できないのでよければ、この文がどのように動いているのか解説してもらえないでしょうか。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (11)

回答No.12

配列として宣言しているデータ型にもよりますが、1バイトや2バイト単位のデータ型の場合は、以下のような方法でループ回数を減らし、多少パフォーマンスが向上する可能性もあります。 ループを使わない方法ではありませんので、ご参考までに。 例) char s[100]; long l = 0; long *p = (long*)s; for (l = 0; l < sizeof(s) / sizeof(long); l++){ *p++ = 0; }

ashiato-li
質問者

お礼

回答ありがとうございます。 速度を上げることも目標の1つだったので参考になりました。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.11

> ループを回避したいのは、ある程度ループが繰り替えされるとなぜか > プログラムが強制終了されてしまうからです。 ループを使わずに回避するのではなく、なぜ強制終了されるのか、その原因を究明することの方が先決だと思います。 問題のあるコードを補足していただければ、もっとまともな解決策が見つかるかもしれません。 なお、配列の0クリアは、(厳密には移植性がありませんが)memsetを使うのが現実解です。そのためには、環境を明らかにすべきです。

ashiato-li
質問者

お礼

回答ありがとうございます。 環境を書いておくべきでした。すみません。 環境は、 windows xp professional sp2 borland c++ compiler 5.5 CPad for borland c++ compiler です。

全文を見る
すると、全ての回答が全文表示されます。
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.10

「ループを使わない目的」はなんですか? 結局、トレードオフになるわけですが、 例えばANo.5のコードはループを再起呼出で置換してるものです。 一般に再起はループより理解しがたい(≒保守しにくい)といわれますし、 別に速度上の優位性があるわけでもないですし(劣るとも限りませんが)。 目的が「ループを使わないでかけるか」というパズル(知的遊戯)なら十分な解ですが、 C言語で再起処理にするメリットが考えにくいところです。 もしも速度に焦点があるなら、実行速度が確保できる可能性が高そうなのは多分、 > あるいは、もう一つの手として、あらかじめ全要素を0で > 初期化した配列を別に用意しておいてmemcpyでコピーする これじゃないですかね。 どの程度のメモリが要求されるかは配列サイズ次第ですが、 再起関数を書いてもコード領域は使いますし。

ashiato-li
質問者

補足

回答ありがとうございます。 ループを回避したいのは、ある程度ループが繰り替えされるとなぜか プログラムが強制終了されてしまうからです。 この原因が分かればループを使うのですが。

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.9

#5です。 > 一応使えているのですがポインタの部分とsize_tの指定が、よく理解できないのでよければ、この文がどのように動いているのか解説してもらえないでしょうか。 指定方法ですが、 int a[10]; fill(a, 10); とします。 動作ですが、再帰的にa[9], a[8], a[7], ..., a[0] に0を埋めているだけです。 ついでに、 > #8 構造体のメンバが配列だけの場合でも、サイズが同じになるかどうかは規格上保証されません。

ashiato-li
質問者

お礼

再度の回答ありがとうございます。 プログラムの動きを理解することができました。

全文を見る
すると、全ての回答が全文表示されます。
  • colder
  • ベストアンサー率43% (30/69)
回答No.8

C99が使えるなら int x[10]; struct foo { int mem[10]; }; *(struct foo*)&x = (struct foo){0}; これなら、内部表現が非0の型でも平気。

全文を見る
すると、全ての回答が全文表示されます。
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.7

参考:(CでなくC++なら)標準にstd::fillがありますね。 (内部実装はループかも知れませんけど…これなら内部表現が非0でも平気) #include <algorithm> int array[128]; // 例 const std::size_t size = sizeof array/sizeof array[0]; std::fill(array, array + size, 0);

ashiato-li
質問者

お礼

回答ありがとうございます。 今回はcでお願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • om_unk
  • ベストアンサー率0% (0/1)
回答No.6

すいません。知識が乏しく、嘘をいってました。 インテルコンパイラの説明書リンクします。 ベクトル化って調べるとかなり不明なことが書かれていました。適当なこと言ってしまいました。 インテルコンパイラなら、インテルの言うところのベクトル化をしてくれます。 が正しいです。 インテルの言うところのベクトル化はURLを参考ください。 msnで適当に探したものなので、もしかしたら消えるかも。。

参考URL:
http://download.intel.com/jp/developer/jpdoc/ccomp40j.pdf
ashiato-li
質問者

お礼

再度の回答ありがとうございます。 ベクトル化については、URLを参照させていただきました。 まだ、理解しきれませんでしたがコンパイラによってはそのような機能があることを知れて勉強になりました。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • om_unk
  • ベストアンサー率0% (0/1)
回答No.4

いろいろでてますねー。 ループ使いたくないのは速度の問題です? いいコンパイラならベクトル化すればOKだと思いますよ。(配列を展開しとけばOK) コードが汚くみえるからやだ? アーキテクチャ依存のコードはやだ? では前の回答に従うのがいいですね。

ashiato-li
質問者

補足

回答ありがとうございます。 よければベクトル化するとはどういうことか、教えてもらえませんか。

全文を見る
すると、全ての回答が全文表示されます。
回答No.3

int a[10]; memset(a, 0, sizeof(a)); こんな感じでいけます。定石なので覚えておいて損はないでしょう。

ashiato-li
質問者

お礼

回答ありがとうございます。 配列の中身を0にすることができました。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

配列宣言時の初期化子を指定すれば良いです。 例えばこんな感じです。 int i[10] = {0}; 構造体にも使用できます。

ashiato-li
質問者

補足

回答ありがとうございます。 ですが、宣言をした後の方法でお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 配列の書き方

    C言語の配列の宣言で unsigned char aaa[256/8] という表現があるのですが、これはどういう意味でしょうか?

  • Javaの配列の宣言方法のメリット?

    1週間ほど前からJavaを独学している者です。 C言語をその前からやっていて、初心者レベル程度ならわかると思います。 そこで、質問です。 C言語の配列宣言:   int array[10]; Javaの配列宣言:   int array[] = new int[10]; 二つの言語とも、要素10個のarray1次元配列変数を宣言していると思います。 C言語の書き方はシンプルなので、納得がいきますが、Javaの方はどうしてこの形で宣言をするのかわかりません。(自分が言語製作者ならシンプルな書き方を採用します) だから、このような宣言の方法をとるということは何か理由があるのだと思います。 自分が思うところ、JavaはC言語より、柔軟で多機能だとおもうので、その影響で汎用性をますために、 長くなっているのかな~?と思っています。 こんごJavaの学習を進めていくと、例えば、   int array[] = new double[10]; //←エラーになりました みたいに型のちがう、宣言が出てきたりするのでしょうか? ちらっと、学習に使っている本をみたところ、動的配列の作成は別の操作で実現しているようなので、 「動的とは関係ないのかな?」と思っています。 長くなりましたが、Javaの配列宣言のメリットを教えてください。

    • ベストアンサー
    • Java
  • 配列を使わずに、変数名を動的にループで回したい

    配列を使わずに、変数名を動的にループで回したい 大学の課題をやっている途中に思ったことなのですが……。 プログラム中に同じ型の変数p1,p2,p3があり、それぞれの変数にループで同じ処理を施したいと思っています。 しかし、「p(i)」や「("p" + i)」などと、変数どうしを別のものとして認識させようとしても、コンパイラから警告が出て上手くいきません。 配列を使えば、このような処理が出来ることはわかるのですが、使う変数名を指定されてしまっているために、今回は配列を使えません。 出来るか出来ないか、出来る場合は方法を知りたいです。 後、今回はC言語のプログラムで利用出来るかが自分にとっての問題なのですが、C言語以外のこのプログラミング言語なら出来る、とかの情報もこの機会に知りたいです。 お答え出来る範囲でいいので、もしよければ回答お願いします。

  • 配列へのキーボード入力

    次のような問題がわからなくて困っています。 まず、キーボード入力により配列の大きさを決め、 その後、先ほど入力した個数のデータをキ-ボードから入力するというものです。 これだけならわかるのですが、条件があって、入力は次のようにするとあります。 2 3 ←配列の大きさ(2行3列) 1 2 3 ←配列に入れるデータ 1行目 4 5 6 ←配列に入れるデータ 2行目 Cプログラミングを始めて間もない初心者です。どなたかよろしくお願いします。

  • 配列数を取得するには

    C言語ははじめたばかりです。 例えば、以下のような配列数を取得するにはどうしたら いいのでしょうか? まさか for ループで'\0'が来るまで回すものか・・・ char test[] = {'あ', 'い', 'う', 'え', 'お'};

  • flaot配列の値格納について

    すみませんC言語の初心者ですが、教えて頂きたいことがあります。 floatの二次元配列に、すべて同じ値をセットしたいのですが この場合、for で配列分ループさせて値をセットするしか ないのでしょうか? memesetのように、セットする方法はないのでしょうか? 宜しくお願いします。

  • MIPSアセンブリ言語で配列を宣言するには?

    現在MIPSアセンブリ言語を学習していますが、配列に相当するものの宣言の仕方を詳しく知りません。 int items[5] ={0,0,0,0,0}; (C言語の場合) のような配列をMIPSで用意するなら、 items: .word 0,0,0,0,0 としてやるなどすればよいことまではわかっていますが、もし配列の要素数が500だった場合、上で0を500個も書かなければならないのでしょうか。短く書ける方法はありませんか。

  • 配列をループでたくさん宣言したいのですが、配列名や変数名を変数で宣言することはできませんか?

    お世話になっております。 タイトル通りの質問です。 日付がファイル名になっているCSVファイルが複数あるのですが、 それをそのまま「array20071020」などという名前の配列に、それぞれ入れて行きたいと思います。ループ処理でなければ出来ないと思うのですが、ループ処理内で配列を宣言していく方法はあるでしょうか。

  • 配列の使い方分かりません

    //整数型の配列を10個準備する。 //ループ文を用いてキーボードから値を10個入力する。(for文を用いる) //入力した値を出力する。 //ループ文を用いて入力値の合計と平均値を求める。(while文を用いる) 以上の課題が出されました。 配列の使い方が分からないので上手くできません。 説明付だとうれしいです。よろしくお願いします。

  • 配列について

    C言語には2次配列までしかないようなのですが3次配列のようなものはできないのでしょうか?