[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 05/09 08:32 / Filesize : 231 KB / Number-of Response : 986
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

スレを勃てるまでもないC/C++の質問はここで 10



1 名前:デフォルトの名無しさん mailto:sage [2009/05/14(木) 20:35:36 ]
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。

過去ログ
スレを勃てるまでもないC/C++の質問はここで
pc11.2ch.net/test/read.cgi/tech/1167476845/
スレを勃てるまでもないC/C++の質問はここで 2
pc11.2ch.net/test/read.cgi/tech/1178503366/
スレを勃てるまでもないC/C++の質問はここで 3
pc11.2ch.net/test/read.cgi/tech/1187521676/
スレを勃てるまでもないC/C++の質問はここで 4
pc11.2ch.net/test/read.cgi/tech/1221633708/
スレを勃てるまでもないC/C++の質問はここで 5
pc11.2ch.net/test/read.cgi/tech/1230516307/
スレを勃てるまでもないC/C++の質問はここで 6
pc11.2ch.net/test/read.cgi/tech/1231564903/
スレを勃てるまでもないC/C++の質問はここで 7
pc11.2ch.net/test/read.cgi/tech/1232983248/
スレを勃てるまでもないC/C++の質問はここで 8
pc12.2ch.net/test/read.cgi/tech/1235921779/
スレを勃てるまでもないC/C++の質問はここで 9
pc12.2ch.net/test/read.cgi/tech/1240022781/

554 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 03:49:46 ]
go to文は有害だよ
どんなネストごちゃまぜなソースでもちゃんと普通に抜けだすコード書いたほうがいい
go to文はあとから見た時可読性が著しく落ちる まじで

555 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 03:53:11 ]
その部分をまるっと関数化してreturnで抜けだすのと
gotoにそこまで違いがあるのかどうかw


556 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 04:01:36 ]
for(a<3){ for(b<20){
if(){if(hensu){}else{},a=3;continue;}
}} // bループの外に処理があるなら }if(a<3){ }}


で十分じゃないの?

557 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 04:02:07 ]
>>554
フラグ変数とか多用されるよりgoto使ってくれた方が追うの楽だし、
そもそもgotoつかえば深いネストしなくて済むことも多い。

558 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 04:05:36 ]
フラグ変数を使って深いループを抜ける事は、仮想関数を
使うべき所にswitch文やif文で多重にネストした醜いプロ
グラムを連想させる

559 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 04:18:03 ]
質問。
あるクラスから派生したクラスを作るとき、その派生クラスを強制的にシングルトンにさせる方法ってありますか?
派生クラスに自前でシングルトンパターンを実装するしかないのでしょうか?

>goto
まあ俺みたいな初心者は
少しは綺麗になるかも?と思ってもgotoを使わない方向で書いた方が安全ってことだな!


560 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 06:19:47 ]
gotoが必要になる事ってほとんど無いんだけど。
ちゃんとクラス設計しているのか?
・・・と思ったが、C言語の場合はクラス設計もクソもないな。

561 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 06:26:12 ]
gotoも使いようだよ
ifとかwhileで書けるなら、gotoでなくそっちを使うべき、ってだけ

いずれにせよクラスは関係ないな

562 名前:デフォルトの名無しさん [2009/06/02(火) 07:30:53 ]
>>545
最初っから読んだが載って無いな
悪書なのは分かったが買ったからには100%使う予定

で、メモ帳はテキストエディタっていう程だからプログラムを実行出来るんだよね?ググっても良く分からんのだよorz



563 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 07:37:44 ]
>>562
じゃぁ、初心者向けの本じゃ無かったんだろ。
自分のレベルにあった本を買えるようにしような。

564 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 08:04:55 ]
もっと高級なテキストエディタじゃないと実行できないんだよ。

565 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 08:14:21 ]
>>582
C言語なら、コンパイラというプログラムが必要だ。それをつかえ。
コンパイラにも色々種類があるが、C言語用のコンパイラな。

566 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 08:48:14 ]
>>564
嘘は言っていないから困る

567 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 09:54:40 ]
まあ基本は、「エディタは編集するものであって実行するものじゃない」

568 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 12:38:23 ]
>562
念のため、本のタイトルを。

569 名前:デフォルトの名無しさん [2009/06/02(火) 12:59:30 ]
わかた
コンパイラは自力で探してみる

因みに購入したC言語本は
www.amazon.co.jp/gp/aw/d.html/ref=mp_s_a_1/376-2471770-0113248?qid=1243914976&a=4797327928&sr=1-1
コンパイラについて書いて無かった気がしたけどなぁ

