はじめまして。panicdjです。
いまCでプログラムを組んでいます。
環境はVC++ver6.0 Win32 Console Applicationです。
以下のプログラムを見てください。
#define X_MAX 10
#define Y_MAX 20
#define Z_MAX 5
int main(int argc , char ** argv)
{
int i, j, k;
int aa[10][20][5];
for (i = 0; i < X_MAX; i ++) {
for (j = 0; j < Y_MAX; j ++) {
for (k = 0; k < Z_MAX; k ++) {
aa[i][j][k] = 10.0;
}
}
return 0;
}
過去のスレッドでポインタ型によるアクセスを
すれば、処理が高速になるとかかれていました。
自分は,for文による繰り返す処理ではなく,
その「ポインタ型によるアクセス」を実装したいのです。
こんな私にアドバイスお願い致します。
No.9ベストアンサー
- 回答日時:
> C言語などを解説しているサイトでのサンプルコードとかでしょうか??
も、含めてですね。オープンソースなプログラムとかでもよいと思います。勉強の種は沢山転がってますから探してみてください。
> これは、たとえばVCを用いているのであれば、デバッカの
プログラミングの際の話のつもりで書きました。頭の中にメモリのイメージ(箱とか?)を思い浮かべると良いです。今宣言した変数はどこにあるのか、とか、ポインタの先の実体はどこなのかというのを常に意識してということです。
> できることなら、参考になる書籍やサイトを提示させて
残念ながら Cに関しての書籍・サイトともに知りません。
が、http://alfin.mine.utsunomiya-u.ac.jp/~niy/algo/i … で集められた関数等は勉強になると思います。
参考URL:http://alfin.mine.utsunomiya-u.ac.jp/~niy/algo/i …
yatokesaさん、何度もアドバイスありがとうございます。
>> C言語などを解説しているサイトでのサンプルコードとかでしょうか??
>も、含めてですね。オープンソースなプログラムとかでもよいと思います。勉強の種は沢山転がってますから探してみてください。
はい、承知しました。
yatokesaさん、いろいろ教えて頂きありがとうございました。
なお、本スレッドでお世話になった方にも感謝しています。
ありがとうございました!!
No.8
- 回答日時:
>for (i = X_MAX*Y_MAX*Z_MAX; i; i--) {
>とすると、速くなるのでしょうか?
理屈は #6:terra5さんのとおりです。また、terra5さんの仰るとおり、コンパイラが勝手に最適化する可能性もありますので、知っている人が見れば気分的に早いコードだ!って気分になれる程度の速さです^^;)。デバッグモードなどでアセンブラとの混合リストを見ると違いが分かるかもしれません。
>レベルなのでなんとかその域から脱却したのですが。
私が Cを始めたのはもう十ン年前なので...。私が学習したのは「はじめてのC」というやつですがね。公開されている色々な人のコードを見るのが良い勉強になると思います。
ポインタを理解したいのなら、常に変数がどのメモリ(スタックも含めて)に配置されているのかを考えながらコーディングすることです。
yatokesaさん,何度もアドバイスいただきありがとうございます。
>公開されている色々な人のコードを見るのが良い勉強になると思います
ちょっと、別件なのですが、↑は,サイトで公開されているコードとは、
C言語などを解説しているサイトでのサンプルコードとかでしょうか??
>ポインタを理解したいのなら、常に変数がどのメモリ(スタックも含めて)に配置されているのかを考えながらコーディングすることです。
上記についてもう少し教えてください.
これは、たとえばVCを用いているのであれば、デバッカの
混合モードを開いてアセンブラでどの変数がpushされているか
とか確認することなのでしょうか??
私は、詳しく混合モードの使い方
(例えば、espレジスタなどのレジスタの詳しい機能 他)
がよくわかっていません。
できることなら、参考になる書籍やサイトを提示させて
頂けると助かるのですが.
以上、どうかよろしくおねがいします!
No.6
- 回答日時:
ポインタを理解するなら意味がありますが、
高速化の為に・・なら、あまり意味がないですね。
まず、意味があるほどの差がでないか、変わらないですし、
読みづらいプログラムは悪です(^^;
>for (i = X_MAX*Y_MAX*Z_MAX; i; i--) {
>とすると、速くなるのでしょうか?
アセンブラレベルの話になりますが、
CPUの命令は、ある値とある値が等しいかを比べる命令が無いか,
あってもある数値が0かどうかを調べる命令より実行速度がたいてい遅いからです。
(命令が無い場合は引き算をして、結果が0かどうかを調べるという、二つの命令を実行することになります)
ただ、コンパイルしてアセンブラになる時に
どんな命令になるかはわかりませんから、
必ずしも速いとは言い切れません。
現在のコンパイラは最適化といって、
こういう高速化のための小細工は勝手にやりますので。
terra5さん、詳しい解説ありがとうございました.
「処理はコンパイラが最適化する」とのことですが、
処理の高速を考える際は,どのような観点から
コードを組めばよろしいのでしょうか??
よろしくおねがいします!!
No.5
- 回答日時:
int aa[X_MAX][Y_MAX][Z_MAX];
int *p = (int *)aa + sizeof (aa) / sizeof (int);
while (p != (int *)aa)
*--p = 10;
怒られそうだ(笑)
No.4
- 回答日時:
No.2 の回答にある
>「見やすさを優先するためのプログラミングをした方が良いと思います。」
に大きく同意しつつ、もうちょっと早そうなコードを。
int aa[X_MAX][Y_MAX][Z_MAX];
int* p = &aa[0][0][0];
int* p_end = &aa[X_MAX][Y_MAX][Z_MAX];
while (p != p_end) {
*p++ = 10;
}
もし、
int* p_end = &aa[X_MAX][Y_MAX][Z_MAX];
が気持ち悪いのであれば、
int* p_end = p + X_MAX * Y_MAX * Z_MAX;
でも OK 。
# この程度のサイズなら、たいした差は出ないと思いますよ。
a-kumaさん、名前によらず天使のようなアドバイスありがとうございます!
>int* p_end = &aa[X_MAX][Y_MAX][Z_MAX]; (1)
>が気持ち悪いのであれば、
>int* p_end = p + X_MAX * Y_MAX * Z_MAX; (2)
僕の場合、なぜか(1)の方の初期化の方がしっくりきてしまいました。
(2)のような初期化はたいへん参考になります。
どうもありがとうございました!
No.2
- 回答日時:
見やすさを優先するためのプログラミングをした方が良いと思いますよ。
コンパイラの最適化によってあまり速度差がでないこともあります。上限の決まっている領域の初期化は、for文かwhileを使うのは仕方ないことでしょう。それをふまえて、ポインタを使うと次のような感じで出きると思います。
int *p;
int aa[X_MAX][Y_MAX][Z_MAX]; // 折角defineしているのだから、定数を使いましょう
int i;
p = (int*)aa;
for (i = 0; i < X_MAX*Y_MAX*Z_MAX; i++) {
*p++ = 10; // 10.0は浮動小数です
}
ですか、ね。
yatokesaさん、お返事ありがとうございます。
>見やすさを優先するためのプログラミングをした方が良いと思いますよ。
ごもっともですが、僕のプログラムはまだまだです。
細かい点も注意して頂きありがとうございます。
PS。yatokesaさんがプログラムを組む上で、または勉強した本やサイトの
中で推薦できるものがあったら教えて頂きたいのですが。。
僕は、一般的なC言語本にあるサンプルコードのような
レベルなのでなんとかその域から脱却したのですが。
No.1
- 回答日時:
こんにちは。
int 型なのに、10.0 入れてはいけませんよ。(^o^)丿
さて、配列の場合は、基本的にはリニアにメモリを確保されることになります。
ですから、
#define X_MAX 10
#define Y_MAX 20
#define Z_MAX 5
int main(int argc , char ** argv)
{
int i;
int aa[10][20][5];
int *p ;
p = (int *)aa ;
for (i = 0; i < X_MAX * Y_MAX * Z_MAX; i ++) {
*(p++) = 10 ;
}
return 0;
}
でOKだと思います。
ただ、このリニアにとられるというのは、どんなときにもとは行かないので、アーキテクチャを確認する必要はありますね。
Wintel 系だったら大丈夫だと思いますが。
fuji1さん早速の解答ありがとうございます。
御返答の内容について質問があります。
>配列は、基本的にはリニアにメモリを確保されることになります。
つまり、malloc()関数を用いたときと
異なり、連続的にメモリが確保されるというこですね?
>ただ、このリニアにとられるというのは、どんなときにもとは行かないので、
>アーキテクチャを確認する必要はありますね。
↑のことがよくわかりません。
リニアに確保できないarchitectureとは例えばどのような
構造でしょうか?
よろしければついでに教えて頂きたいのですが・・・
>Wintel 系だったら大丈夫だと思いますが。
Pentium 3を使っています.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数桁10進数の*桁目だけを抽出...
-
C言語での引数の省略方法
-
「指定されたキャストは有効で...
-
#define _CRT_SECURE_NO_WARNIN...
-
(int *)の意味
-
C言語 配列と関数の練習問題
-
if と配列の組み合わせ
-
構造体の勉強中です 合計点の高...
-
ラップ関数とはどんなものですか?
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
【C++】関数ポインタの使い方
-
C言語 巡回セールスマン問題 2-...
-
C言語初心者です、、、お助けく...
-
ColorをRGBで指定する方法
-
プログラミングです。 行列要素...
-
商と剰余を同時に求める(C言語)
-
シグマ公式・・・C言語
-
acceptをalarmでタイムアウトさ...
-
systemの戻り値を取得する方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
std::set<int> で、ある値が何...
-
C言語 エラーの原因がわからな...
-
c言語
-
system関数がうまくいかない
-
C++でvectorにテキストファイル...
-
acceptをalarmでタイムアウトさ...
-
if と配列の組み合わせ
-
return 1L
-
「{ } で囲むだけ」は正しい?
-
(マルチスレッド)_beginthrea...
-
PowerShellがうまくいかない
-
このプログラミング誰か教えて...
おすすめ情報