アプリ版:「スタンプのみでお礼する」機能のリリースについて

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

A 回答 (12件中1~10件)

C++でなくCならbzero(target,sizeof(target))


でできるかも。でもあんまし勧めん。
C++ではできるけど通用しない技だね。
0を入力することとメモリとして0を代入してしまうことが同じと言い切れるかどうかの問題なんだけど...
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
string.hをincludeしたのですが、bzeroを使えなかったのでこの方法はすみませんが、諦めさせてもらいます。
回答ありがとうございました。

お礼日時:2007/05/26 23:13

配列宣言時の初期化子を指定すれば良いです。


例えばこんな感じです。
int i[10] = {0};
構造体にも使用できます。

この回答への補足

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

補足日時:2007/05/26 23:13
    • good
    • 0

int a[10];


memset(a, 0, sizeof(a));

こんな感じでいけます。定石なので覚えておいて損はないでしょう。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/26 23:24

いろいろでてますねー。



ループ使いたくないのは速度の問題です?
いいコンパイラならベクトル化すればOKだと思いますよ。(配列を展開しとけばOK)

コードが汚くみえるからやだ?
アーキテクチャ依存のコードはやだ?
では前の回答に従うのがいいですね。

この回答への補足

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

補足日時:2007/05/26 23:35
    • good
    • 0

整数であれば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です。

この回答への補足

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

補足日時:2007/05/27 01:54
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/27 01:16

すいません。

知識が乏しく、嘘をいってました。
インテルコンパイラの説明書リンクします。

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

参考URL:http://download.intel.com/jp/developer/jpdoc/cco …
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/27 01:19

参考:(CでなくC++なら)標準にstd::fillがありますね。


(内部実装はループかも知れませんけど…これなら内部表現が非0でも平気)
#include <algorithm>
int array[128]; // 例
const std::size_tsize= sizeof array/sizeof array[0];
std::fill(array, array + size, 0);
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/27 01:59

C99が使えるなら



int x[10];
struct foo
{
int mem[10];
};
*(struct foo*)&x = (struct foo){0};

これなら、内部表現が非0の型でも平気。
    • good
    • 0

#5です。



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

指定方法ですが、

int a[10];
fill(a, 10);

とします。
動作ですが、再帰的にa[9], a[8], a[7], ..., a[0] に0を埋めているだけです。

ついでに、
> #8

構造体のメンバが配列だけの場合でも、サイズが同じになるかどうかは規格上保証されません。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/27 05:39

「ループを使わない目的」はなんですか?



結局、トレードオフになるわけですが、
例えばANo.5のコードはループを再起呼出で置換してるものです。
一般に再起はループより理解しがたい(≒保守しにくい)といわれますし、
別に速度上の優位性があるわけでもないですし(劣るとも限りませんが)。

目的が「ループを使わないでかけるか」というパズル(知的遊戯)なら十分な解ですが、
C言語で再起処理にするメリットが考えにくいところです。

もしも速度に焦点があるなら、実行速度が確保できる可能性が高そうなのは多分、
> あるいは、もう一つの手として、あらかじめ全要素を0で
> 初期化した配列を別に用意しておいてmemcpyでコピーする
これじゃないですかね。
どの程度のメモリが要求されるかは配列サイズ次第ですが、
再起関数を書いてもコード領域は使いますし。

この回答への補足

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

補足日時:2007/05/27 05:33
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!