570 名前:デフォルトの名無しさん [2009/06/02(火) 13:00:55 ]
あ、コンパイラはC++用でもおKなの?


571 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 13:02:32 ]
/                     \
              、   ヽ\    ヽ
. /  , /    !    ∨丁ヽ い   |    /二フ”
/  ! |   ィ 「\   | ハ   l |   ,′    /
l   ! | / /j/   '.  ノ, =、!// /j/      ヽ/
l   い/ ,, =x j/ ′   〈j/       /ヽ
ト ._  \_〃         :.:.:.:.}           /二フ”
l l { 下 ̄ .:.:.:.:  -‐1   ∧          /
l l T ‐个 ._     ー'  イ l|         ニニ!
l/ /|  l l//下二千ヽ_l い          ─┘
' / .′ l,ノ\/// 小、|、\ヽ\          「〉
Ul  /  / \/ U` \ヽl i      r_|
Ul l    i      !   ト ヽ |


572 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 13:29:57 ]
>569
ちょっと軽く評判を調べてみたんだけど、「実行する方法が書いてない」「やたら間違ってる」なんて話がチラホラあった。
1から読み直せとか、さんざん疑ってしまってスマン。




573 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 13:31:19 ]
>>571 質問者はケータイみたいだし、AAでの返答はしないほうがいいんでね?

574 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 13:37:19 ]
>>570
今のC++コンパイラはたいていCも扱える

575 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 13:39:07 ]
やっぱりぼうようか

576 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 13:42:25 ]
>>573
もともと >>571 に、真面目に答える気があるとも思えん。

577 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 14:08:56 ]
これは酷い
labaq.com/archives/51093225.html

578 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 14:12:23 ]
夏休みまだだよな?

579 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 14:13:22 ]
年中夏休みですがなにか

580 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 14:25:09 ]
VB、C#、C++だと.NETフレームワークの使い方って全然違ってくる?
.NETフレームワークの用途毎の使い方が載ってる本がほしいので
「.NET Frameworkプログラミングテクニック―for Visual Basic/C#」
を買おうかと思うんだが今使ってる言語はC++なんだ・・・

581 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 14:46:50 ]
C#がいいお

582 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 14:51:25 ]
>cat test.cpp
#include <iostream>
template <typename _T>
struct base { typedef size_t size_type; };
#ifdef CANNOTCOMPILE
template <typename _E>
struct A:base< A<_E> >{
#else
struct A:base< A >{
#endif
  size_type s;
};
#ifdef CANNOTCOMPILE
  typedef A<int> type;
#else
  typedef A type;
#endif
int main(void)
{
  type a;
  a.s = 10;
  return 0;
}
>g++ test.cpp
>g++ test.cpp -DCANNOTCOMPILE
test.cpp:10: error: ‘size_type’ does not name a type
test.cpp:10: note: (perhaps ‘typename base<A<_E> >::size_type’ was intended)
test.cpp: In function ‘int main()’:
test.cpp:20: error: ‘struct type’ has no member named ‘s’

頭がこんがらがってよくわからなくなってしまったのですが、
テンプレート版でsize_typeが継承されてないのはなぜでしょうか?



583 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 15:31:35 ]
public base

584 名前:デフォルトの名無しさん [2009/06/02(火) 15:31:42 ]
マイクロソフトの最新版らしいので安心して使用してみます

べっかんこから見ているのでAAも安心です

では、おいとまさせて頂きます

585 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 15:33:26 ]
おとこは黙ってVisual J

586 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 16:33:41 ]
涙で>585が見えない


587 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 16:55:46 ]
>>569
amazonの中身が読める所だけみたが
3ページの上の方に、プログラムの実行方法は
「処理系や実行環境によって異なりますから
みなさんが利用している処理系のマニュアルなどを参照してください」
と書いてある

まぁ、完全な初心者にはそもそも「処理系」って何?ってなるから
これじゃつまづくな

588 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 18:56:19 ]
訳語の「処理」が大外れではないけど意味を採り難い語だからね

「処理乾酪」でヤバさ倍増な感

589 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 19:33:34 ]
>>580
ライブラリ自体の使い方は同じだから、そういう目的ならVB/C#向けでも構わないと思う。

590 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 21:39:01 ]
同じ名前のメンバ変数を持ってるクラスを継承しちゃったらどうなるの?

591 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 21:50:55 ]
>>590
継承の仕方による。

多重継承ならスコープ解決演算子で名前解決することになる。

多重継承でなく、単一の継承を繰り返した場合は
派生クラスのメンバ変数の名前が基底クラスの
メンバで同名なものを「全て」隠蔽する。

これ以上は、実例を挙げるのがめんどくさいので、誰かよろしく。

592 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 23:34:12 ]
すいません、VS2005で外部ライブラリをソースコードの中に記述して取り込む方法をど忘れしてしまいました、教えてください。



593 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 23:37:41 ]
絶対ど忘れじゃねーだろwwwww

594 名前:デフォルトの名無しさん mailto:sage [2009/06/02(火) 23:40:00 ]
pragman

595 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 00:06:16 ]
そうだった
#pragma comment(lib,"ws2_32.lib") これでよかった、thx>>593ぶた野郎

596 名前:デフォルトの名無しさん [2009/06/03(水) 06:42:31 ]
メモリ上のポインタをファイルポインタで開くことはできますか?

597 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 06:58:06 ]
できません

598 名前:582 mailto:sage [2009/06/03(水) 16:54:38 ]
よろしくお願いします。

599 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 17:59:15 ]
すまん質問させて貰う

下のように定義した関数があり
void funcA( const char *pszA, const char *pszB, const char *pszC );

funcBで色々と処理した後に、funcB内でfuncAを呼ぶと
pszBとpszCのアドレスが変わってしまう

pszBに渡されるアドレスが本来0x1000だとすると、0x1200となる
デバッガで渡される直前の中身と、funcAで受け取った中身が違ってるのも確認済み
これの原因で考えられるのはメモリ破壊のみだろうか?
funcAとfuncBは別々のモジュールで実装されているんだが
WinMainを呼んで他に処理をする前に
すぐにfuncBを呼んでも、同様の現象が起きてる

そこの機能だけを一つに纏めて実験すると問題無く動作する
IDEはVC++2008 ExpressEdtion

正直訳が分からない。よろしくお願いします。

600 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 18:27:56 ]
char const * (const char *)
const なcharへのポインタ。アドレスは変わっても良い。データはconst。

char * const
charのポインタがconst。アドレスはconst。データは変わってもよい。

char const * const (const char * const)
const な char のポインタがconst。アドレス、データ共にconst

601 名前:599 mailto:sage [2009/06/03(水) 18:51:25 ]
自己解決した

構造が
main.cpp
dialog/dialog.cpp
shell/shell.cpp
resource/resource.cpp
という風にモジュール分けしてて

funcB内で別のモジュールの処理を呼ぶんだが
そのモジュール(funcB内で呼ぶ処理)自体は結合度が凄い低い

そのモジュールのヘッダに
#include "../hogehoge.h"
とアプリ全体の共通ヘッダをインクルードしたら解決した

そのモジュール自体、他の機能全く使わないのに
何でこれで解決するのかが分からないが…

スレ汚しすまない

602 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 18:56:43 ]
>>601
アドレスは変わっても良いってコンパイラに伝えてるんだから、当然アドレスはいつか突然変化する。
今回変わらなかったのは単なる偶然。



603 名前:599 mailto:sage [2009/06/03(水) 19:17:16 ]
例えば
void func( const char *pszHoge )
と定義して

char szHoge[] = "hogehoge";
szHogeのアドレスが0x1000として
func( szHoge );
とすると、func側のpszHogeは必ずしも0x1000ではないって事?
同じアプリのメモリ空間だから、アドレスが変わるっていうのは知らなかった

でも、今回のはアドレスも変わって、中身も変わってた

604 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 19:18:46 ]
すまん、記述ミスがあった
×pszHogeは必ずしも0x1000ではないって事?
○pszHogeが指すアドレスは0x1000ではないって事?

605 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 19:23:39 ]
>>600参照。
const char*だと、アドレスは変わる。
ついでに>>603だと宣言の時点でconstついてないから中身も変わる。
コンパイラによって保証されるのは、funcがpszHogeの中身を変えないことだけ。

606 名前:599 mailto:sage [2009/06/03(水) 19:45:18 ]
>>605
有難う
ポインタで渡す限りアドレスは固定だと思ってたが、違うのか
今日アドレスと中身も変わったが、相当レアなケースに遭遇したみたいだ
>>600は凄い参考になった。有難う

607 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 19:53:48 ]
ポインタ変数だろうがint型の変数だろうが関数に渡した値が勝手にかわってたらおかしいだろw

608 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 20:18:16 ]
C++でゲーム開発してるんですが、敵ユニットや弾をリスト構造を用いて実装しました。
しかし、これらのオブジェクト同士の当たり判定の実装で詰まってしまっています。
解決策を知っている方が居たらお願いします。

それが駄目でも、二つの双方向リストを総当りで比較する方法などありましたらお願いします。

609 名前:デフォルトの名無しさん [2009/06/03(水) 20:24:55 ]
>>608
サンプルプログラムそこらじゅうに転がってるからてきとーに参考にすりゃいいだろ

総当りの方法って、先頭から順番に見ていきゃ言いだけだろ



610 名前:582 mailto:sage [2009/06/03(水) 22:23:15 ]
VC++2008 EEで試してみたところ、どちらのバージョンでも問題なくコンパイルされてしまいました。
動作も期待(?)通りです。お騒がせいたしました。

611 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 22:25:31 ]
だめだったのはやっぱBCC無料版だったりするんだろうか

612 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 22:38:02 ]
>>609
まぁ、ゲームの場合速度が重視されるから単純な総当たりなんてやらないで
エリアを区切ってエリア単位で総当たりの判定するけどな。



613 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 22:42:02 ]
まずすべてのオブジェクトの座標を確認して
適当な範囲ごとにソートして、それからその範囲内で当たり判定を行うってことかしら?
範囲の境界に位置するようなオブジェクトの場合はどうしたら…

614 名前:デフォルトの名無しさん [2009/06/03(水) 22:42:52 ]
>>613
どっちでもいい、処理を減らすことが目的だから

615 名前:デフォルトの名無しさん [2009/06/03(水) 22:43:36 ]
いや違うな
>>613じゃ根本的に間違ってる

616 名前:デフォルトの名無しさん [2009/06/03(水) 23:35:00 ]
for(n=1; n<=100; n++){
sum += n;
printf("1+2+...+100=%d\n",sum);
}

{ }をつけると、1、1+2、1+2+3、・・・、1+2+…+100までの答え、
{ }を外すと単なる1+2+…+100の答えが出るのですが、
これはなぜですか?

本には{ }内に1つの文しかないときには{ }を省略できるとだけ書いているのですが
ここで{ }を省略するかどうかというのは重要な問題だと思うのですが

617 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:39:11 ]
{} を省略した場合は

for(n=1; n<=100; n++){
 sum += n;
}
printf("1+2+...+100=%d\n",sum);

って書いてあるのと同じ意味になるから。

618 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:41:42 ]
> 本には{ }内に1つの文しかないときには{ }を省略できるとだけ書いているのですが
だから、{ }がなければ
for(n=1; n<=100; n++){
sum += n;
}
printf("1+2+...+100=%d\n",sum);
とみなされる。

619 名前:616 [2009/06/03(水) 23:42:47 ]
>>617
なるほど!
1つの文しかないときは{}を省略できるってのは、
条件式が1つの場合、って解釈してたんですが
printfも何もかも含むんですね!わかりやすい説明ありがとうございます

620 名前:616 [2009/06/03(水) 23:44:20 ]
>>618
ありがとうございます!

621 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:44:21 ]
関数で値渡しをするときに配列の要素全てを渡すことは出来ますか?
それともそれぞれ引数に指定しないとダメでしょうか

622 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:47:37 ]
;が文の終わり。日本語の句点のような存在。
だからsum += n;で1つの文。

{}はその例外で、囲った部分全体で1つの文になる。 すまん話し過ぎたか。



623 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:51:15 ]
>>621
C++ なら vector を使えばいいです。
Cでは直接配列を値渡しすることはできないので、
構造体の中に入れて、構造体を値渡ししましょう。

624 名前:デフォルトの名無しさん mailto:sage [2009/06/03(水) 23:56:06 ]
>>623
アリガトゴザイマす

625 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 04:23:23 ]
初心者です。

Cの参考書でメモリ関連の事が良く出てきます。

バイトとかビットとか2進数、10進数とか出てきますけど、これらはスルーしても
良いんでしょうか?

HTMLで例えるなら#ffffffみたいな感だったので・・・。
これは覚えたほうがいいんでしょうか。
わけわからないんですが

626 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 04:54:02 ]
スルーしちゃらめぇ。

627 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 06:24:57 ]
>>625
C言語はそう言うのを扱うのが醍醐味というか、
それが分からないと全然まともに使えないと思われる。

理系なら分かるでしょ?がんばれ!

628 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 07:46:11 ]
授業で言うなら、最初の3回くらいまでは知らなくてもなんとかなりそうな気はするけど
せいぜいそれくらいだよなあ。

629 名前:デフォルトの名無しさん [2009/06/04(木) 17:39:26 ]
C++の質問です。

あるクラスの、あるメンバ関数からしか参照されないことが分かっている変数があるとします。
この関数が呼び出されたあとも、変数の内容を保持したい場合は、どのようにするのがスマートでしょうか?


 ・メンバ変数にする
     → 数が多いと、ヘッダに書く量が増えて見通しが悪くなるかも?

 ・呼び出し側で変数を用意しておき、引数でその都度渡す
     → 呼び出し側の手間が増える。数が多いとかなり大変。

 ・staticを付ける
     → オブジェクトごとに個別の値を持てなくなる

630 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 17:42:17 ]
そのときの変数の性質や役割による。 手間隙とかは関係ない

631 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 17:50:18 ]
ああごめん、途中で質問を書き直したら
頓珍漢な内容になってました。

以下の3パターン以外に方法はないのでしょうか、で。
思いついた3つのうち、いずれの方法を取るにしても何らかの欠点があるので。


632 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 17:57:18 ]
制約がないなら好きにすればいい



633 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 17:58:41 ]
>>629
 ・メンバ変数にする
     → 数が多いと、ヘッダに書く量が増えて見通しが悪くなるかも?
これがやっぱり一番自然でしょ。
と俺は思う。
いくつあるのかしらないが、そんなに多いならクラス内クラスを作るとかすれば?


634 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 17:58:43 ]
・関数オブジェクトを用いる。

635 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 18:08:35 ]
C言語勉強中なんですが、宿題で
「ファイル名を自分で設定しそのファイルに、EOFを行うまで
スペース区切りの二つの整数を何回でも入力できるようにし、
それをファイルに改行して記録しなさい」
というのがあり、
#include <stdio.h>
int main()
{
int a,b;
FILE *fp;
char name[100];
printf("ファイル名を入力してください\n");
scanf("%s",name);

fp=fopen(name,"w");
printf("数値を入力してください\n");
while(scanf("%d %d",&a,&b)!=EOF){
scanf("%d %d",&a,&b);
fprintf(fp,"%d,%d\n",a,b);
}
fclose(fp);
return(0);
}
というプログラムを作ったんですが、なぜか
数値を入力した際に記録される時とされない時があります。。。。
どなたか解決策を教えていただけないでしょうか?

636 名前:デフォルトの名無しさん [2009/06/04(木) 18:36:32 ]
スレの皆様に質問です。
8ビットbitmapファイルを読み込み、各ピクセルに演算を加え、別ファイルとして出力するプログラムを作っています。
演算結果をint型の変数ifooに格納し、unsigned char型にキャストしてputしています。
ifooがunsigned char型の範囲外の値の時は、範囲の端の値を代入しています。

//fin,foutのファイル上の位置は適切な場所にあるとする
for (int y=0 ; y<height ; ++y){
  for (int x=0 ; x<width ; ++x){
    int ifoo = fin.get()*A+B;
    if(ifoo<0) ifoo=0;
    if(ifoo>255) ifoo=255;
    fout.put((unsigned char)ifoo);
    ++i;
  }
  //bmpファイルの幅は4の倍数ピクセルとする
}

先輩が組んだプログラムはこれの2倍以上速いのですが、AとBがハードコードされていて
ソースコードは失われ、先輩本人は行方知れずです。。。
そのためA,Bを引数で与えられるように、イチから再作成しています。
1000x1000pxのBMPを一度に数千枚〜数万枚単位で処理するため
このループ部分をもっと高速化したいです。何か良いアイデアは無いでしょうか。
ちなみにこの部分以外に目立ったループ箇所は無いです。


637 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 18:48:13 ]
>>636
1. ループの中で ファイルIOするのは遅すぎるので、
一度メモリに全部読み込んでから変換→ファイルに書き出しを行う。
(全部読み込めないほどメモリが少ないのなら、一部ずつとか)

2. SIMDで複数pixelを同時に処理するか、OpenGL or DirectXのpixelシェーダ書く

638 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 20:50:01 ]
>>637
早速ありがとうございます。とりあえず1を試してみます。

環境書き忘れて申し訳なかったですが、Windowsのプロンプトから呼ぶプログラムをgccで作っています。
2の手法はVisualStudio等を使って行う方法でしょうか?
そのうち勉強してみたいと思います。

639 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 20:56:08 ]
>>638
インラインアセンブラ

640 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 20:57:00 ]
と外部ライブラリ

641 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:17:36 ]
usingを解除することはできますか?
namespace {
using foo::CFoo;
class CBar {
public:
void hoge(CFoo);
};
}
みたいにやってるんですが副作用があるのかどうか気になってます

642 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:21:29 ]
>>638
最近だとインラインアセンブラのほかに<emmintrin.h>なんかの組込関数という手もある。
いずれにせよgccでも使える。



643 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:23:37 ]
まぁまずないとは思うけど最適化オプションの存在は知ってるよね?

644 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:37:23 ]
>>635

while(scanf("%d %d",&a,&b)!=EOF){
 fprintf(fp,"%d,%d\n",a,b);
}

としてみるべし

645 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:40:54 ]
デートは家でまったりしたいのですが
女性から見ればNGですか?

646 名前:デフォルトの名無しさん [2009/06/04(木) 21:43:37 ]
Rubyを教えてくれるならOK

647 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:43:39 ]
>>645
死ね

648 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 21:44:20 ]
>>645
誤爆サーセン

649 名前:636 mailto:sage [2009/06/04(木) 22:05:38 ]
>>639
アセンブラはマイコンで少々やったことがあるので挑戦してみます。
ただ後年に後輩が読めなそうなので、教授が許してくれなそう・・・orn
>>>640
外部ライブラリというと、そういう処理が高速にできる
ライブラリを他から持ってきちゃえということでしょうか?
>>643
恥ずかしながら知らなかったです。
軽くググってみて、とりあえず -O3 をつけて変化を観察することにします。

プログラムを大学に置いてきてしまったので、有意な変化があれば明日報告します。
皆様アドバイス有難う。

650 名前:デフォルトの名無しさん mailto:sage [2009/06/04(木) 22:46:58 ]
あと、流行りの並列処理も最近のコア沢山なCPUには効くぞ。
gccならOpenMPが使えるし。

651 名前:636 mailto:sage [2009/06/05(金) 14:13:30 ]
>ループの中で ファイルIOするのは遅すぎるので
>一度メモリに全部読み込んでから変換→ファイルに書き出しを行う。
new で uint8(unsigned char)型の readbuf,writebuf を、int型のcalcbufを確保し
以下のように書き換えたところ、>>636より約6倍も高速化しました。

fin.read((char*)readbuf,width*height);
int i=0;
for( int y=0 ; y<height ; ++y){
for( int x=0 ; x<width ; ++x){
calcbuf[i] = readbuf[i]*A+B;
if(calcbuf[i]<0) writebuf[i]=0;
else if (calcbuf[i]>255) writebuf[i]=255;
writebuf[i] = (uint8)calcbuf[i];
++i;
}
//bmpファイルの幅は4の倍数ピクセルとする
}
}
fout.write((char*)writebuf,width*height);


○vector<uint8> foo でバッファを確保した場合 read()にchar* が渡せないからダメ。
 という判断から、バッファはnewで確保しました。
○ループ中の2回のif文をelse if でまとめ、比較演算回数の減少を図りました。
 (気休め程度だと思ったので、これ単体の効果は未計測)

「先輩と互角」という目標を軽くクリアし、先輩の倍以上高速なプログラムになりました。
最適化オプション、インラインアセンブラ、並列化等もこれから試してみたいですが
目標クリアしたためとりあえず質問は終了させて頂きます。
スレの皆様ありがとうございました!

652 名前:デフォルトの名無しさん [2009/06/05(金) 14:20:51 ]
アセンブラ化は効果なし。 
もっとも時間かかるのはディスクアクセス。
Windowsであれば、Noバッファリングで読み込んでみて。
バッファリングありより倍以上の速度になる。
あと、一度にたくさん読み込んでも逆に遅くなる。
100M読み込むより、4Mや2Mずつのほうが速い。
データが仮想メモリ(HDD)に移動してしまう可能性が高い。
自分の環境では4M以上は速度は上がらなかった。



653 名前:デフォルトの名無しさん [2009/06/05(金) 14:24:21 ]
ちなみに一度に一斉に書くのも遅くなる。 
メモリ不足になるという理由で。
入出力バッファは、1M〜4Mくらいにして、使い回すのが吉。

654 名前:デフォルトの名無しさん mailto:sage [2009/06/05(金) 14:27:13 ]
並列化もきっと意味ないだろうなぁ






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<231KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef