1 名前:デフォルトの名無しさん [2010/03/05(金) 16:51:13 ] エスケープシーケンスやWin32APIなどの環境依存なものでもOK。 ただしその場合、質問者は必ず環境を書きましょう。 ※sage禁止です(と代々スレに書いてありますが自己判断で)。 【前スレ】 【初心者歓迎】C/C++室 Ver.71【環境依存OK】 pc12.2ch.net/test/read.cgi/tech/1264774545/ 【アップローダー】(質問が長い時はココ使うと便利) kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め) ◆ソースのインデントについて 半角空白やTABでのインデントはスレに貼ると無くなります。 そのため、アップローダーに上げるのも手ですが直接貼る場合は、 全角空白か に置換すると見栄えだけはよくなります。
475 名前:デフォルトの名無しさん [2010/04/18(日) 11:41:36 ] スレ違いならごめんなさい C言語で日本語が表示されるプログラムを作ったのですが、コマンドプロンプトでそのプログラムを実行しても日本語が表示されません(記号と変な文字のオンパレードになります)。どうやったら日本語で表示されるのでしょうか? ちなみに参考書の通りプログラムを書いているので、間違いというのは無いはずです
476 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 11:49:50 ] >>475 ソースコードを保存するときの文字コードをシフトJISにしてみるとか
477 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 12:02:51 ] .NETを使った記述もここでOKでしょうか?(ダメなら誘導してください) 2005 C++ WinXP SP3 Form1、Form2と作成し、Form2内部で実処理部分を関数で呼び出しています。 Form1からはForm2を呼び出せるのですが、実処理部分の関数からForm2を呼び出すことができません。 Form2^ ff = gcnew Form2(); としていますがこれがコンパイルエラーとなります。 (error C2065: 'Form2' : 定義されていない識別子です。) Form1からは同じ宣言で呼び出せるのですが・・・ 助言をお願いします。
478 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 12:11:19 ] >>477 #include "Form2.h"
479 名前:477 mailto:sage [2010/04/18(日) 12:24:15 ] >>478 includeはしています。 (確かにincludeの順番でエラーを吐いたりもするので関連しているようにも思います)
480 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 16:10:38 ] >>477 よう分からんけどForm2が定義されてる名前空間と 実装処理部の名前空間が違うんじゃない?
481 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 16:39:17 ] インクルードがループしてるんじゃないか
482 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 21:42:57 ] >>477 Form2を定義している名前空間をそのnewしてるトコで参照してない希ガス 或いは参照してるつもり->スペルミスとか
483 名前:デフォルトの名無しさん mailto:sage [2010/04/18(日) 22:16:43 ] Form1.hでForm2.hをインクルードして Form2.hでForm1.hをインクルードしているのでは?
484 名前:477 mailto:sage [2010/04/18(日) 22:33:07 ] >>480-483 ありがとうございます。 >>481 さんの助言をもとに色々と調べた結果、Form2と実処理の関数の間で循環参照が起きてしまっています。 (>>483 さんのおっしゃられているとおりです) 実処理の関数はForm2の実行ボタンを押したときに実行するようになっており、 その実処理の進捗をForm2内のLabelやProgressBarに表示したいのですが、 根本的に考え方が間違ってますかね? Form2内でLabelやProgressBarにアクセスする関数を宣言して、実処理関数の中で使いたいのですが・・・
485 名前:デフォルトの名無しさん mailto:sage [2010/04/20(火) 21:46:40 ] windows7のvisualstudio2008でgdi+をインクルードするとエラーの嵐なんですが、なんとかなりませんか?
486 名前:デフォルトの名無しさん mailto:sage [2010/04/22(木) 09:59:27 ] >>485 VisualStudioスレへどうぞ。 >>484 C++/CLIスレへどうぞ。
487 名前:デフォルトの名無しさん mailto:sage [2010/04/22(木) 19:52:22 ] 誘導するだけならこのスレ不要だな
488 名前:デフォルトの名無しさん mailto:sage [2010/04/22(木) 19:56:06 ] そんなこと言ったらこの社会の大部分は不要になるぞ 適切にたらいまわしてくれる人も必要なんだよ
489 名前:デフォルトの名無しさん mailto:sage [2010/04/22(木) 19:56:43 ] >>488 たらいまわしじゃねーよ
490 名前:デフォルトの名無しさん mailto:sage [2010/04/22(木) 20:06:04 ] 誘導だよな。 何でC/C++スレで、関係ない言語の話やソフトウェアについて話をしたがってるんだっていう。 肉屋で野菜や包丁買おうとしてるのが普通に思えるんだろか。
491 名前:デフォルトの名無しさん mailto:sage [2010/04/22(木) 20:10:21 ] >>490 初心者歓迎、環境依存OKを謳っているスレでそれは言いすぎ 単に、より適切な回答がつきやすいスレに誘導したほうがお互い効率的だという だけの話
492 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 22:40:51 ] template<class T> struct identity { typedef T type; }; このメタ関数は何のために存在するんですか?
493 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:26:15 ] >>492 template<class T>cast(typename identity<T>::type v){ return v; } とか typedef boost::mpl::eval_if<is_const<T>, identity<const int>, identity<int> > iint; とか
494 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:31:17 ] 横槍レスだが >>493 相変わらずC++ TMPは難しすぎだろ
495 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:35:48 ] ・eval_ifに渡すラッパー ・変数宣言 ○int *p1, *p2; ×int* p1, p2; ○boost::mpl::identity<int*>::type p1, p2; ・メタ関数をつくるヘルパ(例:osteram等から同じ文字型とTraitsのbasic_stringをつくる、strメタ関数 template<typename Stream> struct str : public boost::mpl::identity< std::basic_string<typename Stream::char_type, typename Stream::traits_type> > { };
496 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:39:04 ] すまんtypo ×osteram ○ostream
497 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:48:41 ] なるほどぉthxですた、でも template<class T>cast(typename identity<T>::type v){ return v; } これがちょっとわからなかった
498 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:52:02 ] >>493 自分で書いておいてなかなかひどい template<class T> T cast(typename identity<T>::type v){ return v; }と typedef boost::mpl::eval_if<is_const<T>, identity<const int>, identity<int> >::type iint; だな 前者はTの型の推論ができなくなる(=明示的に型を指定してほしい関数に使える) template<class T>void f(T v); char c; f(cast<int>(c)); 的な
499 名前:デフォルトの名無しさん mailto:sage [2010/04/23(金) 23:52:26 ] >>495 なーーーるほど!! いやー、気がくるっとルなぁ
500 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 19:32:40 ] virtualメソッドに実行時コストがあるのは関数ポインタ経由してるから、とかるんですが virtual継承にも実行時コストがあるのはなぜ何ですか? コンパイル時に解決出来そうな気がするんですが
501 名前:477 mailto:sage [2010/04/25(日) 19:56:38 ] >>486 誘導ありがとうございます。 行って参ります。
502 名前:デフォルトの名無しさん mailto:sage [2010/04/25(日) 23:07:04 ] >>500 解決できそう? #include <iostream> #include <vector> class Animal { public: virtual void bark() { }; }; class Dog : public virtual Animal { public: virtual void bark() { std::cout << "bow wow" << std::endl; } }; class Cat : public virtual Dog { public: virtual void bark() { std::cout << "meaow" << std::endl; } }; int main() { std::vector<Animal*> animal; animal.push_back(new Dog()); animal.push_back(new Cat()); animal[0]->bark(); // Dog animal[1]->bark(); // Cat }
503 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 02:46:24 ] なにその猫こわい
504 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 03:57:09 ] 凡ミスがこんなに怖いとはw
505 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 05:32:17 ] ワロタ
506 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 05:56:15 ] 違うよ全然違うよ凡ミスじゃないよ犬だってネコにもタチにもなりうるんだよ じゃなくて、virtual継承が仮想継承のことを言っていると見せかけて 実は仮想関数のオーバーライドを指してるんじゃないかと思ったから 両方入れてみたんだよ
507 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 06:28:24 ] 我が輩は猫であるが犬でもある。名前はまだ無い。
508 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 07:50:34 ] >>502-503 の流れでワロタwwww >>506 それはわかったけど、クラス名のチョイスがじわじわ来た
509 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 09:32:24 ] 今は亡き加藤和彦が木村カエラをボーカルに呼んで再結成したサディスティックミカバンドの歌で、 「犬だってにゃぁ」とか「猫だってわん」とかって歌詞があるのを思い出した。
510 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 09:41:18 ] 今後クラスの継承の話する時このネタ使わせてもらうわw
511 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 14:55:14 ] class Animal { public: virtual void bark() = 0; };
512 名前:デフォルトの名無しさん [2010/04/26(月) 21:04:13 ] Waveファイルを読み込むプログラムを作ろうとしてますがうまくいきません。 大きいファイルを読もうとしてるので、バッファ領域を確保して、その領域にちまちま ファイルを読み込んでいこうという魂胆ですが、出力してみると全て0のままです。 小さいファイルなら読み込めるようですが、大きい(200MB以上)では読み込んでくれません。 アドバイスをください。 以下ソース ifs = fopen("C:\\TEST.wav","rb"); /*** ヘッダー読む ***/ int blockSize = waveHeader.getBlockAlign(); //ブロックサイズを得る //12000バイトのバッファを確保したつもり unsigned char *buffer = (unsigned char*)calloc(4000, blockSize); do { //12000バイト分のデータを読み込んだつもり readSize = fread( buffer , blockSize , 4000 , ifs ); for( int i = 0; i < readSize; ++i) { //読み込んだデータを出力してみても 0 のままで出力される cout << ((short*)buffer)[ i * 2] << ":" << ((short*)buffer)[ i * 2 + 1] << endl; } } while (readSize == 4000);
513 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 21:23:35 ] 素朴な疑問だが、waveHeader構造体のメンバはちゃんとした値が入っているのかね。 取り敢えず、blockSizeが幾つになっているのか確認するところからだな。 つーか、通常fread()は失敗しないからdo-whileは要らんだろ。
514 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 21:24:27 ] >>513 ファイル終端まで読み続けたいんじゃないかと
515 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 21:32:36 ] unsigned int blockSize = waveHeader.getBlockAlign();
516 名前:デフォルトの名無しさん [2010/04/26(月) 21:45:13 ] みなさんありがとうございます。 >>513 blockSizeは4が入ってます。 一応RIFF , fmt , dataなどの文字を確認してヘッダー読み込みOKとしてます。 >>515 変えても何も起こりませんでしたが、確かにマイナスが入るというのは考えにくいですね こうしておきました。
517 名前:512 mailto:sage [2010/04/26(月) 22:00:48 ] typedef struct _RIFF{ char riff[4]; int fileSize; char formatType[4]; }RIFF; typedef struct _FORMATCHUNK{ char id[4]; int idFormatSize; short int formatId; short int channel; int sampleRate; int bytePerSec; short blockAlign; short bitsWidth; }FORMATCHUNK; typedef struct _DATACHUNK { char id[4]; int size; }DATACHUNK; ちなみにwaveHeaderは各構造体を持っているだけで 主要な部分のみgetメソッドを作りました。読み込まれたか確認するのは>>516 の通りで ヘッダーの最後にあるDATACHUNK内のsizeを見ても正しいデータが入ってますので 構造体の値はOKかと
518 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 22:13:49 ] >>512 全て0ってのはどうやって確認してるのかな 出力の一部分だけ覗いてるならその部分がたまたま無音だったとか
519 名前:512 mailto:sage [2010/04/26(月) 22:25:12 ] >>518 そこはバイナリエディタで開いて確認しました。 最初の方は確かに0でしたが、一回目のfreadで全部読み込める程度しか なかったので、全部0になっていると判断しました。 あと、いい忘れていましたが、小さいファイルなら do whileを抜けてプログラムが終了しますが 大きいファイルは do whileを抜けてきません。
520 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 22:36:11 ] >>512 ソースうp!
521 名前:デフォルトの名無しさん mailto:sage [2010/04/26(月) 22:39:06 ] 4*4000=16000
522 名前:512 mailto:sage [2010/04/26(月) 22:49:34 ] すいません。少し出かける用事がありますので。 今日は一旦締めせていただきます。 みなさんお付き合いいただき。どうもありがとうございました。m( _ _ )m >>520 また後日お伺いする機会があれば 是非、よろしくお願いします。 >>521 その通りですね。恥ずかしいです。( /// )
523 名前:デフォルトの名無しさん [2010/04/28(水) 06:34:30 ] age
524 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 04:37:54 ] 2次元の座標を返す関数を作る予定です POINT GetPoints() 戻り値が座標の場合 関数が失敗したかどうか分からないので ・bool GetPoints( POINT &out ) 戻り値をboolで関数の成功判定、結果を入れる変数渡す ・POINT GetPoints() 失敗の場合(-1,-1)の座標を戻り値とする どちらの方がいいかな? 両方のパターンを見たことがあるので気になった
525 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 05:01:18 ] C++なら ・例外を投げる ・boost::optional<POINT>を返す
526 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 08:14:57 ] >>524 その用途で言えば -1,-1 の座標を返すのだけは無しだと思う 個人的には bool 戻す形だな。もしも関数の失敗が通常は起こらない純粋な失敗なら例外でもいいけど、 もしもそれが有効範囲/リージョン判定等でも利用される想定ならシンプルに bool戻す
527 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 08:18:01 ] (INT_MIN, INT_MIN)を返すようにしたことならある
528 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 08:27:42 ] POINT* GetPoints() にして NULL を返すのはあり?
529 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 08:28:57 ] 毎回newすんの? それはないわ
530 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 08:33:56 ] std::pair<bool, POINT> は?
531 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 14:25:59 ] >>524 例外を投げろ。 C++なら例外と、例外安全くらいはどっちみち知らなきゃだめだから 勉強しよう。 。
532 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 15:16:46 ] >>531 例外も例外安全もC++だけの話じゃないぜ。どの言語でも同じ。 例外機能の無い言語なら、より広い意味での「エラー安全」ね。
533 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 15:17:23 ] >>524 エラーがほんとに例外的におきるものなら、例外がいいな 普通にありえるものならそんなのに例外使っちゃいかん
534 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 18:20:09 ] こういうのは? if(IsPointsValid()){ POINT pt = GetPoints(); ... }
535 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 19:27:48 ] >>531 最近、例外安全って言葉を覚えたばかりの人とかは何でもそれを使いたがるかもしれないが、 それはそもそも 「例外的な何かが起こった場合の対処」 を行い、安全にしようって事なので、 元の質問にある「関数が失敗した場合」が何を指すのかによって話しは違ってくるぜ。 他の人も言ってるが、それが本当に例外的な意味での失敗なら例外投げた方がいいが、 そうでない場合、別の手段の方がいい。 そして勉強って意味だと、これらの話を理解して、 何でもそれにする、みたいな頭悪い処理は書かないようにした方がいいぜ 意味がちゃんと伝わると嬉しいが。
536 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 19:30:27 ] あ、あと当たり前だけど、これらは別に排他の関係じゃないので、 両方実装したっていいんだぜ。 内容次第じゃ冗長にはなるけども、 しかしあえて冗長に書いて勉強の内にするって手もある。 ・・・が、そもそも勉強の意図があるのかどうか不明なので、余計なお世話かもしれないけどもw
537 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 19:48:21 ] つーか、コーディング規約次第だよな。 Win32 API風なら エラー判定値を返す HRESULT GetPoints(POINT *out) 最近のboost風なら 例外を投げる POINT GetPoints( ) と 空値を返す optional<POINT> GetPointsOpt( ) を両方用意するとか。 設計思想によるとしか。
538 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 20:18:13 ] VECTOR2 a; D3DXVECTOR2 b = a; D3DXVECTOR2に自分で定義したVECTOR2を代入したいので以下のようにやったんですが ランタイム スタック オーバーフローの警告が出ます。 警告を出さないようにするにはどうしたらいいのでしょうか。 class VECTOR2{ VECTOR2():x(0), y(0){} operator D3DXVECTOR2() const { return static_cast< D3DXVECTOR2>( *this); } FLOAT x, y; };
539 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 20:26:54 ] これじゃいかんの? operator D3DXVECTOR2() const { return D3DXVECTOR2(x, y); }
540 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 20:27:08 ] >>538 なんでキャストなんか使うの? ちゃんとオブジェクト作って返せよ。
541 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 20:40:38 ] そうでした。ありがとうございます
542 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 20:52:27 ] >>538 のコードが vc++2008ee でコンパイル通るのはバグだよね?
543 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 21:03:09 ] >>542 1. > D3DXVECTOR2 b = a; // VECTOR2->D3DXVECTOR2の暗黙の変換を呼び出そうとする 2. で、VECTOR2::operator D3DXVECTOR2() const がlookupされるわけだが 3. > static_cast< D3DXVECTOR2>( *this) // ここで、さらにVECTOR2->D3DXVECTOR2の暗黙の変換を呼び出そうとする 以下2-3の繰り返し そのため> ランタイム スタック オーバーフローの警告 無限再帰でスタック溢れるぞ、って警告が出たんじゃないかと想像。 C++の規格的にどうかが知らん。たぶん未定義動作だと思うが。
544 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 21:19:01 ] そういえばC++相談室 part79でも型が違うのに コンパイルが通るってのがあったな C++相談室 part79 の955 pc12.2ch.net/test/read.cgi/tech/1268846738/955 www.unkar.org/read/pc12.2ch.net/tech/1268846738/#l955 vc……
545 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 21:28:33 ] >>535 元質問者のモデルで (2次元空間での)2直線の交点を返す関数 だったとする 与えられた2直線が平行だった場合 例外投げる? 戻りは解なしを通達・非引数は書き換えず? 俺は後者を選択したくなるけど… 意見を聞いてみたい
546 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 21:38:35 ] 交点だったら無限遠になるから (HUGE_VAL, HUGE_VAL) を返したくなるな。 (数学座標を扱うものと仮定すれば要素の値は実数だろうし)
547 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 21:47:49 ] なるほど。 実数空間ならソレも考え方としてはアリな部類かー 運用時の前提条件(呼び出される頻度や例外/エラーの頻度等)をがんがん絞り込んでいかないと 決められない部類の問いになっちゃうねー 思想がしっかりしてて、一貫してれば混乱しないだろうけど、取捨選択が難しいな
548 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 22:22:23 ] >>545 535だけど、そのモデルっていうか、ケースで言えば俺も後者と言うか、 「解無しだ」っていう明示的な何らかの値なりBOOLなりを返して終了かな。 別に俺の意見がどうこうって言うより、そういうもんじゃね? そして繰り返しになるけど、要はどういう使われ方を想定してるかって話なので 解が無いってのが例外と言うよりただの答え、って言う使われ方なら解がありませんって値を返してあげる方が自然かなと思う。 でも想定するその関数の使われ方の中で、「この関数に与えられる2直線として平行な値が与えられるのは異常なのだ」 って事なら 例外投げて明示するかもしれない。 要点はそこ。 セマンティクスというか考え方っていうか
549 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 22:25:26 ] 正しく間違えられた場合と、例外的な状態の違い ・・・って、言葉がまんま過ぎてそろそろゲシュタルト崩壊しそうな人もいるかも試練
550 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 22:39:37 ] とある要素数10の配列を表す処理について、例えば外から11番目の値をくれとお願いをした時、 「私は0〜9の要素を持つ配列だ。私に対して11番目を欲しいという要求は、 私にとってはあってはならない異常な要求だ」 として例外を投げるかもしれない。 でも、3番目の要素が例えばNULLだったとしても、「私はただの配列だ。その内容までは関知しない」 から、そのまま返す。 そして受け取った側にとって、NULLが戻る事が、例えば進行上異常だったとしても、 配列にとっては異常な訳じゃない。 だから、彼はそのまま返すし、進行上、それでは問題があるなら、 受け取った側が何か対策するか、あるいはこの配列処理そのもののスタンスを変えてしまえばいい。 例外と、何かを表す値の関係ってこんな感じじゃね? …今更かもしれないけども
551 名前:デフォルトの名無しさん mailto:sage [2010/04/29(木) 22:41:48 ] vectorのatですねわかります
552 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 04:53:30 ] #include <stdio.h> int main(void){ int i, j; for(i=1; i<=5; i++){ for(j=1; j==i; j++){ printf("*"); } printf("\n"); } return 0; } ↑どこが間違っていますか? 実行結果を * ** *** **** ***** にしたいのですが。
553 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:23:04 ] × j==i ○ j<=i
554 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:25:38 ] >>553 ありがとうございました
555 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:34:02 ] 余計な老婆心だが、 ループカウンタは1.for内で宣言 2.0から開始 を癖にしたほうがいい。 1.は変数のスコープはなるべく狭いほうがいいのと、 2.はC配列のインデックスが0から開始のため。 int main() { for (int i = 0; i < 5; i++) { for (int j = 0; j < i; j++) { printf("*"); } printf("\n"); } return 0; }
556 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:36:40 ] >>555 ごめんなさい。入門書を読んでいて、そんなことが出来るなんて知りませんでした。 これからはそうやって書こうと思います。
557 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:38:17 ] 556ですが、 1.の意味は、forのなかで宣言するようにすると、forの中だけでiが有効になるから 節約できるって事ですか?
558 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:42:32 ] あと、何度もすいません、 test.c:2: error: 'for' loop initial declaration used outside C99 mode test.c:3: error: 'for' loop initial declaration used outside C99 mode ってエラーがでてコンパイルできなくなりました…
559 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 05:47:09 ] >>558 は事故解決しました
560 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 06:29:28 ] 関数が長くなったり、処理が複雑になってきたときに int i; /* i を外で宣言したら */ for (i = 0... i = 5; /* ループカウンタ以外で i を使ったりすると管理が面倒 */ string::iterator i; /* 同じ識別子を宣言できない */ とかの状況を回避する。 要するにコードの保守性を上げるため。 グローバル変数多用しない、とかも同じ理由。
561 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 06:53:02 ] >>560 つまりコードの上のほうでループ用にiつかって、 おそらくそのデータはそのループのカウント用にしか使わないなと思ったら 次の場所でiを再び使うこともある、そのブロック内で宣言しておけばOKってことですか?(最初に宣言してるとだめ?)
562 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 09:39:00 ] >>561 ちょっと解釈は変かな。 本来、関数内で違う目的に同じ名前の変数を使うのは設計が悪い。 但し、ループ制御変数みたいに同じ*ような*目的に一々違う名前を使う習慣がない場合もある。 そんなとき、次のループで前のループ制御変数をそのまま使うと問題がある*かもしれない*し、ループだけ移動するかもしれない。 だったら有効範囲を限定してしまえば宣言を遠くまで探しに行かなくて済むし、影響を心配することもなくなるということ。 但し、古いCではブロックの途中での宣言ができないことと問題のfor文内での宣言ができないことに注意。 -- void func(int a) { int b = a; // ブロックの先頭なので問題なし if (a == 0) return; int c = a; // ブロックの先頭ではなくif文の後なので古いCではエラー { int d = a; // ここはブロックの先頭なので問題なし for (int i = 0; i < a; ++i) { // for文内での宣言は古いCではエラー int e = a; // ここもブロックの先頭なので問題なし } for (d = 0; d < a; ++d) ; // これは当然、問題なし } -- >>560 グローバル変数を極力使用しないのは、有効範囲を限定する目的以外にも名前を公開しないと言う目的もあることに注意。
563 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 15:09:02 ] 横から質問失礼 グローバル変数をやむなく使うというのは例えばどういう状況でしょうか 自分は結構頻繁に使ってましたorz
564 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 15:54:23 ] >>563 やむなく使う状況が分からない、なぜならグローバル変数を使ったことがないから、なら筋が通るんだけど 頻繁に今使ってるのであれば、それを極力減らすように努力してみてはいかがか
565 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:01:47 ] >>563 グローバル変数を使うと何が便利だと思う? その裏返しで、便利さ故の厄介な目に遭いたくないから使いたくないのよ。
566 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:14:30 ] それはグローバル変数のデメリットなわけで、やむなく使う状況の説明になっていません
567 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:16:17 ] あと、微妙な問題だけど、 1.for内で宣言 これコンパイルとおらない環境あるから。。 for(int i...){} for(int i...){} とやるとiの多重宣言だといわれるのがVC6
568 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:26:14 ] >>567 今更そんな過渡期のコンパイラなんて無視していいでしょ。 今後サポートされているOSではVC6自体がサポートされないのだから。 >>566 已む無く使う状況は、その状況になれば判ります。 逆に言えば、そうならない限り無視して構いません。
569 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 16:33:38 ] 学校の環境がそれであることが十分ありうることは宿題スレを見てると実感できるよ。 あと、業務でも出会う可能性もあって、VC6でビルドできないとリリースさせてもらえない現場があった。 まあ、捨てちゃいなよ、とは思うんだけどさ。。
570 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 17:29:43 ] >>567 YOU! #define for if (false); else for しちゃいなYO!
571 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 19:54:37 ] 563です。亀レス失礼 自分は趣味の域なんで大きいサイズを扱わないからってのが グローバルの怖さがわからない一番大きな要因だと思います とりあえず今後は減らす方向で色々やってくことにします >>564 世間一般的にはグローバルは「やむなく」使うのかなと 自分はやむなくと言うより結構頻繁に使ってたもので ややこしい文面で申し訳ない いずれにせよ勉強あるのみってことで
572 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 20:12:41 ] おまえみたいなやつは一番信用ならんので, プログラマにならないでください
573 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 20:14:56 ] >>570 上を説得する気もなかったのでそれやらないまま任務遂行したYO!
574 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 20:17:45 ] >>571 ああ、なるほど。 自分が神様ですべてを把握できているのなら、グローバル祭りでも特に困らないままだよ。 というのは、複数人が触る、または他人のコードをメンテするときに困ることが多いから。
575 名前:デフォルトの名無しさん mailto:sage [2010/04/30(金) 20:28:48 ] グローバル変数のよくない理由はみんな分かってるし、それでも メリットを見出して使うんだから、基本的にはどんどん使っていい 2chとかの頭でっかちは、グローバル変数ときいただけでとにかくダメって わめくけど、気にする必要はない。そういう奴に限って、10個も20個も引数のある 関数作って、グローバル変数使ってないからって理由でドヤ顔だったりする