ここから本文です

C言語 配列の全てに同じ値を初期値化するにはどうすればいいでしょうか?

yakatabakoさん

2014/1/2713:28:00

C言語 配列の全てに同じ値を初期値化するにはどうすればいいでしょうか?

int a[10]
aという配列の中身の全てに9999を設定する場合、どう初期値化すればよいでしょうか?
一応下記のようにプログラムを書けば,代入する形で9999が入りますが
a=9999;のように一行で初期値化する方法はありませんか?

#include<iostream>
using namespace std;

int main()
{
int a[10],i;

for(i=0;i<10;i++){
a[i]=9999;
}
}

閲覧数:
99,921
回答数:
6

違反報告

ベストアンサーに選ばれた回答

bluely622さん

2014/1/2713:40:37

残念ながら、質問文にあるようにfor文で全要素に代入するしかありません。

例外として、"0"で初期化したい場合は

int a[10] = {0};

といった形で初期化できます。

※C言語の仕様で、初期化が記述されていない要素(この場合はa[0]以外)は全て"0"で初期化されるため。

この質問は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜5件/5件中

並び替え:回答日時の
新しい順
|古い順

khurataさん

編集あり2014/1/2817:29:16

すでに回答がある通り、C/C++ では、配列の全要素に任意の値を初期化代入するには、いちいち代入しなければなりません。
質問者様の示したコードでも良いのですが、より汎用的には、次のように書くべきでしょう。
for(i=0;i<(sizeof(a)/sizeof(a[0]));i++){
a[i]=9999;
}
こう書けば、配列の要素数がいくつであっても、全ての要素が間違いなく初期化されます。
(sizeof( 何々 )/sizeof( 何々[0] ) をマクロとして定義するのは C では定番のテクニックです)



付記:

bluely622 さんが書かれている通り、配列の全要素ないし構造体の全メンバを値 0 で初期化したいならば、宣言で { 0 } を代入すれば済みますが、9999 という値では、このテクニックは使えません。
(個人的には、コンパイラがこれくらいやってくれても良いのに、とは思いますが)

なお、b_fifty_one さんは、{ 0 } を使ったゼロ初期化に異を唱えていらっしゃいますが、memset( ) でゼロビットを埋めたところで、値 0 で初期化出来るという保証はありませんので、「値 0 で初期化したい場合」は、やはり { 0 } を使うべきです。

たとえば浮動小数点数の値 0.0 の内部表現が全ビット 0 であるかどうかなんて事は、C の言語レベルで問うべき事ではありません。浮動小数点数に限らず、「値 0」の内部表現が「全ビット 0」であるかどうかは、処理系を限定しないと成り立たない仮定です。
つまり、memset( ) でゼロクリアするようなプログラムは処理系依存であって、移植性・標準性を失っているのです。充分に注意すべきです。
(コンパイラが { 0 } を memset( ) と同義に展開している例は多く見受けられますが、それは結局、「処理系依存の話」です)

プロフィール画像

カテゴリマスター

trekfareastさん

2014/1/2723:57:14

/*yakatabakoさんへ

>#include<iostream>
>using namespace std;

というコードがありますので、C++ですと、…
STLのalgorithmは通常の配列にも使用でき(るものもあり)ますので、
algorithmをインクルードして、以下のようにすれば、配列内容を指定値で埋めたり、ソートしたりする事が可能です。

----------実行結果----------
a[10]=9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999,
b[12]=0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1, 11.11,




外してたらごめんなさい(^_^;
*/

#include<iostream>
#include<algorithm>
using namespace std;

//配列内容を表示するテンプレート関数(coutが対応しているものは表示できます)
template <class T>
void arrayPrint(char *name,T array[],int size){
cout << name << "["<< size <<"]=";
for(int i = 0; i < size; i++) cout << array[i] << ", ";
cout << endl;
}

//配列の名前や要素数をarrayPrintに自動で与えるマクロコード
#define ArrayPrint(array) arrayPrint(#array,array,sizeof(array)/sizeof(array[0]))


int main()
{
//配列内容を指定値で埋める例
int a[10],i;
fill_n(a,10,9999);//またはfill(a,a+10,9999);//配列内容を指定値で埋める
ArrayPrint(a);//配列の内容を表示

//配列内容をソートする例
double b[12]={7.7, 5.5, 8.8, 3.3, 4.4, 2.2, 1.1, 9.9, 6.6, 0.0, 11.11, 10.10};
sort(b,b+12);//配列内容をソート
ArrayPrint(b);//配列の内容を表示


return 0;
}
//以上です。m(_ _)m

umiushi711さん

2014/1/2720:00:16

初期値として、9999に拘らなければ、例えば、

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

とすると、(2の補数が採用されている場合は)全て-1に初期化される、といった邪悪な手法もありますね。

b_fifty_oneさん

編集あり2014/1/2716:46:30

すでに出ている通り、C言語としてはできません。
#まあC++でもSTLの関数を使って内部的にループさせるだけですが

ご理解のとおりループさせるのが一番早道でしょうね。
多用するなら関数化すればいいでしょうし。

ちなみに、初期化対象の配列が(unsigned)char型の場合であれば、memset関数で初期化できます。
int型などでは、この関数ではゼロクリア以外の目的には使えません。(まあ全バイト同じ値ならゼロ以外でも使えますが、intで9999というような値はセットできません)

>例外として、"0"で初期化したい場合は
これはまあその通りなのですが、個人的にはこの仕様に頼るのは可読性・可搬性の低下を招く恐れが高いかなと思います。
ゼロクリアするだけなら、memset使えば済む話なので、そっちの方が可読性・可搬性は高いでしょう。

jtaka451さん

編集あり2014/1/2721:17:31

C++だとSTLのarrayクラスをつかえば、fillを使って一気に代入できそうだけど。

追記:
基本的にC言語では結構細かいところまで手作りってイメージ。
オブジェクト指向言語は面倒は言語仕様とクラスライブラリに押しつけて、コードはある程度わかりやすく出来るって感じかな。

あわせて知りたい

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

5文字以上入力してください

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。