
こんばんは!
C言語初心者です!(もとい、プログラミング入門者ですが)
配列の再初期化?について質問です。
現在、テトリスを作っていて、
周りの壁を表す配列 int Stage[21][12]
テトリミノ(ブロック)を表す配列 int block[4][4]
Stageとblockを加算して(※1)、現在の状態を画面状態を示す int Field[21][12]
があります。(すべてグローバル変数です。)
このうち、配列Filedはテトリミノが刻一刻と落下するので、内容を一度初期化してから、再度、配列Stageと配列blockの内容を配列Fieldに取り込む必要があります。
その際の、配列の再初期化の方法なのですが、一般的にどのように初期化するのでしょうか?
方法1)配列に0を代入していく
for( int i = 0 ; i < sizeof( field ) / sizeof( field[0] ) ; i++ ) {
for ( int j = 0 ; j < sizeof( field[0] ) / sizeof( field[0][0] ) ; j++ ) {
field[ i ][ j ] = 0;
}
}
方法2)空の配列をコピー
int initStage[21][12] = { 0 };
memcpy(stage, initStage, sizeof(stage));

A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
単純に配列の中身をゼロ初期化するのであれば、
for (i=0; i<(sizeof(field) / sizeof(int)); i++) *(field + i) = 0;
もしくは、
memset(field, 0, sizeof(field);
ですね。
ちなみに、RAMが64KBしかなく、CPUのクロック周波数が4MHz程度で、
画面描画は直接VRAMに書くしかなかった時代の人なら、
ブロック周辺の背景に当たるデータをいったんその大きさの領域に退避し、
ブロックの形状と背景を重ね合わせて表示、
ブロックが移動するごとにその領域だけ一旦元へ戻し、
移動先(回転後の形状も同様)ブロックの領域のみまた同じように重ね合わせて表示すると思います。
(これを文字通り『重ね合わせ処理』と呼んでいました)
現代のコンピュータはかなり高性能なので気にならないかもしれませんが、
質問者様が作っているプログラムは画面全体を毎回再描画していると思うので、
スペックのかなり低いマシンでは画面全体がチラついた感じになると思います。
No.4
- 回答日時:
私は、memsetは使いません。
最近のコンパイラなら、最適化の技術も相当のものなので、forでのループとmemsetのどちらが効率がよいかなどと簡単に判断できません。
それなら、CPU等に依存するmemsetによる書き換えよりは、環境依存の少ないforループを選びます。
余談ですが
「21」って何の数?「12」って何の数?
幅を増やそうとしたら、12 を変えることになりますが、例えば
int a = 12 ;
とあったら、この「12」という数値は「幅」なのか、それとも、幅とはまったく関係のない値なのか、判断できますか?
「幅を表わす12」の全て、変更忘れをしない自信はありますか?
このような「意味のある数値」には、#define で名前を付けるのがよいでしょう。
No.3
- 回答日時:
配列全てを一つの値にするのではなくて、テンプレート配列(周囲の壁を含むフィールドの状態)からfield[][]へコピーするのですよね?
forでループさせても、memcpyを使用しても、どちらでも良いのではないでしょうか?
No.1
- 回答日時:
memset()でできるっぽいですね。
以下サンプルプログラム。
全角スペース2個(" ")をタブか半角スペースに変換すれば
実行できます。
空の2次元配列を用意し、初期の配列状態を表示。
適当な場所に適当な値を設定し、現在の配列状態を表示。
memsetして、現在の配列状態を表示しています。
プログラムの最後でsizeof(Stage)を出力すると、1008となっており、
配列の長さ 21 * 12 * 4(int型1つ当たりの大きさ)と一致しています。
#include <stdio.h>
void pri(int Stage[21][12]) {
printf("Stage[][]の中身\n");
for (int i = 0; i < 21; i++) {
for (int j = 0; j < 12; j++) {
printf("%d\t", Stage[i][j]);
}
printf("\n");
}
printf("\n");
}
int main(){
int Stage[21][12] = { 0 };
pri(Stage);
//適当な値を設定
Stage[3][4] = 34;
Stage[18][1] = 181;
pri(Stage);
memset(Stage, 0x00, sizeof(Stage));
pri(Stage);
printf("sizeof(Stage) = %d\n", sizeof(Stage));
return 0;
}
[参考]
http://www9.plala.or.jp/sgwr-t/lib/memset.html
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
- C言語・C++・C# プログラミングを教えて欲しいです。 配列aは、int a[9]={7,6,12,8,3,5,10,9 4 2022/12/19 23:27
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列で格納したものをmsgboxで...
-
C# Listを使わずに2次元配列の...
-
VBで構造体の配列を関数に渡す...
-
C言語で特定列だけを抽出して配...
-
テキストファイルから文字列を...
-
配列を使わずに、変数名を動的...
-
整数型の配列をランダムに並べ...
-
複数の選択範囲の行番号を個別...
-
C言語でcharの足し算
-
C言語 配列の再初期化
-
配列の参照渡しで型が一致しま...
-
GCCについて
-
先頭アドレスとは何ですか?
-
C言語初心者 ポインタについて...
-
2次元配列を戻り値とする関数?
-
VB.netでRadioButtonを配列にし...
-
VB.NET 構造体の配列の検索機能...
-
【C言語】配列の中に配列を入れ...
-
インデックスが配列の境界外で...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
C# Listを使わずに2次元配列の...
-
配列を使わずに、変数名を動的...
-
配列で格納したものをmsgboxで...
-
【速いブラインドタッチ】手を...
-
配列をEraseしてもメモリが開放...
-
ExcelVBAで質問です。離れた二...
-
Redimした動的配列はEraseする...
-
C# 配列の変数宣言について。
-
複数の選択範囲の行番号を個別...
-
VBで構造体の配列を関数に渡す...
-
先頭アドレスとは何ですか?
-
配列の参照渡しで型が一致しま...
-
銀行ATMの数字キーの配列
-
配列を含む構造体の初期値について
-
C言語で特定列だけを抽出して配...
-
unsigned char配列への入力の仕方
-
VB.NET 構造体の配列の検索機能...
-
C++ vectorに配列をプッシュしたい
-
C言語初心者 構造体 課題について
おすすめ情報
> 方法2)空の配列をコピー
>
> int initStage[21][12] = { 0 };
> memcpy(stage, initStage, sizeof(stage));
stageではなく、fieldでした