【初心者歓迎】C/C++室 Ver.47【環境依存OK】
引数を取る関数一般の話として、 同じ引数で何度も呼び出しても毎回返値が違う可能性がありますよね。 time()とか。 もし、ある関数に対して「同じ引数ならば常に同じ値を返し、かつ副作用が無い」ことをコンパイラに対して表明できれば、 あるケースにおいては最適化に有利だと思うのですが、 何らかの方法でそれをコンパイラに表明することはできますか? int f(int x){return x+1;} //同じxに対して同じ値を返す int main(){ for(int i=0; i<f(99); i+=f(0)) printf("%d", f(1)); //最適化可能? return 0; }
>>3 定数を返す関数ならVC8などで関数がインライン化されてしまう
事はあるが、引数によって戻り値が違う場合は難しいかも。
>>3 副作用がないことの表明にはならないけれど、C++のinlineはコンパイラにインライン展開を促す
6 :
3 :2008/01/16(水) 16:11:14
たとえば
>>3 のf()がやたら複雑な計算を要する場合とか、
たとえ同じ引数に対して常に同じ値を返すとしても、
インライン展開では毎回計算してしまうんですよね?
やはり自分で一時変数を確保しておくのが良いということですか
賢いコンパイラならそこを最適化できるかもしれないが、 そうでないコンパイラを使うなら、自前でキャッシュを持てばいいだろう。
>>6 引数の取る数が限られている場合はテーブル展開するのが常識。
引数が実数だとそうは行かないが。
例えばアッカーマン関数のような何度も同じ整数のペアが 出てくるような再帰的な関数の場合、整数のペアをstd::pairに 入れてキーにしてstd::mapに入れれば劇的に速くなる。
次の全ての条件に当てはまる関数を一意的な関数と呼ぶ ・グローバル変数を参照しない ・ローカルstatic変数を持たない ・間接参照を用いてローカル変数以外の変数を参照しない ・初期化していない変数の値を返さない ・他の一意的でない関数を呼ばない こんな感じか
C/C++は余計なことしないからなあ memoizeは自分で処理しないといけない
アセンブラじゃあ開発期間が長すぎる or 開発不可能な プロジェクトをアセンブラにあまり劣らない速度を保ちつつ 開発を可能にしたのがC/C++ 他の言語は必ずどこかで速度や効率を犠牲にしている
13 :
デフォルトの名無しさん :2008/01/16(水) 17:34:41
あ
constexpr待ちsage
>>3 __declspec(noalias)とか__attribute__((const))とかないわけではない。
前スレ995です。 zlib.hはたぶん大丈夫だと思います。この前には zlib.hが見つからないってエラーが出てたんですが どっかのディレクトリにあったzlib.hを/usr/includeに 持ってきたらエラーは消えて現在に至る、と言うかんじです。 glutが足りないんでしょうか。Synapticで lib-glut3 lib-glut3-dev glut3 glut3-dev freeglut3 freeglut3-dev とかは入れたのですが。。。まだ他に入れなければいけないパッケージが あるということでしょうか。
zlibのバージョンは? glutが使ってるzlibが足りないとみたんだが。 gzFileはzlibで定義されてるはず
つーか、どっかのディレクトリにあったのを自分でコピーするって、、 ちゃんとインストールしてないんじゃないの?
19 :
16 :2008/01/16(水) 18:58:46
findで調べてみたら /usr/src/linux-headers-2.6.22-14/include/linux/zlib.h にあったのでこれを取ってきたのですが・・・ するとエラーが消えたのでこれでいいのかな、と思ったのですが・・ ちゃんとsynapticなりでインストールしなきゃいけないということでしょうか。
>>19 そのzlib.hの中に gzFile の定義なかったらハズレ。ちゃんとzlibをイ
ンストールしましょう。
そもそも、ヘッダだけコピーしてもライブラリがなきゃリンクできない
じゃない。
21 :
16 :2008/01/16(水) 19:20:25
なるほど。。お恥ずかしい限りです。Synapticでzlibっぽいのをインストールしたところ とりあえずエラーは消えました。ただ /tmp/ccqSOFll.o: In function `readfile': cv109.c:(.text+0xa41d): undefined reference to `gzopen' cv109.c:(.text+0xa5ce): undefined reference to `gzgets' cv109.c:(.text+0xa5e4): undefined reference to `gzclose' というエラーが出てしまって…GLUTのライブラリを読み込めていないということでしょうか。 Synapticで freeglut3 glut libglut 関連は入れてるので多分大丈夫だと思うのですが。。。 コンパイルするコマンドは gcc -lglut -lGLU -lGL cv109.c でいいのでしょうか?
-lz
#include <iostream> int main(){ int x = 10; float f = 5.5; const int& r = (int)x, &s = (int)f; x = 8; f = 1.00; std::cout << x << ',' << r << std::endl; std::cout << f << ',' << s << std::endl; return 0; } 実行結果 8,8 1,5 同じキャストでも元の型と同じ型にキャストすると変数自体へのリファレンス、 違う型にキャストすると一時値へのリファレンスになります。 (int)xの方は最適化が働いているんだろうと思いますが、 このように同じキャストでも結果が違うのは仕様に準拠したものでしょうか? コンパイラはbccです。
24 :
16 :2008/01/16(水) 20:09:37
-lz をつけると問題なく動きました。ありがとうございます。 お手数をお掛け致しましたm(_ _)m
while(条件){ 処理 if(条件) 構造体の宣言を新しく追加 //例えばkouzoutai hoge[0]、hoge[1]、hoge[2]… } ってしたいんだけどどうやって書けばいいの?
>>3 >>14 の言ってる constexpr ってのが次期 C++ に入る予定。
関数の戻り値をコンパイル時に定数にできる。
ただし、return 文しかない関数じゃないとダメだけど。
あるいは、今でもテンプレート引数と静的メンバ定数を利用して
似たような物を作る事もできる。
複雑な事やろうとしたら再帰するしかない。
制御文も使えないけど、? : は使えるから意外と色々出来るよ。
>>25 宣言は追加できません。配列の要素数を増やしたいなら、std::vectorでも使えばよろしいかと。
28 :
デフォルトの名無しさん :2008/01/16(水) 20:56:19
>>23 同一の型へのキャストはno effectだったという記憶があるような
ないような。
30 :
デフォルトの名無しさん :2008/01/16(水) 20:57:37
>>23 つまり最適化ではなく、標準どおりかと
思うような思わないような。
31 :
デフォルトの名無しさん :2008/01/16(水) 21:04:56
前スレからの続きのunary_functionに関する質問です。 入力 string line = "11 22 33 44"; char delim = ' '; 出力 vector<int> v ← 11,22,33,44 (要素4個のベクタ) という関数をつくろうとして、それはできたのですが、次に stringからintへ変換するunary_functionを引数で渡して(1)、上記関数内で transform()に渡そう(2)としたのですが、上手くいきません。前スレで教えてもらって (1)の引数で渡すところまではできたのですが、(2)のtransformに渡す所でコンパイル が通りません。どこが間違っているのでしょうか? vector<int> line2vec2(string line, char delim, unary_function<string,int> func) { 色々な処理 tansform(v.begin(),v.end(),v2.begin(),func()); tansform(v.begin(),v.end(),v2.begin(),func); =>両方ともコンパイルは通らなかったです。 return v2; } よろしくお願いします。
コンパイルエラー書け。 v, v2の型は何だ。
>>23 一時オブジェクトが作られてるね。一時オブジェクトそのものは仕様にあると思う。
コンパイラの警告レベルを上げると一時オブジェクトを作った警告が出せるコンパイラもあったと思う。
>>28 >>30 ありがとうございます
すっきりしました
>>33 bccでもconstを外すと「一時変数を云々」という旨の警告が出ます。
35 :
デフォルトの名無しさん :2008/01/16(水) 21:30:11
>>23 VC++ 2008でも同じ結果。
キャストの結果は右辺値(一時オブジェクト)
これは仕様。ただし、同じ型へのキャストはno effect
だったと思うような思わないような。
メイヤーズかなんかの本でチラっと書いて
あった気がする。
37 :
デフォルトの名無しさん :2008/01/16(水) 21:33:00
>>34 それは標準準拠してないから。
bccは非constリファレンスでも左辺値以外の値を
参照できてしまう。
38 :
デフォルトの名無しさん :2008/01/16(水) 22:41:31
>>32 すいません。
コンパイルエラー
test.cpp:73: instantiated from here
/usr/include/c++/4.2.1/bits/stl_algo.h:936: error: no match for call to
'(std::unary_function<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, int>) (std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&)'
vの型vector<string>
v2の型vector<int>
です。
先の関数はこんな感じ() {
int begin, end;
vector<string> v;
begin = end = 0;
while (line[end]) {
begin = end;
while (line[end] != delim && line[end]) {
end++;
}
v.push_back(line.substr(begin, end-begin));
end++;
}
vector<int> v2(v.size());
transform(v.begin(), v.end(), v2.begin(), func);
return v2;
}
std::map<wstring, HPEN> pens; std::for_each(pens.begin(), pens.end(), ここ); と書くと、「ここ」の関数に std::pair<wstring, HPEN> が渡されると思うのですが、 BOOL DeleteObject(HGDIOBJ)なので 都合よくHPENだけ渡す方法はないでしょうか?
Microsoft OutLook 2003のメールのルール仕分けにあるような テキストボックスにリンクを複数貼ってクリックするとフォームが開き その開くフォームがフォルダダイアログだったりアドレス入力フォームだったりと 一行ずつ異なるリンク付きテキストボックスはどのようにつくればいいのでしょうか? RichTextBoxで作ろうにもリンクしている文字列が開いたフォームで変えられるので LinkClickedのリンク文字列で判断は難しく、同名のリンクが複数あった場合などで困っております。 どなたか良い方法を教えてください。
>>31 >>38 unary_function型そのものには関数呼び出しが定義されてないからエラー
そもそもunary_function型はそのように使うことを想定されていない
template <typename T> vector<int> line2vec2(string line, char delim, const T& func)
{
色々な処理
tansform(v.begin(),v.end(),v2.begin(),func());
tansform(v.begin(),v.end(),v2.begin(),func);
=>両方ともコンパイルは通らなかったです。
return v2;
}
間違えたw コメント残しっぱだし…… template <typename T> vector<int> line2vec2(string line, char delim) { 色々な処理 tansform(v.begin(),v.end(),v2.begin(),T()); return v2; }
そこでU+2028の改行ですよ。
45 :
デフォルトの名無しさん :2008/01/17(木) 01:03:03
"数値を文字列として入力して、一桁ずつを配列にいれて計算する" 場合ですが、引き算・掛け算の計算方法を誰か言葉で説明してください! 例えば足し算なら 「下の桁から一桁ずつ足していって10を超えたら次の配列に桁上げしていれる」 となるんですが。。 おねがいします!
>>45 aとbの掛け算なら、aをb回足し算すればいいと思うよ
筆算の要領で計算すりゃいいんじゃないの
48 :
デフォルトの名無しさん :2008/01/17(木) 01:30:24
>>46 50桁の掛け算なんですがそれで大丈夫ですかね?(+_+)
やってみます!
あざす!
>>47 筆算みたいに計算するって書いたら先生にそんな単純に書くなって言われました↓
でもあざす!
C/C++ では標準的にインデントとしていくつのスペースを 入れるのがよいのでしょうか?2 となっているコードもあるし 4となっているコードもあります.
4でも6でも8でも構いません。 3や5でもいいですよ。
標準なんてないだろう。俺は4だけど。
52 :
デフォルトの名無しさん :2008/01/17(木) 11:49:01
>>42-43 ありがとうございます。
そうすると、unary_function()を引数にもらって、それを内部で使う関数というのは
かけないのですか?
void *のポインタをもらって、内部で適当にキャストして、unary_function()として
使えたりしないのかな。
とりあえずやってみます。
53 :
デフォルトの名無しさん :2008/01/17(木) 12:13:01
a=1/350,1/320,1/360,1/368,1/397,1/400 b=1/7.90,1/8.12,1/8.23,1/8.56,1/7.97,1/8.68 と仮定する。 for ($i=0; $i<=5; $i++) { $p1 = (1/$a[$i])**$a * (1-1/$a[$i])**($play-$a); $p2 = (1/$b[$i])**$b * (1-1/$b[$i])**($play-$b); $p3 = $p1 * $p2; $t_ap += $p1; push(@ap,$p1); $t_bp += $p2; push(@bp,$p2); $t_abp += $p3; push(@abp, $p3); } 上記の構文で計算すると分母に差があるのでオーバーフローを起こす・・・と言われました。 **($play-$a);←この部分の計算に問題があるようなのですが、プログラムに疎いので良く判りません>< 問題のある部分をどのように記述するべきなのかご指導お願い致します。m(_ _)m
ここは、C/C++のスレなんだが
55 :
デフォルトの名無しさん :2008/01/17(木) 12:20:36
>>54 すいませんm(_ _)m
どこで聞けば良いのでしょう?
>>52 unary_functionへの参照をもらえばいいんじゃないかね
58 :
デフォルトの名無しさん :2008/01/17(木) 12:24:01
コマンド名か、コンパイル時の画面に書いてないか。
unary_functionの関数呼び出し演算子って 仮想関数になってんの?
unary_functionはテンプレート引数をargument_typeとresult_typeにtypedefしてるだけにすぎん
だよねやっぱ じゃあunary_function型で引数を取ること自体が意味無い、だよね
以下のソースプログラムをコンパイルして実行したのですが M:\>sort3.exe 入力ファイル名: と表示されて、そこからどうすればいいかわかりません。 ファイル入出力とソートの宿題なのですが、 いかんせん超がつくほどの初心者なので…。 どなたかよろしかったらお願いします。 使っているソフトはVisual C++ 2005 Express Edition です。
上のソースプログラムです。 /* sort3.c */ #include <stdio.h> struct kamoku { char mei[20]; char kana[10]; int ei; int koku; int su; int sha; int ri; } #define SIZE 30 main(){ struct kamoku seiseki[SIZE], min; int i,j,m,n; FILE *input, *output; char infname[16], outfname[16]; printf("入力ファイル名: "); scanf("%s",infname); printf("出力ファイル名: "); scanf("%s",outfname); if((input=fopen(infname,"r")) == NULL ){ printf("ファイルがありません\n"); exit(1); } if((output=fopen(infname,"r")) == NULL ){ printf("ファイルが作成できません\n"); exit(1); }
>>64 入力ファイル名を入力する。
・・・ってかプログラム以前にパソコン教室に通うべきだな。
>>66 どのようなファイルを入力すべきかがわかりません。
初心者ですみません。
>>67 鼬害。キーボードの使い方やファイルとは何かと言ったことは
プログラミング以前の知識です。
70 :
デフォルトの名無しさん :2008/01/17(木) 13:24:44
>>57 やってみましたが、ダメなようです。
vector<int> line2vec2(string line, char delim, const unary_function<string,int> &func) {
int begin, end;
vector<string> v;
begin = end = 0;
while (line[end]) {
begin = end;
while (line[end] != delim && line[end]) {
end++;
}
v.push_back(line.substr(begin, end-begin));
end++;
}
vector<int> v2(v.size());
transform(v.begin(), v.end(), v2.begin(), func());
return v2;
}
>>61 仮想関数になっているかどうかはよくわかりませんでしたが、
stlのソースを見ていると、pointer_to_unary_functionというクラスが
ありました。今度はこれで試してみる。
なんか無駄に複雑な事になってるな
72 :
デフォルトの名無しさん :2008/01/17(木) 13:41:27
>>70 のつづき
もうなんだかわけがわからなくなってきた。
unary_functionはArgとResのtypedefなんですか?
STLのコンパイルエラーメッセージはやくにたたん。
普通std::unary_functionは継承して使わないと役に立たないと思うんだが。
>>72 そもそもunary_functionを引数にしようとした理由は?
普通継承したファンクタ作るよね
std::unary_functionやstd::binary_functionを継承する理由は std::bind2ndなどのアダプタがargument_typeとresult_typeを 必要とするから。 それ以上の意味はない。別にstd::unary_functionを継承しなくても 自分でargument_typeとresult_typeをtypedefしてもいい。
こんな感じか? template <typename T> vector<int> line2vec2(string line, char delim, T func) { transform(v.begin(), v.end(), v2.begin(), func()); } line2vec2( , , std::ptr_fun(関数ポインタ)); line2vec2( , , 関数オブジェクト());
間違えた >transform(v.begin(), v.end(), v2.begin(), func()); transform(v.begin(), v.end(), v2.begin(), func);こうだな
>>72 今回のエラーメッセージは割と理解できるものだし、
そもそも何が駄目なのか指摘されてるのに
まるで見当違いの方法を試しているのはお前自身だ
80 :
76 :2008/01/17(木) 15:10:05
82 :
コンパイルできた :2008/01/17(木) 15:48:16
皆さんのおかげ様で、とうとうできました。 ソースは以下です。 template <class T, typename T2> vector<T> line2vec2(string line, char delim, T2 func) { int begin, end; vector<string> v; begin = end = 0; while (line[end]) { begin = end; while (line[end] != delim && line[end]) { end++; } v.push_back(line.substr(begin, end-begin)); end++; } vector<T> v2(v.size()); transform(v.begin(), v.end(), v2.begin(), func); return v2; } この関数をこんな感じで使う。 string s = "1 2 3 4 5 - 6 7 8 9"; vector<int> v = line2vec2<int>(s, ' ', string2int());
83 :
コンパイルできた :2008/01/17(木) 15:48:54
<82の続きです> ちなみにstring2int()は以下のように定義しました。 class string2int : public unary_function<string,int> { public: unary_function<string,int>::result_type operator() (unary_function<string,int>::argument_type str) { if (str == "-")return 0; else return static_cast<int>(atoi(str.c_str())); } }; いやー、すげえ感謝感謝。今回答えてくれた方々には昼飯一回おごってもいいくらいス。
昼飯一回程度の感謝
名無しの書き込みから個人を特定して昼飯をおごる程の感謝 えらく大変だな
87 :
76 :2008/01/17(木) 17:44:29
>>83 昼飯はいいから俺がニート脱出できるように神様にお願いしといてください。
#include <iostream> #include <cstdio> char ch[10]; int main() { while ((cin.getlie(char, 10)) != EOF) { } } これをコンパイルしようとするとwhileの行でエラーが出るのですが、 何がいけないのでしょうか??
89 :
88 :2008/01/17(木) 20:02:08
すいませんwhileの行のcharはchの間違いです。
getlie
getlie ではなくて getline な。 分かってるとは思うけど
94 :
88 :2008/01/17(木) 20:12:05
回答くださった方ありがとうございます。 すいません色々抜けていました。。orz 正しくはこれです。 #include <iostream> #include <cstdio> using namespace std; char ch[10]; int main() { while ((cin.getline(ch, 8)) != EOF) { cout << "test"; } } これでもコンパイルできないのです。 whileの行でエラー出ます。
>>94 != EOFこれが不要。
質問するときはエラーの内容も書いてくれ。
>>94 #include <iostream>
char ch[10];
int main()
{
while (std::cin.getline(ch, 8)) {
std::cout << "test";
}
}
#include <iostream> int main() { char ch[10]; while (std::cin.getline(ch, sizeof ch)) { std::cout << "test"; } }
98 :
デフォルトの名無しさん :2008/01/17(木) 21:21:43
Fedora6 gcc でファイルの更新を検知するプログラムを作りたいのですが、 更新までブロックする関数を教えてください。 if (ファイルの更新までブロック) { //更新された read(); ... } みたいなカンジです。 ちなみにtailのソースを見てみたのですが、 1秒毎にファイルが更新されたかチェックして処理をしているようです。 何秒毎にチェックするのではなく、更新までブロックできる関数がわかればいいです。 よろしくお願いします。
なんでそんなものが存在するという前提で物事を進めようとするの?
てゆーかチェックせずに、更新されると発見してほしいのかよwwwwwwwww
Windows だとディレクトリの更新を検知してシグナル送ってくれる FindFirstChangeNotification/FindNextChangeNotification って API があるから 他の OS でもそういう API があるんじゃないかと思う気持ちも分からんでも無い。
>>98 Linuxなら可能。
dnotify inotify といったキーワードで調べてみて。
103 :
デフォルトの名無しさん :2008/01/17(木) 22:30:53
プログラムって教科で分けると数学ということですか?
普通に、技術家庭科。 実際、技術家庭科の時間にVBプログラミングやらされてたし。
情報だろ
107 :
デフォルトの名無しさん :2008/01/17(木) 22:45:09
統一された見解が無いということですか? 哲学っぽいですね。
分野でいうと情報処理だろうな。 つか、いちいちageんなって。
>>99 Winだと
tp://www.google.co.jp/search?hl=ja&q=ReadDirectoryChangesW&lr=
みたいな感じで、存在するんだよ。だから、98もそこから、Linuxにも存在すると期待してるんじゃないかな……
ちなみに、俺は知らん。
高専だと、情報基礎以外に、制御とか計算機科学、電子、通信、ソフ技、ハード技、プロ技 至る所でプログラミング漬けだったけど。時代遅れのw
111 :
デフォルトの名無しさん :2008/01/17(木) 23:02:50
>>102 具体的にありがとうございます。
手詰まりだったので、大変助かりました。
ありがとうございました。
>>100 何が言いたいのか分かりません。
>>110 そういえば親戚に情報基礎の教科書見せてもらったら15年前と大差なくてワロタ
15年前って言うと、数学の教科書の後ろの方に載ってる、 実際には授業で何にも使われない BASIC のことか?
基礎は不滅です。
流動的なものは情報Aなんかに任せとけば良いよ。
>>113 入力・出力・制御・演算・記憶
FFの応用回路・BASIC・CASL
のあたり。
ああ、高専の教科書か。 それは・・・知らんから何とも言えん。
情報関係の教科書書いてる教授がwinの基本操作とかCDの焼き方きいてくるからね〜(実話
VC++にtypeof()みたいのはないですか?
BOOST_TYPEOF
標準C++的にはtypeid演算子 あとMFCがなんか持っていた気がする。 C++/CLIなら当然.NET Frameworkのリフレクションが色々使える。
#define foreach(t, o, i) for(t::iterator (i)=(o).begin();(i)!=(o).end();++(i)) な感じのマクロの場合、それを使うと方を渡さなくて良くなりますか?
そんなマクロを作るな。 制御文をマクロ化すると 自分以外に読みづらいので 悪い作法だと言われている。
Cの文法で基本的な事かもしれないのですが、Linux のカーネルソースを読もうとして 挫折してしまったんですが、例えば struct hw_pci mr300_pci __initdata = { .nr_controllers = 1, .preinit = mr300_pci_preinit, .swizzle = pci_std_swizzle, .setup = ixp4xx_setup, .scan = ixp4xx_scan_bus, .map_irq = mr300_map_irq, }; のような struct 宣言が書いてありましたが、 .(dot)var = 値 のような記法って、そのメンバーの初期化という意味になるのでしょうか? 手元のCの文法書に見つからなかったのですが、この記述の説明文献ってありますかね?
C99 から導入された文法。 そのメンバの初期化という意味でおk。
122はコンテナの型、BOOST_FOREACHは要素の型を渡す必要がある点では、どっちもどっち。
長いのよ
適当にマクロで短い名前を付ければいいだろ。
VC++2005、WinXPです。 チェックボックスつきのツリーコントロールを作りたいと考えています。 チェックボックスでは三つのチェック状態をあらわしたいと思っておりまして、 ちょうど、VCをカスタムインストールする時に出てくるチェック付きツリーコントロールのような物を考えております。 これを実現する簡単なAPIないし、クラスはないでしょうか?
135 :
デフォルトの名無しさん :2008/01/18(金) 04:20:09
xcode環境でc++を開発している人はいますか? emacsよりもイイですか?
>>135 そもそもIDEとエディタを単純比較するのが間違ってる気がするよ!
気持ちは分かるけど・・・・・・
newでメモリを確保してdeleteをせずプログラムを終了した場合ってそのまま ずっとメモリ確保されたままになるの?
cout って何の略なんですか?
大抵はOSが何とかしてくれる
>>139 ありがとう
再起動するまでずっと無駄に領域とられたままかと思ってたけどOSがどうにかしてるのね
極めて古い OS だと分からんけどね。
144 :
デフォルトの名無しさん :2008/01/18(金) 11:36:39
>>136 emacs が好きなんですが、
class-name.<Tab>とか押すと、method-nameが選択できたり、
method一覧がかんたんに見れたり,そういう環境が羨ましい。
VB6、.NET言語のインテリセンスに比べればどうということはない。
インテリセンスは正直凄いと思う。
VCのは御馬鹿
eclipseとかもVC#のインテリセンス真似してくれればいいのにな
糞lipseは重くて嫌いだ。
最近のVSはC#だけインテリセンスがよく効く C++はおざなりってか
C++は複雑すぎるからな
てゆーか昔から
プリプロセッサ,テンプレート,ポインタの 置き換え,マッチング,追跡の大変さを考えたら, 今の IntelliSense ってすげぇとおもうが.
VB.NETとC#はおなじじゃない?
MessageBoxの上にカーソルのせたら WMessageBoxWにマクロで置換されてると教えてくれるけど。 肝心の引数がプロトタイプが見えないとか。
MessageBoxW
157 :
デフォルトの名無しさん :2008/01/18(金) 19:25:42
確かに引数のプロトタイプが見えないのは面倒だね たいてい関数の末尾にA、W付ければ良いって話だけど
VS使ってるなら、「(」書いたときにプロトタイプ出て来ないっけ? まぁ書いてるときじゃなくて見てるだけのときは面倒かもだけど
public: template <class T> class templateA { protected: T value; public: 各種メソッド }; template <class T> class templateB { protected: T value; public: 各種メソッド } class child : templateA<templateB<type> >{ 追加メソッド } 以上のようなクラスを作成し、 子クラス内でthis->value.valueでテンプレートクラスB内の値にアクセスしようとしたのですが、protectedの要素にアクセスできないというエラーが出ます。 どこを直せばよいのか分かりません。 どなたかご教示下さい。 宜しくお願いします。
templateBのvalueをpublicにすれば良い childはtemplateBを継承してないんだからtemplateBのprotectedメンバにはアクセスできない
安易にpublicにしていいのだろうか。
なら安易にアクセスすんなよw
public にするくらいなら friend にするわ。 でも、設計をもうちょっと考える事をまず検討した方がいい気がする。
>>161-164 様、ありがとうございます。
それぞれのテンプレートクラスにgetメソッドを追加して、要素にアクセスできるようにしてみました。
あまり綺麗な方法とは思いませんが、ひとまずこれで妥協しておきます。
C++初学者なので、friend関数の存在は知っていますが、使った事がないので、こちらも少し勉強してみようと思います。
オブジェクト指向が少しずつ理解できるようになってきて、数ヶ月前に作ったクラスのリファインが楽しすぎて困ります。
お陰で研究が全然進まないYO...
おすすめ 設計見直し > get > friend > public おすすめしない って順かな。
friendもpublicも大差ない気がするけどな 研究とかならいっそstructでもいい気がする
一応公開する相手が制限されてる分、public よりマシだとは思うが、 決しておすすめはできないという点では確かに似たようなもんだな。
>>166 getは○〜△というところでしょうか。
一応意図したものにはなったので、取りあえずこれで行ってみます。
>>167 この先数年使う可能性があるので、ある程度しっかりしたものが作っておきたかったのです。
最悪の場合、お上に献上しないといけないものなのでw
リファイン前は各変数毎にgetメソッドとsetメソッドを用意していました。
これではあまりにも酷いと思いまして。
>>168 難しいですね。
自分の知識がついてきたら、またリファインすると思います。
そして無限ループへ…
作る前に設計をよく練った方がよさそうな・・・ 設計に関する知識が無いならC++なんかやってないでそっちの勉強すべきだし
#include <stdio.h> class A{ public: virtual void func(){printf("A::func¥n");}; }; class B :public A{ private: virtual void func() {printf("B::func¥n");} }; int main (void) { A* b = new B; b->func(); //B::funcと出力される。privateなのにアクセスできる!? } 上記のコードについて、ご教授をお願いします。 gcc4.01で試したところコンパイルすることができました。 B::func()はprivateなのになぜコンパイルエラーにならないのでしょうか?
A::funcがpublicだから
>>171 class A の 仮想関数テーブルには
void func(){printf("A::func\n");}
の関数アドレスが配列0番に登録されている。
また、class B の 仮想関数テーブルには
void func(){printf("B::func\n");}
の関数アドレスが同じく配列0番に登録されている。
コンパイル時には静的な型であるAのfunc()が
調べられ、publicゆえにアクセスできることが
確認される。同時に仮想関数ゆえ、func()は
意味的には以下のようにコンパイルされる。
(b->vptr[0])(this);
vptrは仮想関数テーブルへのポインタで、今の
場合、派生クラスBの仮想関数テーブルのアドレス
が格納されている。仮想関数の呼び出しでは
コンパイル時はあくまで静的な型でアクセス可能性
が決定されるのがポイント。
と思う。
>>171 こういうコードだと分かりやすいと思う。
B の実装なんて知ったこっちゃないのよ。
// a.h
#include <stdio.h>
class A{
public:
virtual void func(){printf("A::func\n");};
};
// b.h
#include "a.h"
A* get_b();
// test1.cpp
#include "a.h"
int main (void)
{
A* a = get_b();
a->func();
}
// b.cpp
略
間違えた。こうだ。 // test1.cpp #include "b.h" int main (void) { A* a = get_b(); a->func(); }
一般的なコンパイラの実装の仮想関数呼び出し メカニズムで理解しておいたほうがいいんじゃね? 静的な型でアクセス可能性が決まるというのが 真実だと思うが。
178 :
デフォルトの名無しさん :2008/01/19(土) 04:15:38
typedef{ int x,y; }data; ・・・ hogehoge(std::vector<data>dist); こんな使い方はできるんでしょうか? また、こんな使い方はトリッキーなんでしょうか?
>>178 vectorにユーザー型を入れれるのか?
ということであれば、普通に使えます。
その書式はおかしいけどな
180 :
デフォルトの名無しさん :2008/01/19(土) 04:33:56
struct a { ... }; typedef t_a { ... } a; C++コード上で下の利点ってどういったものがありますか?
>>181 C でも使えるコードを書くのでなければ特に何の意味もない。
d
184 :
デフォルトの名無しさん :2008/01/19(土) 10:09:32
勉強で簡易Stringクラスを作ろうとしてます。 ところがコンストラクタだけの段階で、実行時に アクセス違反の例外で死にます。なんで? #include <cstring> class String { int len; char* s; public: String (const char* ch_ini) { len = (int) strlen(ch_ini); strcpy(s,ch_ini); } }; 実行は String k1("kkkkk1"); だけ(作っただけのつもり)。 これで死にまする。
土曜の朝から釣りか char *sの指してる領域はどこなんだよ?
>>184 そのコードじゃstrcpyで死ぬわ。
char* sはどこを指してるのかね?
187 :
デフォルトの名無しさん :2008/01/19(土) 10:17:02
unsigned long型 = 256 * unsigned char型の計算をしています。 unsigned char型の変数に入る値はランダムで0〜150くらいの値が入るのですが、大体100以上の値が入ったときに4,294,967,295などの変な値になります。 なんで正しい値が入らないのでしょうか?
わかりました。あなたは世界を革命するしかないでしょう。
189 :
184 :2008/01/19(土) 10:28:34
どこも指してない!? どーすればよいのでしょうか。
古っ
>>189 その辺はポインタの基本中の基本なんだから、本でも読んで勉強してくれ。
>>187 本当に unsigned char なのかね?
符号つきになってないか?
>>189 正直自作クラスとか以前の問題。
文字列やポインタなどの基本から学び直してからのほうが良い。
産業スパイか
(int)4294967295u == -1
197 :
187 :2008/01/19(土) 11:32:13
処理の部分だけ抜き出して見ました。 traは0〜255が入ります。 unsigned char tra_undf = 0; unsigned char tra_buff = 0; static unsigned long ValuePuls = 0; void main (void){ while(1){ if (tedgf_tracr == 1) {tra_buff = tra; flag_edge = 1; tedgf_tracr = 0;} if(tundf_tracr == 1) {tra_undf++; tundf_tracr = 0;} if(flag_edge == 1) {Sort(); tra_undf = 0; flag_edge = 0;} : }} void Sort(void){ValuePulse = ((256 * tra_undf) + (255 - tra_buff));} 結果は tra_undf=189のときにValuePulse=4294950301 tra_undf=234のときにValuePulse=4294961868 念のため+ (255 - tra_buff)の部分を消して見ましたが tra_undf=223のときにValuePulse=4294958848 でした。
198 :
デフォルトの名無しさん :2008/01/19(土) 12:01:07
>>184 何の本読んで勉強してんだ
さらしちまえ
int と size_t はどういう違い、あるいは、どのように使い分ければよいのでしょうか?
201 :
デフォルトの名無しさん :2008/01/19(土) 13:02:40
>>197 >念のため+ (255 - tra_buff)の部分を消して見ましたが
>tra_undf=223のときにValuePulse=4294958848でした。
intが16bitの環境か?
256がintなのでtra_undfがintに格上げされ乗算され0xdf00になるが
これはintでは負数になる。
でunsignd longに代入されると符号拡張され0xffffdf00になる。
これは符号無しだと4294958848になって一致する。
LSI_C 試食版の悪寒
204 :
187 :2008/01/19(土) 13:57:43
>>202 ありがとうございます。
NC30というコンパイラを使っているのですが、調べたらintは16bitと書いてありました。
回避方法は256の前に(unsigned)を付けるんで大丈夫ですか?
256u でおk。
(unsigned long) にしないと一緒じゃね?
207 :
206 :2008/01/19(土) 14:03:49
そんなことないか、(unsigned)でもいいかも
256 * unsigned char 値 なら一応 16 ビットに収まるしな。 別に 256lu にしてもいいとは思うが。
209 :
187 :2008/01/19(土) 14:15:25
助かりました! 本当にありがとうございます。
まだはじめたばかりなんですが、short int とかlong、double longなどの意味が分かりません。 無視して進んでも大丈夫ですか? どんな場合に使うのかなどが把握できていない状況です。
必要になれば使うし、必要にならなければ使わない。 それだけの話。
ビールをグラスに入れるか、ジョッキに入れるか、ピッチャーに入れるかの違いだ。
SFCで遊ぶか、PSで遊ぶか、PS2で遊ぶかの違いくらいか?
現在「猫でもわかるC言語」で勉強しています。 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { double pai=3.14159265358979; int mon=2; float flt=1.2f; printf("%5.2hf\n",flt); ←ここだけtypeのプレフィックスの「h」を使っているのか分からないです。 printf("%-5.2f\n",flt); printf("%05.2f\n",flt); printf("%+08.2f\n",flt); printf("%-08.2f\n",flt); printf("%d\n",mon=3); printf("%e\n",pai); printf("%08.2f\n",pai); printf("%05d\n",mon); printf("円周率は%fです\n",pai); printf("円周率は%1fです\n",pai); printf("もう少し詳しい値は%10.8lfです\n",pai); printf("もう少し詳しい値は%15.13lfです\n",pai);←ここの2行も「l」が使われていますが何のために使用しているのか分かりません。 printf("もう少し詳しい値は%20.18fです\n",pai) system("PAUSE"); return 0; } 見難いと思いますが、現在このような感じで悩んでます。 質問の内容がおかしかったらすみません。
hとl(長さ修飾子)そのものがわからないのか それともどうしてそのタイミングで修飾子を使っているのがわからないのか 前者ならprintfでぐぐると一番上に出てくるけど
lf : C89 の場合、規格違反。ただし、f と同じになるコンパイラも多い。 double を渡す時につい l を付けてしまう人がいるが、 l が必要になるのは scanf の方だけ。 printf の方では l は必要ない。 ただ、l をつける間違いを犯す人が多く、さらにそれをサポートしているコンパイラも多いため、 C99 になって l を付けてもいいことになった。 lf は f と同じ。
>>217 hf は?
だいたい長さ修飾子に対して浮動少数点数って関係あるの?
上のリンク読む限り関係ないと思えるんだが。
hf はおかしいっつーのは既に
>>216 が書いてあるから
>>215 >>216 >>217 せっかくお答え頂いてるのにいまいち理解できないです・・・。すいません。
この「h」も「l」も書かなくても結果には関係しないのですが、
ここでは「h」も「l」も書く意味はないということですか?
>>217 l (エル)
各変換に対応する引き数が、整数変換では long intか unsigned long int、 n
変換では long long int へのポインタ、 c 変換では wint_t、 s 変換では
wchar_t へのポインタであることを示す。
L
a, A, e, E, f, F, g, G 変換に対応する引き数が long double であることを
示す。 (C99 では %LF を使うことを認めているが、SUSv2 では認められていな
い。)
lfじゃなくてLfのことじゃねえの?上の説明では明らかにlとLは違うし
lの意味を考えるとlfはおかしくね?
>>220 おれは今の場合だと、lもhも指定する意味が無いと思う。
(コンパイルエラーにはされないみたいだが。)
ありうるとすれば、Lfだが、long doubleの
引数を渡してるわけではない(floatの引数になってるよね)
のでLfも無意味だと思う。
>>222 この場合は特に意味は無いんですね。
引数がいまいち分かっていないので、皆さんの説明を上手く理解することができませんでした。
引数はもっと本の先で解説されているようなので、そこまで進んでまた戻ってみます。
アドバイスを上手く活用できなくてすいませんでした。ありがとうございました。
>>223 ほほー thx
以下でいいの?
%f doubleを出力
%lf doubleを出力(実質的には今までの%fと同じ)
%Lf long doubleを出力
要は表記を許しただけということか。
>>225 Yes.
>>226 まあもう少し後でいいんじゃね。
というか、可変個引数の引数の規則とか
先まで進まないとよく分からんと思うし。
C89は実情に見合ってないしC99は明々後日の方向向きすぎ
試したみたのはgcc,bcc32, vsのやつ、です float.hのマクロ定数を表示させる文 1. printf("FLT_MIN = %e\n", FLT_MIN ); printf("FLT_MAX = %e\n", FLT_MAX ); 2. printf("FLT_MIN = %f\n", FLT_MIN ); printf("FLT_MAX = %f\n", FLT_MAX ); としたところFLT_MAXはどちらもまともに表示されるのですが FLT_MINのほうは2.の方が0.000000という表示になってしまいます これはなにがまずいのでしょうか? どなたかお願いします
%.50f くらいやっとけ
>>230 桁が足りなくて丸められてたのですね
ありがとございました
丸められていたというか表示されていなかっただけかと
>表示されていなかっただけかと 処理系依存かどうか知らないけど、printfって小数点以下表示桁で四捨五入しないっけ?
>>233 %fって%.6fと同じだからこれで合ってるんじゃないの?
丸めるか切り捨てるかの話だろ
>>235 あぁいや、大したこっちゃないんだけど、四捨五入した結果だったら、
表示されてないだけというより丸められてるって方があってるかな、と思っただけ。
実際問題じゃどっちでも良いかな
Visual Studio Std 2005 で Win32API を勉強中です。 ウィンドウを表示して、その中にMoveTo や LineTo で線を書くことはできました。 そこで、その書いた線上にマウスを持って行くと マウスポインタが変更できるようにしたいのですが、 どんな感じに作っていけばいいのでしょうか? マウスの位置を調べる関数があるのですが、 マウスが動くたびにその関数を呼び出して、 その値を、先ほど書いた2点間の線上の一次方程式に入れて判断していくとか、 そんな感じになるのでしょうか? それとも、もっと簡単な方法とかあるのでしょうか。 教えてください。
>>239 Win32APIスレの方がいい気もするが。
WM_MOUSEMOVEのlParamを使うなりしてカーソル位置を取得。
特定の方程式があるなら、それに当てはめればいいし、
GetPixel()を使って色で判別とかも出来る。
>>240 色で判別というのもありますね。
いずれにしても、簡単にはいかないみたいですね。
Win32API スレにも質問してみます。
ありがとうございました。
後のマルチである。
243 :
デフォルトの名無しさん :2008/01/19(土) 23:43:44
凄く簡単な質問で、自分で確かめろって感じなんですが、 今実行できる環境がないので、教えてもらえませんか。 <Head.h>で以下のように変数を宣言して、 int var; <Main.cpp>にインクルードしたら、 #include "Head.h" 何もしないでも<Main.cpp>でvarは使えますか? それとも<Main.cpp>で"extern int var;"としないといけないんですか?
じゃ俺も試さないでレスw 多分何もしないで使えるはず。
245 :
243 :2008/01/19(土) 23:52:22
>>244 ありがとうございます。
やっぱ何か心許ないので、後で実験してみます。
すいません。
%e との比較をしたい以上、%f の方が適切じゃね?
248 :
243 :2008/01/20(日) 00:09:50
すいません、なんか混乱してきたのでもう一度質問です。 ------------ <Head.h> extern int var; <Head.cpp> int var; ------------ <A.h> #include "Head.h" <A.cpp> #include "A.h" ------------ <B.h> #include "Head.h" <B.cpp> #include "B.h" ------------ これで<A.cpp><B.cpp>共に同じvarを使えるでしょうか?
>>248 リンケージと宣言、定義について勉強しろ
>>248 使える。
>>249 もしかしたらそれ以前に、#includeの意味がわかっていない気がしないでもない。
私にも力が出せるかな 本気でがんばるから見ててね キミらしく夢を語る瞳 宝石だってかなわない (いちばん) 好きなことで (進める) 道を探そうよ 「大人になることはさみしいことさ」なんて逃げないよ Overwrite 輝きながら あしたを塗り変えるため 最新Dream ステキな毎日を重ねたいだけ 一緒に行こう! とまらない想いがあるってのに 誰にも言えずに温めてた これからは話してみたいんだ キミに会ってわかったよ (ときどき) 確かめ合う (希望が) 色あせぬように 「喜びをふたりで何倍にもしよう」いまを楽しくね Overdive 広がる世界 あしたは無限に続く 最高Trance トキメキながらまた あふれるリズム 何でもできる!? Overdive 広がる世界 あしたは無限に続く 最高Trance トキメキながらまた あふれるリズム 何でもできる!? Overwrite 輝きながら あしたを塗り変えるため 最新Dream ステキな毎日を重ねたいだけ キミの笑顔と 一緒に行こう!
253 :
デフォルトの名無しさん :2008/01/20(日) 18:04:28
メモリ解放というのをいつやればいいのか分からないんですが、 例えば下の場合、methodを抜けたら解放しなくても、 bufは自動でなくなるんでしょうか? void method(){ char buf[100]; int i = 123456; sprintf(buf,"%d",i); }
無くなる。 解放する必要があるのは malloc やら new やらしたやつ
ありがとうございます。
256 :
デフォルトの名無しさん :2008/01/20(日) 18:42:36
サーセン 「+=」 とか 「-=」 ってどんな時使うんですか?(>_<)
>>256 A = A + 2
でAを2回書くのがめんどくさくなったとき。
a = a+10; a += 10;
普通は a = a + 10; なんて書かない。 BASIC や FORTRAN あがりの人が書く程度。
260 :
デフォルトの名無しさん :2008/01/20(日) 22:48:50
最近のVisual C++ではfopenを使うと代わりにセキュアなfopen_sを使えと警告が出るらしいのですが、 fopen_sはfopenに比べてどうセキュアなのでしょうか。
>>260 fopenとfopen_sのソースでも見比べたら?
262 :
デフォルトの名無しさん :2008/01/20(日) 23:04:45
>>262 デバッガで動かして、fopenの中にF11キーで入ればいいだろ。
そうすりゃ分かる。
264 :
デフォルトの名無しさん :2008/01/20(日) 23:10:58
265 :
デフォルトの名無しさん :2008/01/21(月) 00:16:01
も、もうだめだ。 さよなら単位
さよなら(^o^)/~~
267 :
デフォルトの名無しさん :2008/01/21(月) 00:40:28
>>267 経歴が恐ろしくしょぼいなwwwwwwwwwww
>C++未経験ながら、1人でC++の10万行のソースコードの保守及び、3万行の開発を行った。 突っ込みどころはここですか?www
>>260 s付いてるほうは受け渡し用のバッファサイズを指定するようになった。
バッファサイズを超えては読まないようになってる。
errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); 形そのものが違うじゃん
悪い悪い、fopen_sの場合は パラメータの検証が行われます。 pFile、ファイル名、またはモードが null ポインタの場合には、 「パラメータの検証」に説明されているように、これらの関数は 無効なパラメータの例外を生成します。 あとUnicode のファイル ストリームをサポートします
qsort関数について質問なんだが、 必ずしも内部のアルゴリズムがクイックソートだとは限らないよな? 選択ソートが使われてる気がして仕方ないんだが。 でもぐぐってみるとクイックソートが使われてるって書かれてるし…。
規格では具体的なソート手法の指定はないが、 O(N logN) でテンポラリバッファ不要のソート法であるという指定はあったと思う。
んだから、選択ソートは使われていないはず。O(N^2) だから。
ああ、ただし、要素数が少ない場合はわからん。
>>277 ありがとう。
比較関数弄ってみてるものの中々アルゴリズムが特定出来ない…。
O(N log N)だとするとやっぱりクイックソートなのかなぁ。
要素数によって使われるアルゴリズム変わるんですかね。
だとすると新しい発見かも…。
>>274 BCC5.9.2の実装だと途中で挿入ソートに切り替えている
要素数が10以下になると再帰呼び出しのコストが馬鹿に
ならないからだろう
280 :
デフォルトの名無しさん :2008/01/21(月) 02:21:47
281 :
274 :2008/01/21(月) 02:43:21
>>279 VC++ 2005だと要素数が10個になるまではクイックソートで
それ以降は選択ソートを使ってるみたいです。多分。
バブルソートや挿入ソートではなく選択ソートと思った理由は何だろう? 選択ソートは交換回数が少なくて微妙に速度が違うからそこで判断したのかな。
安定じゃなかったんじゃないかな
286 :
デフォルトの名無しさん :2008/01/21(月) 15:28:11
C言語で質問なのです。 下のプログラムは動作確認済みなのですが、なぜ動作するかがわかりません。 iでfor文を考えているのに、for{}の中にiがなくても、動作するのはどうしてなんでしょうか? #include<stdio.h> int main(void){ double a[15]={-256.0,-128.0,-8.0,-2.0,-1.3,-1.0,-0.5,0.0,1.0,1.3,2.0,8.0,128.0,256.0}; double *p; p=a; for(i=0;i<15;i++){ printf("%f\t%p\n",*p,p); ←例えばこの部分がprintf("%f\t%p\n",a[i],p);とかなら納得なのですが… p++; } return(0); }
288 :
デフォルトの名無しさん :2008/01/21(月) 15:46:18
ポインタについてはまだ理解力が足りないと思っています。 ただ、printf("%f\t%p\n",*p,p);にするなら、forの()の中身をpのみで表さないとなんか気持ち悪い気がして… 今までやってきたfor文は()の中の変数が{}の中で必ず使われてきたので…
確かにあんまり行儀のいいプログラムじゃないなぁ。 私ならこう書く。 #include<stdio.h> int main(void) { double a[]={-256.0,-128.0,-8.0,-2.0,-1.3,-1.0,-0.5,0.0,1.0,1.3,2.0,8.0,128.0,256.0}; for (unsigned i = 0; i < sizeof(a) / sizeof(* a); ++i) { printf("%g\n", a[i]); } return 0; } ポインタを使うならこうなるかな。 for (double * p = a; p - a < sizeof(a) / sizeof(* a); ++p) { printf("%g\n", * p); } return 0; } いずれにしろ、定数を生のまま書くのはやめた方がいい。
>>286 >printf("%f\t%p\n",a[i],p)とかなら・・・
それを言うなら、printf("%f\t%p\n",a[i],&a[i]); だろ?
最後のpがokなら、*pもokだろうに。
>>288 p=a; //pがaの先頭(-256)を指す
printf("%f\n", *p); //pが現在指してる値(-256)を表示する
p++; //pが次の要素(0)を指す
printf("%f\n", *p); //pが現在指してる値(0)を表示する
p++; //pが次の要素(-128)を指す
printf("%f\n", *p); //pが現在指してる値(-128)を表示する
以下繰り返し
iを使ってるのは、単に繰り返し回数を数えるため
292 :
デフォルトの名無しさん :2008/01/21(月) 15:56:46
>>289-291 みなさんわかりやすい説明をありがとうございます。
なんとか理解できそうです。
>>288 繰り返し「回数」を明示するためにfor使ってるんじゃね
そのプログラムだとp+iとかp[i]とかでもいいが
ループ回数だけが重要で、何回目のループかはどうでもいいこともたまにある
ループ変数にunsignedを使っちゃう奴を久しぶりに見た
どうみてもわざと
ここで聞いていいか分からないのですが、スレ違いならスレ教えてください。 目的はC++を使えるようになることです。 C++の前にC言語勉強した方がいいということで、(どっかのサイトに書いてあった) 今はC言語を勉強中ですが、 一通り勉強したらC++に移ってもいいでしょうか? それとも、C言語をしっかりやってからの方がいいですか?
>>297 俺は両者を混同しなければいつ移ったって構わないと思う。
まぁせっかくCやってるんだからポインタあたりまでは勉強したほうがいいかもね。
>>298 ありがとうございます。
ざっと一通り勉強してから移ります。
自分の勉強の方針くらい自分で決めろよ 学習を進めていけば、次に何をしたらいいかくらい 自分で判断できるようになる。 C++の勉強を始めたが最期、Cの勉強には一生戻れない というわけでもあるまいし。
逆に考えるんだ。 次にやるべきことを判断できるようになるまで 真面目に勉強する気が最初からないと考えるんだ。
というようなキチガイ的な返事しか出来ないのがプログラマw 個人的にはいきなりC++でも全然問題ないと思う。
>>295 > なんかまずいんですか?
・ふつーint
・差をとったりして負の数が出てくる計算で気分的によろしくない
>for (unsigned i = 0; i < sizeof(a) / sizeof(* a); ++i) { forの初期化のトコで宣言出来るのってC99だっけ?
C++も
size_t型が符号なし整数として定義されている環境だと、iがsignedの場合 i < sizeof(a) / sizeof(* a); の部分で「signedとunsigned比較すんなボケ」という警告が出るから unsignedにしたんだろう。 だがこれだと、size_t型が符号あり整数として定義されている環境では 逆に警告が出る。 これが嫌な人は(sizeof(a) / sizeof(* a))の方をcastしたりするんだろうけど、 signedなsize_t型なんて聞いたことないからぶっちゃけどーでもいい。
根本的に違うんじゃね? for文回すのにunsignedがいけないという理由は for (unsigned i = 0; i > 0; i--) { ... } というような回し方をしてたら、unsignedだから結局、 0未満は無いで、知らずに無限ループにハマってしまうからやめろ とか、そんな理由の奴は聞いた事がある
そもそも、回数が固定なループを書くときに 継続条件に < を使うのがおかしい。!=を使え。
309 :
デフォルトの名無しさん :2008/01/21(月) 23:15:54
signed/unsigned関係ないし・・・ iteratorならよく見るが、ふつうは不等号じゃね?
>>306 >だがこれだと、size_t型が符号あり整数として定義されている環境では
そんな環境ありえねー。
>>307 そのループ1回も実行されないぞ。
まずいのは、例えば i を 9, 8, ... 1, 0 としてループしたい時に
for(int i = 9; i >= 0; i--){ ... }
って書いた場合、int を unsigned int にすると、
>>307 の言うようにはまる。
でも、最近のコンパイラなら i >= 0 が偽にならないとかの警告が出るものも多いよ。
>>308 ネタだろうが、それはない。
俺もたまに使ってしまう>unsigned vectorなんかを添え字で単純に回したいとき。 くせというかなんというかw
>>310 >>308 ネタだろうが、それはない
iteratorでなくとも
Cの場合でもループの不変な表明を考えた場合
!= を使うべきことは非常に多い。
i != NUMS
の場合、ループ終了後はi == NUMS であることが保障される。
が、i >= NUMS だとそうはいかない。
どっちが速いの?
>>314 変わらないだろ。
0との比較は速い場合がある。
for(int i=10; i; i--) { ... } // 10回ループ
たまに数字飛ばしたりするからi>0って書くな
>>315 まさか、Javaでもあるまいし普通のコンパイラは速度差がないコードを吐くと思うぞ。
for(unsigned int i=10; i>0; i--) { cout << i << endl; } →期待通り for(unsigned int i=10; i>=0; i--) { cout << i << endl; } →無限ループ 理由、 unsignedの値はmax→→→→→→0→maxになる。 上のループだと偽(i==0)があらわれる。下のループだと常に真だから無限。 おk?
>>317 0との比較はゼロフラグを使えるので、効率が良い。
アセンブラの話な。
もちろん、命令パイプラインの効果で差が無くなるかもしれないが、
「場合がある」ということで。
>>319 言われて見れば同じ事言ってるw つうか微妙に違う事言ってるのかと思って。
>>319 のような言葉でしっかり確信持てることもある。
ということで、言葉は人をなめてるが実は優しい
>>319
>>320 その話を知ってからいろんな環境で実験したけど未だに実感できたことがない。
ハンドアセンブルするような環境ならそりゃ違うけど・・・
>>322 だって期待できるコード削減量って
ループ1回につき比較命令1つ程度なんだから、
実感は難しいかなあ。
いや、実験はそりゃ億とか兆とかするよ? CPUの周波数がわかってれば期待できる短縮時間は予測できるじゃん? んでも、どんだけ回しても測定誤差程度の値しか出ないんだよ・・・逆転も往々にしてあるし。
なんか自分で書いててアセンブラで比較してステート数確認すりゃいいじゃんとか思ってしまった・・・
アセンブリ吐いて比較してるよね? 場合によっては逆順に最適化されることもあると聞いた事あるが。
>>306 規格でsize_tは符号なしと決まっている。
VC9なんですけど #define WIDEN2(x) L ## x #define WIDEN(x) WIDEN2(x) #define __WFILE__ WIDEN(__FILE__) このマクロをもっと圧縮できませんか? 二行くらいに。
できないから3行なんだ。 #define WIDEN(x) L#x #define __WFILE__ WIDEN(__FILE__) VC9を持ってないからこれがコンパイル通らなきゃ不可能。 ってか通ったところでほかの環境でも通るとは限らないが。
真ん中飛ばせる希ガス
みり
switchでcaseが大量にあるときに、 高速化を狙って関数ポインタの配列に するって手があると思うんですが、 ポインタ関数の呼び出しのオーバーヘッドは case何回くらいに匹敵するんでしょうか? 皆さんだったらcase何回くらいからポインタ関数 配列に換えますか?
>>332 そういう風に出来る switch は
普通はジャンプテーブルに最適化されるから
気にしなくてもいいぜ。
関数ポインタを使うのは高速化を目的とするものじゃなくて、
実装の利便性やら可読性やらを目的とするもんだ。
>ジャンプテーブルに最適化される そうだったのか!w わざわざ変えてたのは無駄だったんですね。
実は、関数テーブルではなくジャンプテーブルなので、手動で関数テーブルにするより高速。
337 :
デフォルトの名無しさん :2008/01/22(火) 03:28:00
>>332 実際は、ifで分岐を書いた方が高速
もし等確率で起こるならcaseの最適化がifより速くなることもあるが
CPUには分岐予測があり、30%くらいを占める分岐があればそれを始めに判定することでかなり速くなる
テーブルにアクセスする時間との兼ね合いで ジャンプテーブルに最適化するかどうか 決めてたりしないのか? コンパイラは。
>>337 分岐数が100とか1000とかに達するような場合でも
CPUの分岐予測って効果あるんですか?
既存のクラスParentを新しいクラスChildに継承させたいのですが、Parentに規定のコンストラクタがなく、必ず引数を必要とする場合の子クラスのコンストラクタの書式が分かりません。 親切な方、どうか助けて下さい。
初期化子つけりゃいいだけじゃん
>>341 初期化子に親クラスで定義されている変数を引数として使えないことを知らなかった…
親クラスに少し手を加えて自己解決しました
勘違いしてる悪寒
wchar_tについて質問です。 実装によってはwchar_tのサイズは2byteなようですが、これはサロゲートペアは どのような扱いになるのでしょうか? 1.サロゲートペアは見なかったことにする。結果サロゲートペアが必要な文字は文字化けする。 2.サロゲートペアも適切に処理。結果文字列の長さが変わる。
fgetsは改行までを読み込むんだよ。
取り敢えず、kaiseki.cvsなんて名前はやめよう。誤解の元だ。
>>328 #define AL2TL(x) TEXT(##x##)
#define __TFILE__ AL2TL(__FILE__)
とか
VC2008で、「where」という単語使うと 予約語みたいで青くなるんですけど。 .NETの予約語みたいなんで使ってもいいですか?
>>344 wchar_tの中身がUnicodeとは限らないので、その質問は一般的には無意味。
で、Windows環境は確かにwchar_tは2バイトなんだけど、サロゲートペア
が問題になるかどうかはどういう処理をするかに依存するので、やるこ
とをもっと具体的に書いたほうがいいかも。
言語周りのAPIなり何なりに任せるしかないんじゃね?
文字数を数えたいときって,サロゲートペア以外に 合成文字も考えなきゃだめだよね? もう,ウンコでそう.
もう1文字8バイトにしちゃいなYO
>>349 whereは予約語になる予定だったが
よく使われていたので却下された。よって使ってよし
みんな大好きデバナガリ
あなたも私も結合音節
>>350 確かに仕様ではwchar_tの中身もサイズも未定義でした。すいません。
やりたいことは、UTF-8のテキストをFreeTypeに突っ込みたいのですが、よくよく考えたら
FT_Get_Char_Indexの引数はFT_ULongで32ビットでした。
サロゲートペア関係ありませんでしたねOTL
#define max(x,y) ({ \ typeof(x) _x = (x); \ typeof(y) _y = (y); \ (void) (&_x == &_y); \ ←これ _x > _y ? _x : _y; } ) 上記の4行目だけ良く判りません。 これは、変数_x と _y の格納場所アドレスが同じ場合、 真(1)になるという意味だと思いますが、文がここで終わって まして、このような場合どのように解釈されるんでしょうか?
型が違う場合に(intとdoubleのmaxとか)コンパイルエラーを起こさせて 落とすための仕掛けじゃないかという気がする。確かめたわけじゃ ないからほんとにそうなるかわかんないけど。
360 :
358 :2008/01/23(水) 15:53:12
gcc 3.4.4 で int と long 型の変数を max に与え、4行目のあり・なしでコンパイルしてみた所、 確かにありの場合だけ warning: comparison of distinct pointer types lacks a cast が出ました。なるほどー ちなみに、_x > _y でも比較を行っていると思うのですが、ここでは弾かれないんですね…
数値の比較は暗黙の型変換されるからね。 ポインタだとそれがない。
362 :
358 :2008/01/23(水) 16:03:06
よく分かりました。ありがとうございました。
363 :
デフォルトの名無しさん :2008/01/24(木) 13:08:33
cabファイルに、ファイルを追加圧縮したいのですが、DLLの説明書には出来ないとあります しかしアーカイバで対応しているものがあります C言語ではどのようにやればいいのかわかりますか
一旦どこかに展開してから再圧縮してるのでは。
365 :
デフォルトの名無しさん :2008/01/24(木) 13:15:21
そうみたいです ありがとうございます
昔のVCの話ですが。
めでたし、めでたし。
日本語のWindows98で動くプログラムは_MBCS指定しますか?
ケースバイケース
370 :
デフォルトの名無しさん :2008/01/24(木) 19:33:00
32bit数どおしの足し算が範囲を超えたのかチェックするにはどうすればいいですか if無しで出来ますか
371 :
デフォルトの名無しさん :2008/01/24(木) 19:37:22
a、bが1ビットならば a + b = (a and b, a xor b)_(2) ですが32bitはどうすればいいですか
>>370 何も考えずに、一番簡単なやり方でやろうと思えば、64bit整数にキャストして足し算してしまうことだな。
後は(a+b) と aの大小を比較するとか。
374 :
デフォルトの名無しさん :2008/01/24(木) 19:45:23
比較とかキャストしないでマシンに手間がかからないでやる方法ないですか
375 :
デフォルトの名無しさん :2008/01/24(木) 19:48:02
>>372 C言語は、1bit単位の変数ないし、加算器をソフトウェアで実装すると鈍いです
速い方法ないですか
a + b > INT_MAX ↓ a > INT_MAX - b
377 :
デフォルトの名無しさん :2008/01/24(木) 19:51:39
1bitみたいに桁上がりをandや+を使ってわかりませんか
比較っつっても真偽値取得するだけなら setxx 命令使えるから遅くはならないと思うがね。
キャリーフラグとか? まぁ、どっちにしても比較はいるわなぁ……
a + bで、 aとbの符号が異なれば、オーバーフローすることはない。 同符号の場合、aやbの符号とa + bの符号が異なれば、オーバーフローしている。
インラインアセンブリ?
382 :
370 :2008/01/24(木) 20:02:29
いい方法みつけたような気がします unsigned intだとします 桁上がりが起こるならどちらかの31bit目が1です 2^32からその数を引けばあといくつで桁上がりするかわかります そこで2の補数を求めてから2つの数を足してみて、31bit目が1なら負なので桁上がりしません
mov eax, a xor edx, edx add eax, b setc dl もうこれでええっしょ。
384 :
370 :2008/01/24(木) 20:10:10
間違えました でもいい線いってるきはします
OFビットを見るほうがいいんでね?
久しぶりだからOFとか忘れてたお・・・
387 :
370 :2008/01/24(木) 20:17:58
a+b; のあとにOFはどうすれば調べられるんですか
インラインアセンブリでごりごり
((a >> 1) + (b >> 1) + (a & b & 1)) & 0x80000000 これでどうよ? シフト2回入っちゃうけど。
390 :
370 :2008/01/24(木) 20:27:42
良いですね 下位1bitの桁上がりを求めて、1bitシフトさせたものに加えれば桁上がりがわかりますね サンクス
何か a >= (unsigned)-b の方が速い気がする。 ちゃんと実測してソースつきで報告よろ。
符号ありなの無しなの?
なしっぽい流れ
394 :
370 :2008/01/24(木) 20:58:30
なんか、if文の方が速いかも・・・BCC5.5の場合
#include <iostream>
#include <time.h>
using namespace std;
#define N 1000000
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)
main(){
unsigned int *a=new unsigned int [N];
unsigned int *b=new unsigned int [N];
int n,cl,clsum[3],s=0;
for(n=0;n<3;n++)clsum[n]=0;
for(n=0;n<N;n++){ a[n]=rnd(); b[n]=rnd();}
for(int k=0;k<200;k++){
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]
>>1 )+(b[n]
>>1 )+(a[n]&b[n]&1))
>>31 ;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){unsigned int x=a[n],y=b[n];s+=((x
>>1 )+(y
>>1 )+(x&y&1))
>>31 ;}clsum[2]+=clock()-cl;
}
cout<<"if文の速度 "<<clsum[0]<<endl;
cout<<"if無しの速度1 "<<clsum[1]<<endl;
cout<<"if無しの速度2 "<<clsum[2]<<endl;
}
396 :
デフォルトの名無しさん :2008/01/24(木) 21:00:27
最適化しないように文末にcout<<(s&1);を入れて下さい
if文じゃないだろif文じゃw 条件式だ。
398 :
デフォルトの名無しさん :2008/01/24(木) 21:08:11
メモリアクセスに時間かかるようなのでパラメータ変更しました これだと微妙に論理演算のほうが速いかも
#include <iostream>
#include <time.h>
using namespace std;
#define N 10000
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)
main(){
unsigned int *a=new unsigned int [N];
unsigned int *b=new unsigned int [N];
int n,cl,clsum[3],s=0;
for(n=0;n<3;n++)clsum[n]=0;
for(n=0;n<N;n++){ a[n]=rnd(); b[n]=rnd();}
for(int k=0;k<30000;k++){
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]
>>1 )+(b[n]
>>1 )+(a[n]&b[n]&1))
>>31 ;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){static unsigned int x=a[n],y=b[n];s+=((x
>>1 )+(y
>>1 )+(x&y&1))
>>31 ;}clsum[2]+=clock()-cl;
}
cout<<"if文の速度 "<<clsum[0]<<endl;
cout<<"if無しの速度1 "<<clsum[1]<<endl;
cout<<"if無しの速度2 "<<clsum[2]<<endl;
cout<<(s&1);
}
#include <stdio.h>
#include <time.h>
#define N 10000000
int main() {
unsigned a, b=0;
int k;
int cl, clsum[2] = {0};
for(k=0;k<200;k++) {
cl=clock(); for(a=0;a<N;a++)b+=(a>=(unsigned)-b); clsum[0]+=clock()-cl;
cl=clock(); for(a=0;a<N;a++)b+=((a
>>1 )+(b
>>1 )+(a&b&1u))&0x80000000u; clsum[1]+=clock()-cl;
}
printf("条件式 : %d\n", clsum[0]);
printf("ビット演算: %d\n", clsum[1]);
printf("%u\n", b);
return 0;
}
条件式 : 1004
ビット演算: 1235
1
最適化忘れてた 条件式 : 600 ビット演算: 677 MacOSX Core2Duo 2.16GHz gcc -O2
#include <stdio.h>
#include <time.h>
#define N 10000000
int main() {
unsigned a, b=0;
int k;
int cl, clsum[3] = {0};
for(k=0;k<200;k++) {
cl=clock(); for(a=0;a<N;a++)b+=(a>=(unsigned)-b); clsum[0]+=clock()-cl;
cl=clock(); for(a=0;a<N;a++)b+=((a
>>1 )+(b
>>1 )+(a&b&1u))&0x80000000u; clsum[1]+=clock()-cl;
cl=clock(); for(a=0;a<N;a++)b+=((a
>>1 )+(b
>>1 )+(a&b&1u))
>>31 ; clsum[2]+=clock()-cl;
}
printf("条件式 : %d\n", clsum[0]);
printf("ビット演算1: %d\n", clsum[1]);
printf("ビット演算2: %d\n", clsum[2]);
printf("%u\n", b);
return 0;
}
条件式 : 566
ビット演算1: 672
ビット演算2: 701
やっぱり条件式が一番速い。
std::exceptionを継承して使う場合 勝手にメンバとか付け足してもいいですか? たとえばHRESULTとか
ビット演算は健闘はしているけど、 いかんせん式が複雑すぎたな。
405 :
デフォルトの名無しさん :2008/01/24(木) 21:21:51
『最大50桁の自然数2つを、文字列として入力させて積を出す』 という問題が出たんですが。 先生とのメールのやりとり↓ 私「筆算の方法で行う」 先「積は和の繰り返しで表すこともできます」 私「最初の数値を次の数値分だけ足し算する (2×3 = 2+2+2)」 先「桁数が多い場合単純に繰り返すだけではだめです」 どうすればいいでしょうか(:_;) お願いします
コピペか?
407 :
デフォルトの名無しさん :2008/01/24(木) 21:24:43
>>398 をVC++6でやると論理演算の方が速いよ
1248
1108
1425
となる
BCC5.5では
1931
2878
2160
最近どっかで見たな。
409 :
407 :2008/01/24(木) 21:28:38
GCC(MinGW)では
829
1236
1841
同一スペックで
>>398 を動かしたとき
>>398 ウチではこうなった。
1245
688
1302
>>398 ウチではこうなった。
if文の速度 100
if無しの速度1 111
if無しの速度2 107
あまりに早く終わるので N を 10 倍した if文の速度 896 if無しの速度1 1008 if無しの速度2 1061
413 :
407 :2008/01/24(木) 21:47:10
単純な計算と比べてもほんど無視できる程度しか変わらなかったよ・・・
#include <iostream>
#include <time.h>
using namespace std;
#define N 10000
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)
main(){
unsigned int *a=new unsigned int [N];
unsigned int *b=new unsigned int [N];
int n,cl,clsum[4],s=0,t=0;
for(n=0;n<4;n++)clsum[n]=0;
for(n=0;n<N;n++){ a[n]=rnd(); b[n]=rnd();}
for(int k=0;k<30000;k++){
cl=clock();for(n=0;n<N;n++)t|=a[n]&b[n]&1;clsum[3]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]
>>1 )+(b[n]
>>1 )+(a[n]&b[n]&1))
>>31 ;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){static unsigned int x=a[n],y=b[n];s+=((x
>>1 )+(y
>>1 )+(x&y&1))
>>31 ;}clsum[2]+=clock()-cl;
}
cout<<"比較演算の速度 "<<clsum[0]<<endl;
cout<<"論理演算の速度1 "<<clsum[1]<<endl;
cout<<"論理演算の速度2 "<<clsum[2]<<endl;
cout<<"単純な論理演算の速度 "<<clsum[3]<<endl;
cout<<(s&t&1);
}
414 :
407 :2008/01/24(木) 21:49:39
>>412 Nはランダムの2数を確保する数なので大きくすると
純正のメモリ外に書き込まれる可能性が出てきてしまいます
増やすときは、kの繰りかえし数を上げてみて下さい
>>414 ううん。微妙な結果。
if文の速度 1004
if無しの速度1 996
if無しの速度2 1112
安定して正確な速度がはかれるっぽいコードです・・・スタック領域に少量確保しました わずかに論理式のほうが速いかもしれないです
#include <iostream>
#include <time.h>
using namespace std;
#define kukikaesi 300000
main(){
#define N 1000
unsigned int a[N],b[N];
int n,cl,clsum[4],s=0,t=0;
for(n=0;n<4;n++)clsum[n]=0;
for(n=0;n<N;n++){
#define rd() (rand()&255)
#define rnd() rd()+(rd()<<8)+(rd()<<16)+(rd()<<24)
a[n]=rnd(); b[n]=rnd();}
for(int k=0;k<kukikaesi;k++){
cl=clock();for(n=0;n<N;n++)t|=a[n]&b[n]&1;clsum[3]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=(a[n]>UINT_MAX-b[n]);clsum[0]+=clock()-cl;
cl=clock();for(n=0;n<N;n++)s+=((a[n]
>>1 )+(b[n]
>>1 )+(a[n]&b[n]&1))
>>31 ;clsum[1]+=clock()-cl;
cl=clock();for(n=0;n<N;n++){static unsigned int x=a[n],y=b[n];s+=((x
>>1 )+(y
>>1 )+(x&y&1))
>>31 ;}clsum[2]+=clock()-cl;
}
cout<<"比較演算の速度 "<<clsum[0]<<endl;
cout<<"論理演算の速度1 "<<clsum[1]<<endl;
cout<<"論理演算の速度2 "<<clsum[2]<<endl;
cout<<"単純な論理演算の速度 "<<clsum[3]<<endl;
cout<<(s&t&1);
}
微妙すぎるのでこれにて終了します ありがとうございました
>>416 VC++2008EE Debugビルド
Vista Athlon Dual 4400+ 2.31GHz
比較演算の速度 2030
論理演算の速度1 2678
論理演算の速度2 1948
単純な論理演算の速度 1817
419 :
デフォルトの名無しさん :2008/01/24(木) 22:32:23
超初心者の質問なのですが、、、 #include <iostream> int main() { double a = 3.55; int n = a * 100; std::cout << n << std::endl; return 0; } これの出力が354になります。355ではなく354になるのはどうしてなのでしょうか?
3.55は浮動小数点だと無限小数になって、Intに型変換すると切り捨て誤差が出る。 詳しい解説が読みたければ「浮動小数点 誤差」くらいでぐぐってみれ。
421 :
デフォルトの名無しさん :2008/01/24(木) 22:42:28
>>405 回数分足すのはさすがに重いだろ
一桁ずつ掛けて、そのあと和の繰り返しを使うんじゃないのか?
例えば112×235なら
5×112=560
3×112=336
2×112=224
560+3360+22400=26320
とか
まあ俺の力じゃプログラムは作れないけどなw
>>419 VC++ 2008 では355になる。
xに近い整数にするには、x +0.5を整数にすればいいのでは 変換時に切り捨てられる為
>>420 a * 100 ではintの100がdoubleに昇格して計算されて結果もdoubleだろ。
355になった後でintに変換されるから関係ないと思うんだが。
354.99999999999999999なら354
>>425 おお、そういうことか。あくまでも近似値なんだよな。
BYTE値を0.75倍し、その整数部のみを得たいのですが、 単に0.75を掛けて少数切捨てするより効率がよくて速度出る計算方法がありますかね BYTE >> 1 のようなもの(これは1/2ですが…)があれば教えていただけませんか?
>>427 コンパイラの最適化に任せる。
整数で処理する(最適化に負けるかもしれない)
int value = 123456;
value = value * 75 / 100;
シフト演算で頑張ってみる(1/2+1/4なので)
int value = 123456;
value = value >> 1 + value >> 2
>>427 (BYTE)(((WORD)x) * 3 / 4)
>>427 (BYTE + BYTE << 1) >> 2
(x + (x<<1)) >> 2
>>429-431 おおいろいろ方法があるんですね
みなさんありがとうございます!
早速試してみますね
434 :
デフォルトの名無しさん :2008/01/24(木) 23:02:56
1 の位 = 1 の位の積の 1 の位 10 の位 = (1 の位と 10 の位の積の 1 の位 + 1 の位の積の 10 の位) の 1 の位 100 の位 = 1 の位と 100 の位の積の 1 の位 + 10 の位の積の 1 の位 + (1 の位と 10 の位の積の 1 の位 + 1 の位の積の 10 の位) の 10 の位 : : :
436 :
デフォルトの名無しさん :2008/01/24(木) 23:08:23
>>405 俺が思うに
お前の筆算の仕方が間違ってたんじゃないのか
筆算以外にやりようないと思うんだが
437 :
405 :2008/01/24(木) 23:29:58
先生にまた聞いたら筆算のしかたが間違ってたみたいです、、
>>421 みたいなやりかたどうやるんですか?
ぼくのだと
「112*235=560+336+224=1120」になっちゃいます
桁シフトしとらんがな。 つーか、どうせならインド式実装してみたら?
newで配列として確保した後、その要素数を取得する方法はありますか?
基本的にはない。 つーか、大抵の場合は std::vector 使っておけば問題ない。
>>439 嫌になるほど繰り返し質問されていることですが、ありません。
newなんて使わずにstd::vectorを使いましょう。
ない。std::vectorでも使え。
std::vector 使え!
std::vector使えよ
場合によっては取得できるんだが・・・ そういう事はむやみに教えると悪い影響与えそうで困る。
std::vectorってなんですか?習ってないです。
増やした分を保持しておけばよいが、vectorは勝手に保持するからプログラムが簡単になる
448 :
439 :2008/01/24(木) 23:40:37
みんなThx!ふと気になってレス見ないで書いちゃった、スマソ。。
#include <vector> using namespace std; main(){ vector < int > a(100); a[0]=1; a[1]=2; }
main.cpp:4: error: ISO C++ forbids declaration of ‘main’ with no type main.cpp:4: error: ISO C++ forbids declaration of ‘main’ with no type lipo: can't figure out the architecture type of: /var/tmp//ccLa7Foj.out make: *** [debug/main.o] Error 1
今年のカレンダー表示ってどうやるんですか?
作って表示すれば?
エンディアンの勉強をしてまして、色々ググってみると、例えばリトルエンディアンの場合、 0x1234abcd の値をメモリーに格納する際、下位アドレスから順に、cd ab 34 12 と入りますが、 ここで疑問なのが、1バイトの中身のビット列はどのように扱われているのか?という点です。 1バイト8bit分のデータは、エンディアンにかかわらず常に、例えば 0x12 は、00010010 のビット列 が保たれているのでしょうか?
454 :
405 :2008/01/25(金) 00:03:17
405ですが
筆算の問題、
>>421 みたいに全部かけた後にまとめて足すってできるんですか?
それとも2桁ずつ掛け算して足してかないとむり?
例えば123*123だったら
123*3=369
123*2=246
→369+2460=2829
123*1=123
→2829+12300=15129
455 :
デフォルトの名無しさん :2008/01/25(金) 00:07:35
>>454 421のやりかたでできるだろ
下のだとめんどくさくないか?
よくわからんのだが
>>453 エンディアンは多バイトデータの配置の種類
1バイトは関係ない(同じ内容になる)
>>453 1バイトがどのように格納されていようが、
どうせ1バイト単位でしかメモリアクセスできないのだから、
違いは観測できないだろ。
458 :
457 :2008/01/25(金) 00:34:10
そういえば、ビットアクセス命令のあるCPUもあるか・・・
1byteが12bitの環境もあるわけで
環境がBCCDeveloperというものです。 hoge.txtという名前のテキストファイルを作るプログラムで 同じフォルダの中にすでにhoge.txtという名前のテキストファイルがあったら もともとあったテキストファイルの名前をhoge1.txtとして変えて新しく作るテキストファイルを hoge.txtとすることはできるでしょうか。 できる場合はどうしたらいいでしょうか。
>>460 hoge.txtがあるかどうかを調べる
あったらファイル名を変更する
hoge.txtを作る
System("if exist ren hoge.txt hoge1.txt");っていけるのかな?
>>461 すばやい回答ありがとうございました。
早速とりかかってみたいと思います。
>>454 とりあえず10桁で作ってやったぞ。わからんとこあったら聞いてくれ。
#define N 10
int main( void )
{
int a[ N ] = {0,1,2,3,4,5,6,7,8,9};// 9876543210
int b[ N ] = {0,1,2,3,4,5,6,7,8,9};// 9876543210
int result[ N * 2 ] = { 0 }; // 9876543210*9876543210=97546105778997104100
for ( int i = 0; i < N; i++ ) {
for ( int j = 0; j < N; j++ ) {
result[ i + j ] += ( a[ i ] * b[ j ] );
for ( int k = i + j; k < N * 2 - 1; k++ ) {
if ( result[ k ] < 10 ) break;
result[ k + 1 ] += result[ k ] / 10;
result[ k ] %= 10;
}
}
}
for ( int i = N * 2 - 1; i >= 0; i-- ) {
printf( "%d", result[ i ] );
}
return 0;
}
こんなかんじか #define kosu 4 add(unsigned int *a, unsigned int *b, unsigned int *c){ int ketaagari=0; for(int n=0; n<kosu; n++){ c[n]=a[n]+b[n]+ketaagari; ketaagari=a[n]>UINT_MAX-b[n]; }} seki(unsigned int *a, unsigned int *b, unsigned int *c){ }
50桁までカウントさせるのが面倒で積は諦めた
500メガ程度の複数のテキスト文書があるとします これから単語の頻度を求めたいとします どのようにしたらいいでしょうか? 単語は最低4バイトのものを言います 配列でカウントできないし良い方法ありますか
3バイトの頻度なら、int
>>466 最低4バイトということは200Kバイトの単語がある可能性も考慮しないとだめですか?w
>>468 厳密に求めなくて良いです 高頻度の単語が抽出出来ればいいです 1単語しかなければもとめなくていいです
一回目で24bit列を配列でカウントして、 2回目でたとえば100回以上出現したものの後ろ10バイトずつファイルに切り出して そのファイルごとにしらべればいいか
471 :
デフォルトの名無しさん :2008/01/25(金) 07:23:25
>>420 ありがとうございます。なので、
0.55, 1.55, 8.55 =>切り上げなので、上記現象なし
2.55 〜 7.55 =>切り下げなので、上記現象あり
なのですね。
ところで、上記質問をしてから色々調べたのですが、浮動小数点(例えばC言語のdouble)の
仮数部の丸めについて、丁度中間の場合は偶数になるように丸める、というルールが
あるらしいのですが、これは小数点の場合にどういう風に当てはまるのかわかりません。
これって二進数だと全部あてはまってしまうような気が、、、
どうなっているのでせうか
>なのですね。 いいえ。
473 :
デフォルトの名無しさん :2008/01/25(金) 11:27:52
#include <stdio.h> #include <stdlib.h> #include <string.h> void fileread(int,char * []); int main(int argc ,char *argv[]) { if(argc!=3){printf("次回から引数を入力してください\n"); return 0; } if(!strcmp(argv[2],"r")){ fileread(argc,argv); } return 0;} void fileread(int argc,char *argv[]){ FILE *fp; char *buffer,*str,*n,*s; fpos_t start_fpos; int filesize,count=0; fp=fopen(argv[1],"r"); fgetpos(fp,&start_fpos); fseek(fp,0,SEEK_END); filesize=ftell(fp); fsetpos(fp,&start_fpos); buffer=(char *)malloc(sizeof(char)*filesize); str=(char *)malloc(sizeof(char)*1000); printf("検索する文字列を入力してください\n"); scanf("%s",str); while(s=fgets(buffer,filesize,fp)){ count++; n=strstr(buffer,str); if(n){printf("%d行目 %s",count,s) }; } free(buffer); fclose(fp); }
474 :
473 :2008/01/25(金) 11:30:38
>473 csvファイル検索プログラムを作ったのですが、ファイル名にワイルドカードが使えないので 実用性にかけます。上記のプログラムにワイルドカードの組み込むにはどうすればいいでしょうか? ただし、ファイル名はmain関数の引数で取得いたします。_findfirst,_findnextを使うところまでは なんとなく理解しました。
>>474 環境は?
場合によっては wildargs とか使える場合もある
476 :
473 :2008/01/25(金) 11:41:30
OSはCENTOS 5です。コンパイラにはgccを使っております。
ワイルドカードはどんなのを? そのままだとシェルが勝手に展開しない?
>>473 またお前か。あちこちおかしなプログラムなのは相変わらずだな。
最低でも、バッファオーバフローの可能性は排除しておけよ。
479 :
473 :2008/01/25(金) 12:20:12
>>477 *.csvとかですね。
そのままでは無理でした。
>>478 その件については、なんか知らんけどプログラムができあがりました。
あらかじめ指定されている仕様でしか作ったらいけないことになっておりまして、
どのようにすればそのようにできあがるのか悩まされている次第です。
一応さきほどのプログラムは作りましたが、io.hは無いそうで、_findnextも使えないですね。
こういうときそのヘッダファイルをダウンロードしてヘッダファイルがたくさんあるところに放りこめばいけますか
ヘッダだけ持ってきたって実装したライブラリが無きゃ無理だろ。 通常は、シェルが展開するんだが、、、opendir、readdir使って 正規表現で検索するとかしてみては
481 :
473 :2008/01/25(金) 12:49:24
>>480 ありがとうございます。
階層を一段間違えておりました。
普通に通りますね。よかった・・・
482 :
デフォルトの名無しさん :2008/01/25(金) 13:31:29
>>472 int main() {
double d = 3.55; // ここの数字を変更する
int n = d * 100;
cout << n << endl;
return 0;
}
でも上記プログラムでは、浮動小数点の規格上、
d = 0.55, 1.55, 8.55 =>それぞれ0.5500000....1, 1.55000...1, 8.55000...1
とかになるので、100倍しても減ったように見えたりしない。
d = 2.55, 3.55, 4.55, 5.55, 6.55, 7.55 =>それぞれ2.5499999...などとなるので、
100倍すると、(double)254.99999==>(int)254などとなってしまう。
と理解していたのですが、他の方も書いてくれてたように、Visual C++ 2008でやると
d=3.55の時、355と表示されました。(gccは354)
VC++がx86の80ビット浮動小数点数レジスタを使い回すからかと思ったけど、 一旦64ビットでメモリに書きだすように仕向けてもやっぱり355になるな。
関数に配列へのポインタへ渡してデータょ書いてもらう場合 std::vector buffer(1024); hogefunc(&buffer[0]); とかくのは違法ですか?
確保したバッファサイズをはみ出さないのなら問題ない
private:な物の位置調べて無理やり書き込むわけだが。
そういうことができるように、 vectorは生の配列同様、要素の連続性が保証されている。
inline int nazo(void) { return __LINE__; } 呼び出すと戻ってくるのはどこのあれですか?
そこ
たぶん3
__LINE__やら__FILE__やら__func__はコンパイル時に埋め込まれる
__func__ マクロじゃなくて定数だったはず。
495 :
デフォルトの名無しさん :2008/01/25(金) 21:09:16
ik88 ectuo\ }{([8 ]\@p : dcdc dcdcdcfvfv7qa11111111111111111111111111111111 mnbcadcfvghujk,ol9iikurf4ed333333333333333331W2E3TR4G56
きーけぼーどのいちばんうきえらをうつと 12w3e4rgt5h6789o0:^\ !"#$G%H&'()~*=~| とにゅうりょくされます。 こしょうですか?
pepper
スキンラインの短絡
499 :
デフォルトの名無しさん :2008/01/26(土) 03:17:03
APIについての質問です。 Visual C++ Express 2008で英単語印刷ソフトを作っているのですが、 ウインドウに、ネットの検索欄のような入力欄を作ることは可能でしょうか? それを使って単語の検索機能などを追加したいのですが・・・。 もしよろしければ教授ください。
VCスレかAPIスレ池。
501 :
デフォルトの名無しさん :2008/01/26(土) 09:28:53
>>482 gccでも、-msse2オプションをつけてコンパイルすると、355を返すバイナリを作れました。
でも、80ビットでも、52ビットでも、切り捨てになるから、どちらでも同じと思うんですが。
なんでだろう。
>>501 >482のコードだけなら、最適化で定数は事前(≒コンパイル時)計算されるから不思議ではない。
503 :
デフォルトの名無しさん :2008/01/26(土) 20:29:17
>>502 以下のコードでも、dに3.55を入力すると、表示は354になりますが、
-msse2でコンパイルすると355になりました。
int main(int ac, char **av)
{
double d;
cin >> d;
int n = d * 100;
cout << n << endl;
return 0;
}
確認のために聞きたいんです 関数テンプレートについてなんですが。 template<typename T> void func(){ hoge = new T(); } func<HogeClass>(); つう書き方に、何か問題はありますか? 一応BCCでは動いてるようなんですが、 検索しても基本的に引数のために使われていて、 こういう書き方を見つけられなかったので不安なんですが。
>>504 全然問題ない。それができないならテンプレートの魅力が半減ですよ。
>>505 どうもです。こういう使い方はやっぱり便利なんですね。
でも、混乱もしそう。使いこなせるよう精進します。
>>503 手元のgccだとそのコードでも355になるよ。354になるときの値をprintf("%.20g", d * 100)で出してみて。
C++ で、perl の Data::Dumper みたいなことするのがあれば 教えてください。
テキストファイルをchar型に読み込んだ場合って改行があったら\nもちゃんと格納されるの?
読み込みかたによる。
ありがとう。読み方によるのね できれば\nが格納される読み方の例教えていただきたい
fgets
ファイルの開き方も重要じゃないか
>>512 ありがとうございます。
fgetsって\nの手前までしか格納されないかと思ってたけど\nもちゃんと入るんですね
とりあえず色々試してみることにします
gets以外なら大体¥nもコピーする。fgets、fgetln、テキスト指向ですらないfreadも勿論。というかgetsは絶対使わない方が良い。 C++は…誰かお願い。
C++でWindowsでのDLL作成に関して質問です。 C++のクラスをエクスポートする場合、純粋仮想クラスを利用するようですが、この際、 多重継承は可能なのでしょうか。具体的には以下のようなことをしたいのです。 class IFoo{ public: virtual void fooFunc() = 0; }; class IBar: public IFoo{ public: virtual void barFunc() = 0; } class CFooFunc{ public: virtual void fooFunc(){ /*...*/ } }; class CBarFunc{ public: virtual void barFunc(){ /*...*/ } }; class CExport: public IBar, CFooFunc, CBarFunc{ }; __declspec(dllexport) IBar* createIBar(){ return new CExport(); } __declspec(dllexport) IBar* deleteIBar( IBar* p ){ delete p; }
>>511 istream& istream::get(char& c)
istreambuf_iterator
unsetf ios::skipws and istream_iterator
>>516 DLL でクラスを公開したいなら COM
COM なんて使いにくいもんじゃなくて __declspec(dllexport) と __declspec(dllimport) を使おうぜ。 DLL と EXE で自動的に切り替えるマクロもあったけど忘れた。
C++の初心者向けサイトを教えてください
#ifdef PROJECTNAME_EXPORTS # define DLL_EXPORT __declspec(dllexport) #else # define DLL_EXPORT __declspec(dllimport) #endif
そういうやつ、自分で作らなくてもあったと思うけど、 自分で作った方が細かい制御ができていいかもしれん。
dllexportは所詮同じヴァージョンのコンパイラ相手でしか使えないからね。
しかし、COM は COM で色々と不便だからなあ・・・。 IA ← A の機能強化版として IB と B を別途作るとして、 IA ↑ ↑ IB A ↑ ↑ B こういう継承したいけど無理っしょ? 仮想継承がないから・・・。
ATLみたいに実装をテンプレートに分離すれば解決しない?
wchar_t(unsigned char) に入ったUTF16の日本語を ShiftJISに変換してxharに突っ込む処理を STLだけで書くにはどう書けばいいですか?
>>525 テンプレートは解決策の1つだとは思うけど、
ヘッダファイルに実装するのはどうもね・・・。
コードいじったときのコンパイル範囲が広くなると困るし。
OSに頼ったほうが安全
>>524 そのIAをIUnknown、Aを適当なインタフェースに置き換えれば、そんな例は山ほどある。
Aの実装をソースコードの形で手に入れられるなら、
普通にIBとAを多重継承して、細かいところを整えればいける。
>>530 要は、本来Bでオーバーライドする必要のない関数も、B内から手動でAの実装を呼ぶようにすればいい。
インタフェースはメンバ変数ないから、キャスト関係くらいしか仮想継承の有無の違いはないといっても過言ではない。
struct IA : IUnknown {virtual HRESULT STDMETHODCALLTYPE FnA() = 0;};
struct A : IA {
virtual HRESULT STDMETHODCALLTYPE QueryInterface(IID&, void**) {/*実装*/}
virtual ULONG STDMETHODCALLTYPE AddRef() {/*実装*/}
virtual ULONG STDMETHODCALLTYPE Release() {/*実装*/}
virtual HRESULT STDMETHODCALLTYPE FnA() {/*実装*/}
};
struct IB : IA {virtual HRESULT STDMETHODCALLTYPE FnB() = 0;};
struct B : A, IB {
virtual HRESULT STDMETHODCALLTYPE QueryInterface(IID&, void**);
virtual ULONG STDMETHODCALLTYPE AddRef() {return A::AddRef();}
virtual ULONG STDMETHODCALLTYPE Release() {return A::Release();}
virtual HRESULT STDMETHODCALLTYPE FnA() {return A::FnA();} //オーバーライドしない気なら
virtual HRESULT STDMETHODCALLTYPE FnB() {/*実装*/}
};
HRESULT STDMETHODCALLTYPE B::QueryInterface(IID& riid, void** ppv) {
if (ppv == 0) {
return E_POINTER;
} else if (riid == IID_B) {
*ppv = static_cast<IB*>(this);
AddRef(); //直接A::AddRef()でも可
return S_OK;
} else {
return A::QueryInterface(riid, ppv);
}
}
Javaのインタフェースの仕様だとBでのAddRef以下のようなことを書く必要がなかった気がする、ちょっとうらやましい。
委譲するわけですか。 うーん。委譲のコストが少し気になってしまいますね。 そんなもんなんでしょうか。
534 :
デフォルトの名無しさん :2008/01/28(月) 13:31:23
自分クラスに大小比較の演算子を定義して、<=を使おうと思ったら、 <と==の2つを定義するのではなく、<=を定義しないとだめだったのですが、 そういうものなのですか?
そういうものです。 そもそも、'<='が「小なりイコール」であると言う意味から再定義するわけですから。
>>534 つ[boost::operators]
>>534 以下は違う関数だからねえ
operator<()
operator=()
operator<=()
<=を使うということはoperator<=()をコールするわけで。
538 :
デフォルトの名無しさん :2008/01/28(月) 16:23:28
>>535-537 ありがとうございます。じゃあ自分クラスについては、なるべく「<=」は使わずに
<と==でなんとかするようにします。
boost::operatorsは、<と==をconst関数で定義して、publicでboost::operatorsを
継承すれば動きました。かなり便利そう。
ありがとうございました。
539 :
デフォルトの名無しさん :2008/01/28(月) 18:45:01
typedef struct { .... } hoge_struct; #define TARGET_STRUCT hoge_struct #define TARGET_STRUCT_STR ???????????? printf("type: %s\n", TARGET_STRUCT_STR ); printf("size: %d\n", sizeof(TARGET_STRUCT) ); 表示 type: hoge_struct size: 40 TARGET_STRUCTにあるhoge_struct部分は、任意の構造体名です。(色々変化します) TARGET_STRUCT_STRが "hoge_struct" に(文字列)なるようにしたいのですが、 どんなマクロにすればいいのでしょうか?
言葉足らずでした。 型名であるTARGET_STRUCTを元に、文字列なTARGET_STRUCT_STRを作りたいという意味です。
# TARGET_STRUCT
>>538 なんとかするとかじゃなくて「<」と「==」から「<=」を作ればいいじゃんか。
「<」と「==」が定義されてるならば「<=」は↓のようになる。
return A < B || A == B;
boost::operatorsは内部でそういうことをやってるだけ。
よろしくお願いします。 項書き換えを行うシステムを作るにあたって、今式の構造を木構造で表すことを考えています。 式は中値記法で書かれているので、基本的には一般的な構文木のように作ろうと思っています。 具体的には、ある内部ノードには演算子を格納し、その左と右の子供に項を格納するような2分木です。 2項演算を表現するのにはこれで十分なのですが、 (X, Y, Z) のような三つ組みも表現しなければならないのです。 子供を3つ持つような木を作って、三つ組みを表現するときだけ3つ目の子供に項を格納すれば表現は可能になるのですが、 頻繁に三つ組みが現れるわけではないので、余分な子供はあまり持たせたくないと思っています。 2分木で三つ組みを表現するうまい方法はないでしょうか。
演算子 A を考える場合に A1 ∧ X A2 ∧ Y Z みたいにすればいいんじゃない?
単項演算子で無駄なノードが発生するのは別に構わんのん?
各ノードはふたつのポインタをもち、 それぞれは、 ・自分の子供のひとつ(長男) ・自分のすぐ下の弟 を指すようにすれば2分木でいくらでも子供を持てる。 これは木構造を作るのに定番の方法なので覚えておくといいよ。
Visual Studio 2005なんですが、vector型の変数で名前をarrayにしたら、変数名が青くなってました。 intみたいに予約語なのかなとも思ったんだけど、特に問題なく動くんですが、青くなるのはなんでなんでしょう?
>>548 arrayはCLR配列の予約語だからじゃない?
>>549 即レスありがとうございます!
ほうほう、CLR配列で調べると確かに予約語っぽいですね。でも問題なしと考えてよいんでしょうか。
ついでにうかがいたいんですが、ちょい前までVC++6.0でつくっていたソースコードがあって、関数の引数にbool型をつかっていました。
そのソースを2005でダイアログベースで作っているプロジェクトで利用しようと思ったんですが、チェックボックスのValueがBOOL型になってまして、そのまま関数の引数にぶち込むと、次のように怒られました。
>warning C4800: 'BOOL' : ブール値を 'true' または 'false' に強制的に設定します (警告の処理)
これはどうすればよいんでしょう?
BOOL変数?true:false とか。BOOLってintだからなー。 TRUE/FALSEの代わりに「エラー値」が入ってたりするし。
>>551 うわぁお!!
すげー、通りました、感動しています。
しかし6.0から2005にするといろいろ戸惑いますね。作業効率が半分くらいになった感じです。
553 :
デフォルトの名無しさん :2008/01/28(月) 23:37:08
>>545 そうですね、こちらでも考えましたが、このような木の構造にするしかなさそうですね。
>>547 アドバイス有り難うございます。
処理系を作るときに、こういう形で構文木を作るとネストされたリストも簡単に表現できるということで、
勉強したことがありました。確かに自分もよく使います。
お二方、どうも有り難うございました。
>>552 6.0から2005だと色々変えないといけないところが出てくるだろうな。
new 失敗した時デフォで NULL 返すような古いコンパイラだからなあ。
まあ、変更が終われば大した違いはなくなると思うぜ。
555 :
デフォルトの名無しさん :2008/01/29(火) 00:46:03
LONG a=適当; LONG b=適当; LONG c=適当; if(a*a + b*b > c*c) { } とした時に、 a*a等がLONGに収まる範囲を超えてしまったら、 どうなるのでしょうか?
>>555 LONGがlongのtypedefなら未定義
STLでウィンドウへ作ったり絵を描くクラスはどこにありますか?
ありません gilを使ってください
559 :
555 :2008/01/29(火) 01:32:29
>>556 Win32APIを使ったプログラムで、
LONGは<windows.h>に定義されているモノです。たぶん。
未定義というのは、どうなるか分からないということですか。
世界ランク14位おめw
http://2chcity.myminicity.com/ ランク 国名 街 人口 (前日比) 前日
--- 1 US1 LUELand 326354 (+211) 326143
--- 2 US2 GoonTown 179482 (+711) .178771
--- 3 Germany1 .isnichwahr.de 119091 (-654) 119745
--- 4 US3 CreateMyCity Forum .87380 (+1982) 85398
--- 5 Poland1 #debian.pl 79594 (+1043) .78551
--- 6 Germany2 upOTia 52443 (+399) 52044
--- 7 France1 Reze'Les Nantes .41960 (+246) 41714
--- 8 Canada1 J-C Satanas & CO .40995 (+721) 40274
--- 9 US4 retromundi .40604 (+788) 39816
--- 10 France2 FanaZ .39902 .(+1268) 38634
2↑ 11 Germany3 deluxebits 38770 .(+3199) 35571
1↓ 12 US5 .isnichwahr.at .38234 (+78) 38143
1↓ 13 France3 gravure-news .37204 .(+765) 36439
2↑ 14 Japan1 2ch_city 35637 .(+1970) 33667
1↓ 15 Spain1 Media-Vida .35205 .(+686) 34519
1↓ 16 France4 Sguy .35083 .(+1456) 33626
2↓ 17 Ireland1 .prapikilty .35067 .(+871) 34196
--- 18 Spain2 benidaver .34505 .(+914) 33591
--- 19 Germany4 directupload ..32490 .(+82) .32408
-↑ 20 Slovakia1 Legionar City 32056
562 :
デフォルトの名無しさん :2008/01/29(火) 05:15:49
doubleとintの丸め誤差について質問しているものです。 SSE2命令で計算するとどうして3.55*100が355になるのか、どうしてもわかりません。 IEEEの仕様どおりの浮動小数点の計算方法だと、レジスタのサイズが52でも80でも128でも doubleの3.55は実際には2.54999999...となってしまうと思うのですが、、、 gccでSSE2命令を有効にして作成したバイナリの逆アセンブルの結果をみると、 <元ソース> int main(void) { double d = 3.55; int n = d * 100; printf("%d", n); } <続く>
563 :
デフォルトの名無しさん :2008/01/29(火) 05:17:36
<続き> <main関数の逆アセンブル結果> 80483c4: 8d 4c 24 04 lea 0x4(%esp),%ecx 80483c8: 83 e4 f0 and $0xfffffff0,%esp 80483cb: ff 71 fc pushl -0x4(%ecx) 80483ce: 55 push %ebp 80483cf: 89 e5 mov %esp,%ebp 80483d1: 51 push %ecx 80483d2: 83 ec 24 sub $0x24,%esp 80483d5: dd 05 d8 84 04 08 fldl 0x80484d8 80483db: dd 5d e8 fstpl -0x18(%ebp) 80483de: dd 45 e8 fldl -0x18(%ebp) 80483e1: dd 05 e0 84 04 08 fldl 0x80484e0 80483e7: de c9 fmulp %st,%st(1) 80483e9: dd 5d e0 fstpl -0x20(%ebp) 80483ec: f2 0f 2c 45 e0 cvttsd2si -0x20(%ebp),%eax <以下はprintfを呼んでいるだけと思うので略> をみてもなんでこうなるのか全然わかりません。 cvttsd2siの命令が、「64ビット倍精度実数を整数値に変換して汎用レジスタに コピーします。」という内容らしいので、この動作がキモと思うのですが、これは 中でどういう動作をしてるのだろう。誰かご存知ありせんか? 長々とすいませんどうかよろしくお願いします。
When a conversion is inexact, a truncated (round toward zero) result is returned. と書いてあるから3.54になるはずなのに変だねえ。
>>563 逆アスじゃなく、gccのアセンブリ出力を載せてくれ。0x080484d8なんてアドレス書かれてもなんだか判らん。
566 :
デフォルトの名無しさん :2008/01/29(火) 09:06:52
>>565 すいません。Cのコードは先のものと同じです。
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
fldl .LC0
fstpl -24(%ebp)
fldl -24(%ebp)
fldl .LC1
fmulp %st, %st(1)
fstpl -32(%ebp)
cvttsd2si -32(%ebp), %eax
movl %eax, -12(%ebp)
movl -12(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC2, (%esp)
call printf
<以下略>
だから、どうして.LC0とか.LC1の定義も省略するのかなぁ……
>>563 > cvttsd2siの命令が、「64ビット倍精度実数を整数値に変換して汎用レジスタに
> コピーします。」という内容らしいので、この動作がキモと思うのですが、これは
> 中でどういう動作をしてるのだろう。誰かご存知ありせんか?
ここまでくるとCPUアーキテクチャマニュアル見ないとわからん。
Intelのサイトにあると思うが、日本語であるかどうかわからん。
CVTTSD2SI--Convert with Truncation Scalar Double-Precision Floating-Point Value to Signed Doubleword Integer F2 0F 2C /r xmm/m64 切り捨てを使用して、xmm/m64の 1 つの倍精度浮動小数点値を r32 の 1 つの符号付きダブルワード整数に変換する。 説明 ソース・オペランド(第 2 オペランド)の 1 つの倍精度浮動小数点値を、デスティネーション・ オペランド(第 1 オペランド)の 1 つの符号付きダブルワード整数に変換する。ソース・オペ ランドは、XMM レジスタまたは 64ビットのメモリ・ロケーションである。デスティネーショ ン・オペランドは汎用レジスタである。ソース・オペランドが XMM レジスタの場合は、倍精 度浮動小数点値はレジスタの下位クワッドワードに置かれる。 変換が不正確な場合は、切り捨てられた(ゼロに丸められる)結果が返される。変換の結果が 符号付きダブルワード整数の最大値より大きくなる場合は、整数不定値(80000000H)が返さ れる。
570 :
デフォルトの名無しさん :2008/01/29(火) 12:08:40
本当にありがとうございます。 自分もマニュアル見てみました。 結局動作としては、 1)3.55を80bitのレジスタ上で表現する。レジスタ上では3.55よりもわずかに小さい数として存在 2)fmulp命令を使って、1)の結果と100の積を計算する。 3)上の2)の結果をcvttsd2si命令を使ってint型に変換 になると。 >変換が不正確な場合は、切り捨てられた(ゼロに丸められる)結果が返される。 354.99999..からintへの変換はどう考えても「変換が不正確な場合は、」に該当すると思うのですが、 切り捨てると、354になると思うんですが、、、
571 :
デフォルトの名無しさん :2008/01/29(火) 12:54:22
何度もすいません。 -msse2付きでコンパイルしても、不正確になってしまうケースがありました。 int main(void) { double d = 32.55; int n = d * 100; printf("%d\n", n); return 0; } あとは、512.55, 513.55とか、8192.55, 8193.55とか。(これ以外にもかなり多い) SSE2を使ったところで完全ではないようだし、なんだか不毛な感じもしてきた。 3.55については、たまたまSSE2で上手く計算できたケース、ということかな、と。
>>571 >567
手元の多桁演算処理に喰わせてみようと思うのだが……
私の所でOptimization(最適化)レベルを切り替えて実験してみた所 -O0で354、-O1で355になりました。 コンパイラはg++3.4.5です。 ソースコードをのぞいてみると、-O0は律儀に計算していましたが、 -O1の方はいきなり定数355をロードして終了していました。
.file "IEEE1.c" .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC2: .ascii "%d\12\0" LC3: .ascii "pause\0" .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $16, %eax call __alloca call ___main movl $355, 4(%esp) ←これ movl $LC2, (%esp) call _printf movl $LC3, (%esp) call _system movl $0, %eax leave ret .def _system; .scl 2; .type 32; .endef .def _printf; .scl 2; .type 32; .endef
575 :
デフォルトの名無しさん :2008/01/29(火) 20:52:37
std::vectorを使った場合で指定した添え字番号のオブジェクトを消す方法ってありますか?
vec.erase(vec.begin() + i);
C言語って1から覚えるとなると難しいでしょうか? プログラム関係の職(未経験可)どうしてもやってみたくて 就こうと思ってるんだけど理系学校出てないから無謀かな… スレ違いだったら凄くすいません…
まぁアレだ。プログラマ板で聞けばいいんじゃね
パソコンとインターネット環境持ってるなら、ただでプログラミングの 勉強できるから、やってみればいいんじゃないか。 難しいかどうかは、人によるからなんとも言えない。 また、理系かどうかは思ったより関係ない。 ただし、数字アレルギーとか英語まったく読む気ないですぅとか言うなら、 やめた方がいいと思う。
でも、ひでーアルゴリズムのコードを見ると、 理系ってのも大事だなあと思う。
>>578 プログラマ板か…、予備知識無くここにカキコんじゃったからな…
次からそっちで聞いてみます
>>579 まぁそうなんですよね…<どんな人も1から
それを承知で聞いてみたんで
>>580 色々サイト巡りして知識付けようとはしてます
数字アレルギーは全く無いけど、英語が学校成績で常に2付近だったから
それが不安材料でヤバイってのは承知済み…orz
今度からプログラマ板でも行ってカキコしてみます
レスどうもでしたm(__)m
プログラミング関係の英語ドキュメントなんて複雑な文法とか表現使ってないから学校の成績はほとんど関係ない
俺も数学と英語は毎回赤点だったが今では必要なだけは出来るようになったぞ。 まあ相性と経験次第。
>>581 理系でもひでー奴はいくらでもいる。
>>582 > 英語が学校成績で常に2付近だったから
>>580 をよく読んでくれ、英語ができないんじゃなくて、
「英語をまったく読む気がない」ならって書いてあるだろ。
君が必要に迫られたら何とかするタイプなら、心配はない。
>>583-584 が言うように、そんなに高レベルの英語が出て
くるわけじゃないし、しかもラッキーなことにここ数年で
機械翻訳がそれなりに進化して、技術文書ならなんとなく
意味が理解できるぐらいなってきたから、あまり心配しな
くても大丈夫だよ。
586 :
デフォルトの名無しさん :2008/01/29(火) 23:44:45
質問させてください。以下のソースをコンパイルしたところ、エラーが吐かれたのですが、その理由が良く分かりません。 #include <fstream> #include <TCHAR.h> #include <string> #include <sstream> using namespace std; class zantei{ private: // 行動データ構造体 class Action { public: int No; // 行動番号 (無しなら0) LPTSTR Type; // 行動種類 (無しなら0) LPTSTR Detail; // 行動詳細 (無しなら0) int Damage; // ダメージ(無しなら100) LPTSTR Color; // 色 (無しなら0) int X; // マルチプレイ用の遠距離行動(無しなら0) }; Action action[32]; public: BOOL LoadAction(); };
587 :
デフォルトの名無しさん :2008/01/29(火) 23:45:15
エラー: ・error C2146: 構文エラー : ';' が、識別子 'Type' の前に必要です。 ・以下、変数Typeが認識されないためと思われるエラー他たくさん(24個) 全角スペースや、Typeが実は予約語だったんじゃないかとも疑いましたが、 空白はすべて半角スペースとタブ入力でしたし、TypeをiやNumに変えても同じエラーが出ました。 …ということは、完全に知らないことか、思い至っていないことによるエラーだと思われる、ということまでは考えることはできました。 どなたかご教授いただけないでしょうか。
ほほう 何というコンパイラで、何というメッセージが吐かれたのだい?
コンパイラは、Visual Studio 2005 Academic Editionです。
エラーは、
>>587 以外もかくとすると…、ちょっと多いので、少々お待ちください。
このエラーだと、通常は Type の直前にある物がおかしいんだが、 tchar.h はインクルードしてあるしな・・・。 TCHAR が大文字でも何か起きると思えないし。
もしかすると、 #include <windows.h> が無かったりだったりとか?
エラー 2 error C2146: 構文エラー : ';' が、識別子 'Type' の前に必要です。 エラー 3 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません エラー 4 error C4430: 型指定子がありません - int と仮定しました。 エラー 5 error C2146: 構文エラー : ';' が、識別子 'Detail' の前に必要です。 エラー 6 error C4430: 型指定子がありません - int と仮定しました。 エラー 7 error C4430: 型指定子がありません - int と仮定しました。 エラー 8 error C2146: 構文エラー : ';' が、識別子 'Color' の前に必要です。 エラー 9 error C4430: 型指定子がありません - int と仮定しました。 エラー 10 error C4430: 型指定子がありません - int と仮定しました。 エラー 11 error C2146: 構文エラー : ';' が、識別子 'LoadAction' の前に必要です。 エラー 12 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません エラー 13 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません 警告 14 warning C4183: 'LoadAction': 戻り値の型がありません。'int' を返すメンバ関数とみなします。 これよりしたのエラーは、LoadAction()の実装部分で吐かれているエラーです。
>>594 全角入りのソースでそれと同じエラーを見たぞ。
全角はチェックしてるって書いてあるだろw
まず、LPTSTR を char* にしてコンパイルは通るか? それをチェックしてみようぜ。
うーん、それじゃ、ちょっとソースをあっぷしてみますね 全角半角スペースを表示させても全角はは行っているようにみえないですが… 見落としかもしれないですし
あ、いや、wchar_t* か。
マルチバイト文字セットに変えてchar*型、一応w_char*型にしてみても、 同じエラーが吐かれました(確認したのは大体のエラーの見た目と数だけですが) ソースをアップする作業に入りますね
w_char じゃなくて wchar_t だぜ
お待たせしました。
http://www.youlost.mine.nu/html999/upload.php の、2968.zipです。
うp用に、配置しなおしたら、エラーが増えて涙目になってました(汗
他のアプリケーション用に書いてたものを、エラーはかれていたソースファイルを別プロジェクトでテストしながらなおそうとしたため、
プロジェクト別フォルダから読み込む方式になっています。
ヘッダがプロジェクトに入っていないのは、…えー、ごめんなさい、忘れました、試行錯誤の過程です。
いずれヘッダも戻すつもりではいました。
…ごめんなさい。
zantei の最後にセミコロンがない。
game.h の方のやつね。
607 :
デフォルトの名無しさん :2008/01/30(水) 00:31:11
「最大50文字で自然数を2つ入力し、その大小を求めるプログラムを作成せよ」 って問題なんですが、プログラム作ってみたけどわかりません 文字数が同じときの結果がめちゃくちゃになりました 誰かこのおしえてください(><) cout << "文字数a:" << a_count << endl ; cout << "文字数b:" << b_count << endl ; if(a_count > b_count){ cout << "a>b" << endl ; }else if(a_count < b_count){ cout << "a<b" << endl ; }else if(a_count == b_count){ cout << "文字数が一緒なので一桁ずつ判断します" << endl ; for(int i=0 ; i < a_count ; i++){ if(a[a_count-i] == b[a_count-i]){ cout << a[a_count-i] << "=" << b[a_count-i] << endl ; }else if(a[Max_Length-i] != b[Max_Length-i]){ break ; } } if(a[a_count-i] > b[a_count-i]){ cout << "a>b" << endl ; }else if(a[a_count-i] < b[a_count-i]){ cout << "a<b" << endl ; } } }
a[a_count-i-1]
(><)
610 :
607 :2008/01/30(水) 00:34:08
#include <iostream.h> #include <iomanip.h> const int Max_Length = 50 ; // 入力できる文字数の最大値 main() { char a[Max_Length] ; // 最初に入力する文字列 char b[Max_Length] ; // あとに入力する文字列 cout << "2つの自然数(最大50桁)を入力し、" << endl ; cout << "その2数の大小を判定するプログラムです" << endl ; cout << "数値を入力してください(最大50桁)" << endl ; cout << "a>>" ; cin.getline( a , Max_Length ) ; cout << "b>>" ; cin.getline( b , Max_Length ) ; int a_count , b_count ; // 文字カウンタ int i , j ; a_count = 0 ; b_count = 0 ; i = 0 ; j = 0 ; // 文字数をカウントする while(a[i] != '\n' && a[i] != '\0'){ a_count++ ; i++ ; } while(b[j] != '\n' && b[j] != '\0'){ b_count++ ; j++ ; }
iostreamマジ見にくい
612 :
607 :2008/01/30(水) 00:35:02
610が先で、607が続きです(><)
入力できる文字数の最大値が 50 なら、バッファは 51 以上必要だね。
std::lexical_compare使え
すみません、元からこんなに早くリアクションがくれると思っていなかったので、
質問してすぐ風呂に入る予定だったため、
アップロードしてしばらく返事がなかったので、急いでお風呂に入っていたため、反応が遅れました。
申し訳ありません。
>>605-606 ありがとうございます!
セミコロンを直し、game.hをプロジェクトを追加し、gamemain.cppにgame.hをインクルードし、
gamemain.cppのクラス宣言部分をコメントアウトしてコンパイルしましたが、
結局
error C2146: 構文エラー : ';' が、識別子 'Type' の前に必要です。
がヘッダで吐かれてしまっています…
ここの部分を改善する、考えられるミスはありませんでしょうか…
>>607 ヘッダファイルは <iostream.h> や <iomanip.h> ではなく
<iostream> や <iomanip> を使用する事が推奨されている。
cout とかが std::cout とかになっちゃうのが嫌なら、
この程度のプログラムなら using namespace std; と書いておけば std:: を略せる。
古いコンパイラなら知らんがね。
最大 50 文字なら、a のサイズは Max_Length + 1 にする。
cout の後 cin をする際には、cout を flush した方がいい。
cout << "a>>" << flush;
でないと、表示されない事もある。
getline は改行文字を格納しない。改行との比較は無駄。
50 文字以上入力したら次の cin.getline が失敗するのは無視してもいいのかな。宿題程度なら。
cin.clear(); して、改行まで読み飛ばすか構わず cin.getline するか・・・。
文字数カウントは strlen で可能だが、まだ習ってないのかな。
i と j という変数を作らなくても、直接 a_count と b_count 使えばいい。
while 文より for 文使った方がすっきりする。
i が 0 〜 a_count - 1 のループでは、
a_count - i は a_count 〜 1 になる。
これは意図する所ではないはず。
そして、a[Max_Length-i] != b[Max_Length-i] で何をやろうとしているのか分からないし、
このあたり全体的にちとおかしいと思う。
もうちょっとよく考えよう。
全角だろ。間違いない。全角なんだ。
>>615 風呂の予定なんかどうでもいい。
しかも二回も風呂って書きやがって。
風呂はゆっくり入れ。
インクルードガードがないのもすげー気になるが、 これだけのヘッダファイルだと BOOL は定義されてなくね?
#include <cstddef> #include <tchar.h>
622 :
デフォルトの名無しさん :2008/01/30(水) 00:55:17
>>616 たくさんありがとうございます!
考え直してもういっかい来ます
>>615 とりあえず windows.h をインクルードしとけ。
#include <iostream> int main(void) { const int max_str = 50 + 1; char str1[max_str], str2[max_str]; std::cout << "数値a入力>"; std::cin >> str1; std::cout << "数値b入力>"; std::cin >> str2; int len1, len2; for( len1 = 0; len1 < max_str; ++len1 ){ if( str1[len1] == '\0' ) break; } for( len2 = 0; len2 < max_str; ++len2 ){ if( str2[len2] == '\0' ) break; }
std::cout << "数値a 文字数:" << len1 << std::endl;
std::cout << "数値b 文字数:" << len2 << std::endl;
if( len1 == len2 ){
std::cout << "文字数が一緒なので一桁ずつ判断します" << std::endl;
for( int i = 0; i < max_str; ++i ){
if( str1[i] == str2[i] )
continue;
else if( str1[i] > str2[i] )
std::cout << "a > b" << std::endl;
else
std::cout << "a < b" << std::endl;
break;
}
}else if( len1 > len2 )
std::cout << "a > b" << std::endl;
else
std::cout << "a < b" << std::endl;
}
>>612 総書き直しすれば簡単
>>617 提案ありがとうございます。すみません、でもとおりませんでした
>>618 エディタでトリプルチェックしましたが、やはり全角はありませんでした…
>>619 う…(苦笑)。すみません、お気遣いありがとうです。
>>620 windows.hをインクルードすれば定義されるでしょうか?
>>621 これは、BOOLのヘッダでしょうか。すみません、レスを先にして、試してきます。
>>624 std::cin >> str1;
バッファオーバーフロー一直線!!!
>>621 試してみたら、エラーが13に減りました!
でも、
>>623 windos.hをインクルードしたら、もっと減りました(10)!
あとは、game.hに、using namespace std;をかけば、通りそうな雰囲気です。
ありがとうございました。
一応、最後に通るか確認してきますね。
>>629 ヘッダファイルで決して using しないと俺と約束してくれ。
>>630 ごめんなさい。
gamemain.cppの方でした。
そして、通りました!皆さん本当にありがとうございました。そして、お騒がせしました!
ちなみに、ヘッダファイルでusingすると、どんな弊害がおきるのでしょう?
ちょっと考えれば分かるかもしれない気はするので、失礼な質問でしたらすみません。
あと、<TCHAR.h>より、<tchar.h>をお勧めになった理由もお教えいただけないでしょうか?
本来 tchar.h という名前のファイルだから気になっただけ。 ヘッダで using して、色々インクルードしまくってると、 どこで using されているかさっぱり分からない状態になる。 using されては困る状況が現れた時、どの using が原因で困ってるか分からない。
触っちゃダメよと言われてるヘッダファイルで using されてると泣くしかない。
usingされているヘッダファイルをインクルードすると、 その名前空間がインクルードしたファイルにもusingされてしまう、ということでしょうか? それとも、usingされてると、呼び出すときに、どの名前空間に所属しているのが分かりにくくなり、 数が膨大になったときに、エラーからたどりにくくなる、ということでしょうか? …後者ですよね?
両方。
おあ、両方ですか。
前者も、ということになると、確かに本当にヘッダファイルでusingしてしまう(されてしまう)と、困ってしまいますね。
絶対にヘッダファイルでusingしないと、
>>630 さんと指きりしてお約束します。
ありがとうございました!
namespace isolate { // isolate using directives and declarations #include "hoge.h" // has using directives or declarations } using isolate::Hoge; // declared in hoge.h, and want to use in this source と無理矢理隔離してみたり。
なるほど
STLとATLではどちらを覚えたほうがいいですか?
STL: どの環境でも使える ATL: Windows でしか使えない
STL: 誰も使ってない ATL: 90%くらいの環境で使える
両方覚えろよ
Windowsでプログラミングするなら両方。 そうじゃないならSTL。
てゆーか二者択一するようなもんじゃないだろwwwww
関数内でnewでchar型の動的確保をしたいんだけど、他の全ての関数でもその宣言した char型のを使えるようにするにはどうすればいい?
ごめん文章が変だったので追記 要するに関数内でnewで宣言したcharをグローバル変数みたいな感じで使いたい
外部変数にchar*型のポインタ用意してそこに代入すれば?
>>648 ああそうか。それでいけたw
staticみたいなので全範囲で使えるようになるのないかなって探してたよ
ありがとう
C++で開発をする際、他言語以上にいつもクラス設計で悩まされます 何かそこらへんを専門的に取り扱ったおすすめの本はないでしょうか?
ATLにSTLのコンテナ使う仕掛けが合ったよな。
有った
653 :
デフォルトの名無しさん :2008/01/30(水) 15:30:11
C言語の質問です。コンパイラはgccです。 while(fgets(buffer,filesize,fp)){ flug=strstr(buffer,str); if(flug!=NULL)puts(flug); } これでなぜ出力文字列が検索できないのでしょうか。 教えてくださいませんか? 私の頭の中ではまず改行までのファイルの一行をbufferに読み込む。 その後、bufferに格納されている文字列とstr(検索したい文字列)を比較して検索。 その返り値がflugに入るので、NULLポインタ以外(失敗)のflugは出力。 これで検索した値からの文字列が出力されると思っておりました。
654 :
デフォルトの名無しさん :2008/01/30(水) 15:40:40
cin.getline って文字列を入力させるときに使うの? 普通に50桁の配列に数字を入れたいときって cin >> a[50] でいいのかな??
きもい
>>653 その部分だけじゃわからん。
つーか、その部分に問題は無い。
>>653 ・flugという変数名がキモい
・filesizeは本当にbufferが指すバッファのサイズ?
buffer, filesize, str の宣言や初期化などを詳しく開示しましょう。
658 :
デフォルトの名無しさん :2008/01/30(水) 17:03:00
>> 654 getlineの使い方(ファイルからの一行単位の読み込み) string line; ifstream ifs(filename); while (getline(ifs, line)) { lineには一行がはいってる。 } > cin >> a[50]; これでは配列aの51番目の要素に代入してるだけでは?
659 :
デフォルトの名無しさん :2008/01/30(水) 18:54:56
>>658 やっぱりだめなんですね・・
cin>>a[50]
だと50桁も入力できないんです
ありがとうございました
例外がcatch{}の中では生存していると仮定して 関数でnew | malloc した文字列を返して デストラクタでdelete[] | freeするのはありですか?
言っている意味が分からん。 コードで書いてくれ。
エスパーな俺が翻訳すると、 catch内で作ったインスタンスでもデストラクタは呼ばれるのか? ではないかと。
ふつうにわかるだろ
>>659 「桁」が何のことか分からん
配列のサイズのことならfor引数足してまわせばいいだけ
50桁の数値(10の50乗とか)を扱いたいなら普通には無理
引数じゃなかった添え字だ
自作クラス内に、CreateWindowというメソッドを作りたいんですが、エラーが出てしまいます。 エラーメッセージを見るとどこかで定義されてるようなんですが、 クラス内は独立した名前領域で、同じ関数名を使えるのではないのですか? どなたか、回答をお願いします。
>>667 windows.h から同名のマクロが include されているのかも知れない
回答ありがとうございます。 windows.hは確かにインクルードしていました。 windows.hをインクルードしないわけにはいかないし、 CreateWindowという名称を使うのはあきらめたほうがよさそうですね。
すみません、質問です. C++言語のソースを読んでいて、疑問に感じた所があります。 struct Hoge{ unsigned Wakeup(void) const { return wakeup_time; } Hoge(Container& container); ~Hoge(); private: unsigned int hoge_time; Container& fuga; }; これ構造体ですよね?クラスみたいですけど・・・。 本を読んだりしてクラスと構造体はまったく別物と認識していたんですが。 混乱しています。
C++では同じ 違いはデフォルトのアクセスがpublicな事
>>670 実装は同じだけど、考え方としては区別したほうが良いんじゃないかな、
メンバ変数を public にした方が何かと便利そうなのは構造体に、 そうでないのものはクラスに。 そう考えると、自然と構造体を使う状況は限定される。
>>673 デフォルトで public 継承になる、というやつのことか?
テンプレート絡み。
最近どこかで目にした流れだな
はい、STLスレの受け売りです。
だからテンプレート引数の話とここの話とは ちょっと違うんじゃないか、と。
680 :
670 :2008/01/30(水) 23:43:33
C++だと若干の違いはあるにせよ、classの代わりにstructと書くこともできるんですね。 ありがとうございました。
newで多次元配列分の確保ってできない? char *c; int p=20; c=new char[p][255]; こんな感じでしたいんだけどこれだとエラーでる
char (*c)[255] = new char[p][255];
>>682 ありがとうございます。原理はよく分からないけどできました
勉強してきます
配列へのポインタを使ってる。 typedef 使うと多少分かりやすいかと。 typedef char BUF[255]; // BUF は char 型 255 要素の配列型 BUF *c = new BUF[p]; やっぱそうでもないか。
つまり、char 型 255 要素の配列を p 個確保して、 c[i] とすると i 個目の配列が得られ、 c[i][j] とするとその配列の j 番目の要素にアクセスできる、と。
>>684-685 分かり易くありがとうございます。何となく分かったような気がする
とりあえずもう一度newについて再勉強してきます
newでもmallocでも同じだよ
688 :
デフォルトの名無しさん :2008/01/31(木) 04:56:35
template <int N, typename T> struct array_str { T array[N]; T &operator[](int n) { return array[n]; } }; int p = 20; const int ssize = 255; vector< array_str<ssize,char> > c(p); として、以下のように使う方法は? c[1][1];
>>688 使い方を示しながら使い方を聞く意味がわからん。
proxy classの話かな?
this->template func<type>(arg); という書き方を見たんですが、 this->func<type>(arg); との違いを教えてください。
>>691 template付けないとエラーでコンパイルできない場合がある。
.演算子、->演算子、::演算子の後ろにメンバテンプレート特殊化の
名前があり、それがテンプレート仮引数に属している場合がそう。
>>691 テンプレート内で、 this の型がテンプレート引数に依存するとき、前者のように
template を明示しないと、コンパイラは this->func<type という部分を
(this->func) < (type) のような比較式と認識してしまう。
"ab"でaとbの間に「"」を入れたい場合って「"a""b"」でおk?
\"
ありがとう。あぶなく間違って使うところだった
まぁやったところで別に問題はないけどね、表示されないだけで
確かになw エスケープを "" で表現するのって、どこの文化だっけ? どっかで見た気はするんだが。
昔のBASICだろ
だっけか。全然覚えてないや。
試しにVBでやってみたら通ったわ。""
演算子の優先度と結合規則がいまいちよく分かりません。 下の式を意味が変わらない範囲でカッコを外すとどうなりますか? a = ( b *= ( ( c+d ) << e ) ) ( ( * ( a[b] ) ) . c ) -> d ( a - ( ( b-c ) * d ) ) - e ( + ( ++a ) ) + ( ( b&c ) << ( d+e ) ) ( ( ( * ( a.b ) ) . c ) -> d ) ++ あと下の4つは順序を明確にするためにカッコを付ける問題です。 a + b * c - d a <<= b << c <= d a = b &= c ==d * a . b * c 参考になるサイトとかありますか?アドバイスお願いします。
参考になるのは優先順位表 高低だけじゃなくて、右左にも注意
テスト問題とか、与えられた式を最適化するようなプログラムを作っているのでなければ 素直にカッコをつけておくというのはどうだろうか。 前提無視ですね、すみません。
言語仕様とはちょっと違うけど今でもDB2のSQLは文字列中の"を""で表すぞ
ビット演算の優先順位をちゃんと把握してる人なんてそんないないわ。
>>703 優先順位がわかりにくいときは括弧つければいいと思うよ。別にかっこ悪くないと思うよ
括弧減らしてもバグが増えたら意味が無いしな。
VC++8使ってるんですけど、グローバルスコープの関数ってやっぱり ::CreateWindowEx とかスコープ演算子つけた方が良いのですか? ネットにあるサンプルコードだと、両方見かけますが…
711 :
デフォルトの名無しさん :2008/01/31(木) 21:42:54
boostを使わずにstringの文字列を小文字の文字列に変換するにはどうすればよいですか?
>>711 string str("HeLLo");
for (int i = 0; i < str.size(); i++) {
str[i] = tolower(str[i]);
}
cout << str.c_str() << endl;
あまりよろしくないかも。
std::transform(str.begin(), str.end(), str.begin(), tolower);
ざんねん、あなたのじっそうでは、tolowerは、「まくろ」だった
hoge.hで // 構造体 struct POI{ int n; float x; }; // クラス class hoge { public: hoge(void ); // コンストラクタ ~hoge( void ); // デストラクタ private: POI poi[4]; }; と書き、 hoge.cppの hogeコンストラクタ上で poiの初期化を行いたいのですがうまくいきません。 今下のようにやっているのですがどのように直せばいいのでしょうか、どうぞよろしくお願いします。 poi = { { 1 , 0.5 }, { 1 , 0.5 }, { 1 , 0.5 }, { 1 , 0.5 }, };
そ、そんな実装もあるのか・・・。
for(int i = 0; i < sizeof poi / sizeof *poi; ++i) { poi[i].n = 1; poi[i].x = 0.5; }
>>715 poi = {
{ 1 , 0.5 },
{ 1 , 0.5 },
{ 1 , 0.5 },
{ 1 , 0.5 },
};
その形式が使えるのは宣言時だけなので
>>717 みたいにしないといけません
720 :
715 :2008/01/31(木) 22:40:59
>>717 できれば
poi = {
{ 1 , 0.5 },
{ 1 , 0.5 },
{ 1 , 0.5 },
{ 1 , 0.5 },
};
こういう風に一括でやりたいのですがこれは無理なのでしょうか?
721 :
715 :2008/01/31(木) 22:42:07
>>719 すいません、見逃しました。
そうですか、わかりました。ご丁寧にありがとうございます。
>>720 POI poi_src[] = {
{ 1 , 0.5 },
{ 1 , 0.5 },
{ 1 , 0.5 },
{ 1 , 0.5 },
};
std::copy(poi_src, pos_src + sizeof poi_src / sizeof *pos_src, poi);
POI poi_src[sizeof poi / sizeof *pos] = { ... }; とサイズ指定してた方が安全か。
それでもC++0xなら、C++0xならなんとかしてくれる……
static const POI poi_src[sizeof poi / sizeof *pos] = { ... }; とした方がいいか。
726 :
デフォルトの名無しさん :2008/01/31(木) 23:06:46
>>713 ありがとうございます。でもコンパイル通りません。
下のソースだと、
char my_tolower(char s) {
return tolower(s);
}
int main() {
string s = "Hello world";
transform(s.begin(), s.end(), m.begin(), toupper); // コンパイル通らない
transform(s.begin(), s.end(), m.begin(), my_tolower); // コンパイル通る
下のような結果になります。
test.cpp:14: error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*,
std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >,
<unresolved overloaded function type>)'
何かオーバーロードされてるのか・・・
>>726 transform(s.begin(), s.end(), m.begin(), static_cast<int(*)(int)>toupper);
インクルードするヘッダによって違わなかったっけ
両方あるなら (tolower) でいいってことか
#undef tolowerじゃだめなの?
>>732 括弧無くても大丈夫だな。
後ろに ( ) がついてないから。
それにしても、うちの gcc じゃ
>>726 みたいなエラーでないんだがなあ。
バージョンが違うのか。
tolower(int)のほかに、tolower(char)とかtolower(wchar_t)とかあるんでしょ。
Cとの互換関数だから、規格的にオーバーロード出来ないと思うが。
なら static_cast<int(*)(int)>(tolower) とかしないといけないのか。 面倒臭いな。
<locale>かどこかに、第2引数にロカールをとるバージョンがあったと思う。
古いヘッダ .h なら通るんだよな 謎だ
>>730 Cでは、関数に加えてマクロを用意しても良かったが、
C++だとそれは認められていない。
(JIS X3014:2003では17.4.1.2の6段落目。更に注(159)で明確に指摘されている)
741 :
デフォルトの名無しさん :2008/02/01(金) 01:28:39
double pai(){ double i,imax,n; double x,y,pi; n=0.0; imax=10000000.0; for(i=0;i<=imax;i++) { x=rand()/(RAND_MAX+1.0); y=rand()/(RAND_MAX+1.0); if((x*x+y*y)<1.0) { n+=1.0; } } pi=n/imax*4.0; return pi; } double px(double t){ double pi=pai(); double x,ans; ans=exp(-x*x/2t)/sqrt(2*pi*t); return ans; } としたら エラー E2121 kadai1.c 27: 関数呼び出しに ) がない(関数 px ) と出ましたorz 誰か解決策わかるようでしたら教えてください(;´Д`)
exp(-x*x/2t)/sqrt(2*pi*t); 2t?
あとx初期化してないよね。
744 :
デフォルトの名無しさん :2008/02/01(金) 01:44:15
c++でswitch文のcaseの中では変数宣言できないですか
case HOGE: { int t = 0;} break; ブロックで囲めばいいんじゃね
746 :
741 :2008/02/01(金) 01:58:11
>742 解決しましたw あざす!!
747 :
デフォルトの名無しさん :2008/02/01(金) 03:31:40
空を自由に飛びたいな はーい つLSD
LoadLibraryでもらったHMODULEはCloseHandleで処分できますか?
750 :
デフォルトの名無しさん :2008/02/01(金) 19:24:52
どこで質問すればいいのかわからないほどくだらない質問なのですが、 よく引数であるchar* pszMessageのpszってどういう意味ですか? Pointer Stringはわかるんですが、Zがいったいなんなのか・・・
zはzero、szはヌル終端文字列のこと。
pointer string zero-terminated
753 :
749 :2008/02/01(金) 19:30:06
間違えました。
754 :
デフォルトの名無しさん :2008/02/01(金) 19:31:13
755 :
デフォルトの名無しさん :2008/02/01(金) 21:29:40
c++のプログラムを書いてます。 コンソールからstringを入力させたいのですが、getline()とcinを併用すると 何回目かのcinがユーザの入力待ちにならずにそのまま長さゼロの入力を受け取った と誤解して処理が先に進んでしまうようです。何かフラッシュとかの処理が必要なので しょうか?
エラーが発生したなら cin.clear(); するまで関数に失敗するが、 そういうわけではなくて?
Pointer to a String terminated by Zero
std::map<CString, CComPtr<ID3DXFont>> fonts; に問題はありますか?
エラーが出なければ問題は無い。 エラーが出るなら問題。
760 :
デフォルトの名無しさん :2008/02/02(土) 01:41:21
質問させてください. c言語でscanfで入力を受けるプログラムをつくりました. バッチファイルとかシェルスクリプトで入力してやりたいのですが、つまづいています. 要するに、 (実行ファイル)enter(入力)enter では無く、 (実行ファイル)(入力)enter のような感じに書く方法がありますか?ということです.
int argc, char* argv[] でググれ。
>>760 そのレベルは……ぐぐるとかじゃなくて、本を読んできちんとした知識を身に付けた方が良いよ。
いや、マジで……
>>758 STLのこんてなにオートポインタの類入れると
とりあえず>>だとコンパイルエラーになったりするので> >にしとけ。
765 :
デフォルトの名無しさん :2008/02/02(土) 02:37:31
760です.確かに知識は無いです. 実は数値計算だったので簡単に済ませたかったんです. リダイレクトでパラメータをいれる代わりに、 そのまま数値を書く方法があるのかなと思って質問してみたんですが. どうやら場違いでした.
ウィンドウつくったり図を表示したりするのってWin32API勉強しないとできない?
>763 std::aut_ptrが例外的にダメなオートポインタで、 大抵のスマートポインタは入れても大丈夫じゃねーの。
VC6 だが、std::vector に CComPtr 入れると resize でアサーションエラーが出た。
intrasive_ptr?だっけ? まさにCOMみたいに自前でカウントしてるクラス用のスマポ
770 :
デフォルトの名無しさん :2008/02/02(土) 12:46:10
string型の変数の中身をlistコンテナに一文字ずつ移そうとしてます。 for_each(string.begin(), string.end(), XXXX); みたいにfor_eachを使って書けないでしょうか?
push_backとmem_fun_ptr
mem_fun_refだったorz
これはだめ? std::list<char> l; std::copy(string.begin(), string.end(), std::back_inserter(l));
std::list<char> l(s.begin(), s.end()); または l.assign(s.begin(), s.end()); だろ。
775 :
デフォルトの名無しさん :2008/02/02(土) 15:35:03
for_each(s.begin(), s.end(), mem_fun_ref(v.push_back)); ということですか? でもこれはコンパイルできなかった。
v.push_backではなくて&std::list<char>::push_backだろ まあstd::back_inserterを使うのが最適なわけだが
最適は774だって。 EffectiveSTL嫁。
元の質問は for_each が使いたいらしいから、 >777 でも間違いではない。
>>777 それでもダメ。引数の数が一致しない。
せめてbind1stを使えといいたいところだが
ほとんどの実装でunary_functionで参照の参照が
発生してはじかれる。
ぶっちゃけ、メンバ関数をforeachみたいな連中に渡すのは 面倒くさいのでboost使おう、という話になるw
だからfor_each使わずに
>>774 でいいって。
784 :
784 :2008/02/02(土) 19:38:53
質問です。 //正規分布を求めるメソッド float BestFitInfo::norDis(float x, float mean, float var){ return 1 / ( sqrt( 2 * 3.14 ) * sqrt(var) ) * exp( - (x - mean) * ( x - mean ) / ( 2 * var ) ); } //BestFitInfoというクラスを作って、 //正規分布を求めるメソッドを書いたところ、 warning C4244: 'return' : 'double' から 'float' への変換です。データが失われる可能性があります。 と言われました。すべて引数は float だし、 exp や sqrt の戻り値もそれに合わせて float のはずなので、 どこで double 型が発生しているのかわかりません。 なぜこのようなエラーとなっているのでしょうか? 分かる方がいらっしゃいましたら教えてください。 よろしくお願いします。
>>784 >exp や sqrt の戻り値もそれに合わせて float のはずなので、
本当か?
floatのはsqrtfとかexpfじゃないのか?
あと、3.14はdouble型だ。float型リテラルは3.14fと書く。
786 :
784 :2008/02/02(土) 19:59:47
785さん、お返事ありがとうございます。 3.14fと書いたら「データが失われる可能性があります」と言われなくなりました。 sqrtについて調べたところ、 double sqrt( double x ); float sqrt( float x ); // C++ only long double sqrt( long double x ); // C++ only float sqrtf( float x ); このように sqrt は多重定義されているようです。 sqrtf はC言語のときの名残のようですね。 解決しました。みなさまありがとうございました。
質問です 僕はインクルードガードシンボルにuuidを含ませる事があるんですが Cのプリプロセッサで処理するシンボルは最大何文字までいけるんでしょう? #define HOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGEHOGE ぐらいのものは処理できるならまぁ十分なんですが気になります あと変数名や名前空間名も何文字までいけるか気になります ADLバリアを使うと結構文字数増えますし、 もしあまりに少ない文字数(例えば31文字)だったとしたら怖いんで
プリプロセッサの制限はわからんけど、 C89までは厳密には識別子は先頭6文字位じゃなかったっけ C99で32文字になったような気がしないでもない
プリプロセッサの制限はわからんけど、 内部識別子は最低32 外部が8くらいだったと思う。6かもしれん。 VC6なんかでは外部256とかで、複雑なtemplateとかで警告が出るね。
あ、これはC89ね
完全にうろ覚えだけど、マクロ名などの内部識別子は、 C89が31文字で、C99は63文字だったと思う。
792 :
791 :2008/02/02(土) 23:50:16
C++98ではCにはあったtranslation limitの既定がなくなって、長さに制限はないと明記されているね。 付録のBで内部外部ともに1024文字以上を推奨ってことになってる。(これは一応調べてきた
クラスあったら構造体いらないと思うんですが、構造体で宣言する利点って何ですか?
メッセージループ(DispatchMessage)に入る前にウィンドウプロシージャにメッセージが飛んでしかも処理されてるっぽいんですが 当たらしく作られた別スレッドで動いてるんですか?このウィンドウプロシージャってやつは
ある種のAPIは、直接プロシージャを呼び出して配送する。 有名なのは、UpdateWindowのWM_PAINTなど。
ほかにもWM_CREATEやそれより前にやってくるメッセージはCreateWindow(Ex)内部で呼ばれるし、 Send系で送る場合も同一スレッドなら直接呼ばれる。
>>795 ああ、なるほど、そういうことですか
そういうパターンをすっかり見落としてました
>>793 ただの構造体が欲しいときかな。
たとえば
APIにパラメータを渡したいとき。
ハードウェアをアクセスするとき
オフセットをがっちりあわせたいとき
>>793 しかしだね、
class Hoge { public: int id; double data; };
に対して
hogeInst.id = 1;
hogeInst.data = M_PI;
なんて操作をするのは背筋がぞわぞわしないか?
800 :
デフォルトの名無しさん :2008/02/03(日) 00:59:29
char* str = "aあいう" みたいに日本語とアルファベットが混在した文字列の、 文字数を数えるにはどうすればいいのでしょうか? strlen(str); とすると7になってしまいます。 環境はWindows XPでWin32APIを使ってプログラミングをしてます。
wchar_t* str = "aあいう"; wcslen(str);
L"aあいう"; だた
すいません、少し説明が足りませんでした。 そもそも何がやりたいかというと、 char*からwchar_t*への変換をしたいのですが、 char*変数のstrに'L'をつけて、L(str);とするとエラーになってしまいます。 そこで、MultiByteToWideCharで変換しようと思ったのですが、 wchar_t* wstr = new wchar_t[len]; というふうに、変換後文字のためのバッファをとろうとして、 その長さのlenをどう数えたらいいか分からなくなりました。
804 :
デフォルトの名無しさん :2008/02/03(日) 01:16:44
>>803 MultiByteToWideCharの仕様をMSDNで良く見直すこと。
とくに戻り値の説明を。
806 :
803 :2008/02/03(日) 01:25:33
>>804 ありがとうございます!
len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
これで長さがとれました。
ある関数の返り値を配列でほしいのですが 関数の返り値にvectorやらlistを返すのってありですか? それとも引数から参照渡しで変更させたほうがよいですか?
コストを気にしなければあり。
参照渡しで変更させたほうがいいなぁ。 要素数一桁だとか、RVOが可能な記述が出来るならともかく。 どうしても戻り値がいい場合はshared_ptrで包む。
バイナリでのファイル入出力って普通のと何がちがうの? バイナリ形式で保存したのをメモ帳で開いても普通に出力したのと変らないんだけど
>>799 C++ にもプロパティがあればいいんだけどね。
拡張機能で用意されてる事もあるが。
>>807 配列の先頭アドレスを返す、じゃダメなのかな
>>810 普通のっていうのはテキストモードのことだよね
テキストモードだと改行文字をいじったりしてる
詳しく知りたい場合は「fopen テキストモード」とかでググれば出てくると思う
C++の参照渡しって、結局中ではアドレスが渡されてるんですか? そうじゃないとしたら一体どうなってるんでしょうか?
結局中ではアドレスが渡されてる実装しかないだろうな。
>>812 ありがとうございます
「 ソε2:ホSSカ「8蟹Mタラ男ユムゥtn鶏」みたいな文字化けしたような感じで
書き込まれるのかと思ってたけど違うのね
こんな文字化けしたようなdatファイルとかってどうやって作ってるの?
文字以外を書き込めばなりやすいな
>>815 書きたい内容をそのまま書けばいい。
static const unsigned char data[] = {
0xBF, 0x83, 0xC3, 0x32, 0x3A, 0xCE, 0x53, 0x53,
0xB6, 0xA2, 0x38, 0x8A, 0x49, 0x4D, 0xC0, 0xD7,
0x92, 0x6A, 0xD5, 0xD1, 0xA9, 0x74, 0x6E, 0x8C,
0x7B}; // 「 ソε2:ホSSカ「8蟹Mタラ男ユムゥtn鶏」
FILE* fp = fopen("test.dat", "wb");
fwrite(data, 1, sizeof(data), fp);
fclose(fp);
そのデータだと FILE* fp = fopen("test.dat", "w"); fwrite(data, 1, sizeof(data), fp); fclose(fp); でも同じ物が書き込まれるがね。 バイナリモードとテキストモードの違いは メモリ上で 0x0D('\n') となるバイトを ファイル上でその環境の改行コードに変換するか否かしかない。
>>817-818 ありがとう。でも全然分からない
おれにはまだ早かったみたいです
とりあえずテキストとバイナリモードの違いは\nとかが違うだけで文字は変わら
ないんですね
勉強してきます
820 :
デフォルトの名無しさん :2008/02/03(日) 09:13:33
>>811 なければ自分で作ればいいじゃん。
俺は処理系非依存のプロパティ変数クラスを作った。
>>819 結果はメモ帳で見るよりバイナリエディタで見た方が分かりやすいかと思う。
何かバイナリモードとテキストモードでもの凄く違うと考えてるみたいだが、
動作的には大した違いはない。
普通は fprintf はテキストモードで、fwrite はバイナリモードで使うが、
別にそう使わないといけないという決まりはないんで、
バイナリモードとテキストモードで同じ物を書き込んで
それぞれどうなるか実験してみればいい。
>>820 プロパティリストではなくて、delphiのプロパティ宣言みたいなものが作れるの?
824 :
デフォルトの名無しさん :2008/02/03(日) 12:57:16
複数のソースで使うヘッダファイルの変数や関数が、 多重に宣言されないように、externの宣言がありますが、 ヘッダファイルに↓みたいな多重インクルードガードをつけたときも、 externは必要なのでしょうか? #ifndef AAA_H #define AAA_H //ヘッダの内容 #endif
extern はリンク時の多重宣言を回避するための物。 インクルードガードはコンパイル時の多重宣言を回避するための物。 全く別の物。
827 :
824 :2008/02/03(日) 13:32:45
>>825 >>826 ありがとうございます。
今は、複数ソースで共有する変数/関数にはextern、
全ヘッダにとりあえずインクルードガードをつけてます。
違いがよくわからず、不安なんですが、
こんなんでいいのでしょうか?
ちなみに、関数の方はexternをつけなくても動きました。
関数はデフォルトでextern
コンパイルとリンクの違いを調べるといいよ
830 :
デフォルトの名無しさん :2008/02/03(日) 13:51:38
c++で、int [] hoge(適当な引数) みたいに、配列を返す関数って定義できますか? 上記はできなかったので、結局int []を持つstructを定義して、それを返すように したのですが、、
普通は効率を考えて配列を渡してそこに書き込むようにする。
832 :
824 :2008/02/03(日) 13:54:51
>>828 そうなのですか。一つ大きな疑問が解決しました。
ありがとうございます。
>>829 勉強してみます。
>>827 関数でも、関数定義を複数書けばエラーになるよ。
エラーにならないのは関数定義は1つしか書いてなくて、
他は関数プロトタイプしか書いてないから。
>>825 うそん。
>extern はリンク時の多重宣言を回避するための物。
多重宣言どうこうっていうか、外部結合を明示するだけの物じゃないのか?
そもそもC言語って定義で無い宣言は複数回しても良いんじゃなかったっけ?
突っ込み入らないってことは俺が誤解してるんだろうか。
>>834 >そもそもC言語って定義で無い宣言は複数回しても良いんじゃなかったっけ?
そのとおりだよ。
extern指定子の無い宣言は仮の宣言。
コンパイル単位に定義が見つかったら、仮の宣言は冗長な定義として
無視される。そうでなければ0で初期化される単一の定義になる。
と思ってる。
C は仮定義があるから初期化しなけりゃ 複数の記憶クラス指定子のない変数宣言があっても大丈夫。 C++ は仮定義が廃止されたので 複数の記憶クラス指定子のない変数宣言があるとエラー。
837 :
デフォルトの名無しさん :2008/02/03(日) 14:40:39
gcc用で配布されているコードを, VisualStudio2005でコンパイルしたところ, エラー 1 error C2143: 構文エラー : '{' が ':' の前にありません。 c:\program files\microsoft visual studio 8\vc\include\cmath 18 エラー 2 error C2059: 構文エラー : ':' c:\program files\microsoft visual studio 8\vc\include\cmath 18 といった無数のエラーが出ました. ちなみにcmathはインクルードしておらず, #include<stdio.h> #include<stdlib.h> #include<math.h> #include<complex> だけです. どなたかアドバイス頂けませんでしょうか?
838 :
デフォルトの名無しさん :2008/02/03(日) 14:45:22
>>831 ありがとうございます。
参照渡しとかですね。
すいません、あと1つ質問させてください。
stringを継承して、[]をつかって[-1]と[サイズ+1]の要素にアクセスに行ったときだけ
動作の異なるクラスを定義できますか?自分でやろうとしたのですが、コンストラクタ
は継承されないから自分で定義しなおさないとダメなのですよね。そうすると、コンストラクタ
を書くのが結構大変なような気がしたので。
>>838 コンストラクタだけじゃなくて演算子だって定義する必要があるんだぜ。
戻り値の型が変わるから。
at 関数を使うと範囲チェックして out_of_range 例外投げるから
それ使えばいいんじゃね?
a.exe から LoadLibrary で b.dll を呼び出すんだけど、 b.dll から右側では .NET を使いたい。 a.exe → b.dll このような場合、b.dllをC++/CLIで作成することになるのかしらん?
841 :
デフォルトの名無しさん :2008/02/03(日) 14:54:13
>>839 なるほど、それでやってみます。
サンクス!
>>838 stringは仮想デストラクタを定義していないから
public継承するのはどうかと思うけど、コンストラクタ
の呼び出しに関しては、stringのコンストラクタ
を派生クラスのコンストラクタ初期設定リストで
指定すればいいだけじゃないの。
>>840 C#でもVB.NETでもお好きにどうぞ
845 :
840 :2008/02/03(日) 15:16:22
>>843 a.exeは他所で作ったものだから、漏れはいじれないんだ。
>>844 LoadLibraryでもマネージDLLを呼び出すことができるってこと?
>>808 >>809 >>812 返答ありがとうございます
色々とやり様があるみたいですが、c++的にはやはり生の配列を返すよりコンテナを返したほうがよいのでしょうか?
そうするとやはりlistを引数に取る関数に参照渡しが無難なのかなぁ・・・?
class Hoge1 { void hatena(void) { Hoge2 ht; ht.nazo(*this); } }; class Hoge2 { void nazo(const Hoge2 &rho){} }; みたいなのがあって ht.nazo(*this);のところでエラーになります。 どうす
>>847 nazo(const Hoge1・・・にす
&rho
>void nazo(const Hoge2 &rho){} nazoは引数にHoge2を取るようだが thisポインタってhoge1のアドレスを示してるんじゃないの?
851 :
837 :2008/02/03(日) 15:38:34
>>837 の質問はVC++スレに書き直しました.
マルチポストすいませんでした.
Hoge &rho
化けるのね。
854 :
デフォルトの名無しさん :2008/02/03(日) 15:42:31
hoge piyo fuga
&
&a
&rh
&abcd
&rho
860 :
デフォルトの名無しさん :2008/02/03(日) 18:14:16
なぜか、参考書どおりにコードを打ち込んだのに実行結果が違ってしまいます。 #include <stdio.h> int main(void) { int i, j, ln; printf("何段ですか:"); scanf("%d", &ln); for (i=1; i<=ln; i++); { for (j=1; j<=i; j++) putchar('*'); putchar('\n'); } return (0); } ちなみにOSはVistaです。どこか違っていたら教えてください。
for (i=1; i<=ln; i++); これ。 「;」という何の処理もしない文をforでループさせることになってる。
>>860 正解が何か知らんからわからんが
改行の位置がおかしいんじゃないか?
test
>>860 >参考書どおりにコードを打ち込んだのに実行結果が違ってしまいます
このスレを見ている人はその参考書のことなんてしらない。
どのような結果を求めているのかを提示しないと、どこが違っているのか答えられないよ。
明らかにおかしいコードだから答えは
>>861 の通りだろうけど、もうちょっと質問の仕方を考えたほうがいいよ。
866 :
デフォルトの名無しさん :2008/02/03(日) 18:26:15
861に書かれていることと その下の行の { が足りないことで たまたま{ }の対応がうまくいってコンパイルは通ってるんだな。 なので2ヶ所修正
868 :
デフォルトの名無しさん :2008/02/03(日) 18:26:51
C言語でのアルゴリズムの質問をさせて下さい。 現在以下のようなプログラムを作ろうと思っています。 0〜65535までの数字をIDとしてユーザに割当てる。 ユーザが割当てられたIDを使わなくなったときはそのIDを返却し、 返却されたIDは回収されて他のユーザに割当てられる。 最も簡単なやり方は、user_id[65536]などの大きな配列を作って、 使用状況を配列の中身の0か1で判断する、といったものかと思います。 しかしこのやり方よりもっと効率的なものはないでしょうか? このような大きな配列を作るのは実装としてまずいのかな…と感じています。 初心者で申し訳ありませんがアドバイスよろしくお願いします。
869 :
867 :2008/02/03(日) 18:27:59
あ、違った。 ごめん
とはいえ入門書で{}略すのはイクナイと思う。
>>868 64Kなら、オンメモリで処理してもいいんじゃね?
ビットで処理したら、8Kで収まる。
>>868 更に上限を増やさなければならない可能性があるなら、
別のやり方を考えたほうがいいと思うけど、
それぐらいなら問題ないと思うね。
>>868 その、配列やり方でいいと思うよ。
ランダムに返却され再利用されるならそれしかない。
>>871 のようにビットマップで配列は小さくできる。
連続の範囲でとりますとか特徴があれば、それを使って効率的に管理することもできる。
ある静的メンバ変数を含むクラスをテンプレート化しました。 この場合、静的メンバ変数は、テンプレート引数ごとに別々の実体が 作られるということで、このことは確認できました。 で、質問なのですが、この静的メンバ変数の初期化は、 いつ行われるのでしょうか? テンプレート化してない場合は、mainが始まる前ということで、 これは手元の本にも載っているのですが、 テンプレート化した場合、実際にどんなテンプレート引数で クラスが作られるかわからない段階で初期化ってできるのか、と 思ったものですから。 実際、mainの最初で、静的メンバ変数の値を見てみてみても、 なぜかちゃんと初期化した値が入っているように動きます。 なぜなのでしょうか。
コンパイル終わったときにはわかってるから。
テンプレートはビルド時に、 初期化コードも含めてすべて実体化されるだろ。
>>876 >>877 むむむ、そういうことですかーーー。
考えが至りませんでした。
ありがとうございました。
879 :
868 :2008/02/03(日) 18:56:06
>> 871,872,874 アドバイスありがとうございます。 特に問題がないようですので、このやり方で続行します!
C++だとbitsetでやるのが楽なんだろうけどな
それだとフリー探索がO(N)になるから、vector<unsigned short>(65536)という 手もよくあるパターンではある。
set<>は使えんの?
>>881 なんでunsigned shortなの?
intよりは節約できるし、IDは0〜65535なんだろ?
サンプルコード見ながら勉強してるのですが this->SizeGripStyle = System::Windows::Forms::SizeGripStyle::Hide; #pragma endregion private: の、->、::、#、:、の意味がよくわかりません 調べたいのですが、記号はGoogleで検索できないので、この記号の名称を教えてください
サンプルコードを見る域に達してないな
だから質問しているんです
それどころか勉強すら始まってないな
なんか本買えよ。 というか、そんな変態言語じゃなくて、普通のC++から勉強しろ
>>887 無料で見れる情報、無料で協力してくれる人だけをあてにして勉強する気?
独学で身につけるだけの基礎的な力をもっているならまだしも、
まったく何も持っていないなら勉強するための最低限の準備くらいはしたら?
>>885 何でも良いからCの入門書を読んでからにしようぜ
892 :
デフォルトの名無しさん :2008/02/03(日) 20:00:57
質問ていうか相談なんだけど TXTファイルの文字列置換ツール作たいんだけどさ 置換箇所だけ更新かけたいんだよ でもさ、fopenでファイル開くと一箇所変えると全部上書きしないといけないじゃん 置換箇所だけ更新かける方法ない?
C++/CLIの文法はアレだからなー。
一旦、別のファイルに書き出す。 その後、元ファイルを削除し、 さっき書き出したファイルの名前を元の名前に変える。
文字数変わらないなら、fseekとかfwriteあたりを駆使して 上書きすりゃいいじゃん。 ずれるのならご愁傷様。
>>892 ファイルの途中でサイズが増減しても、局所的な更新だけですむような
ファイルシステムを実装する。
>>874 > ランダムに返却され再利用されるならそれしかない。
そんなことはないだろ。
組み込み用途だと、8KB なんて言うテーブルなんてとんでもないと言う
こともあるだろうし、PC でも ID を 32bit にしたいとか言われたら、
どうするんだよ。(w
>>868 ID の範囲に比べて、同時使用ユーザ数が極端に少ないなら普通にリニア
サーチして管理することもできるし、同時使用ユーザ数がそれなりで
ID の割り当て・回収の処理コストが問題になるならハッシュとかBツリー
を使うこともできる。
stl::map<stl::string, Animal> animals; Animal &a = animals["cat"]; この時点で、aに入る物は出来ていますか?
stlの定義による。 stlがstdの間違いなら、aは正しく要素を指している。
>897 「何」を、リニアサーチするんだ?
>>897 また組み込み厨がでたよ。
特殊な環境を持ち出して、いちいち反論するヤツ。
>>897 ランダムに返却されれば、2^65536の組み合わせが発生する。それを記録処理するには65536bit必要になる。すなわち8Kバイトだ。
それ以下にするには、IDの消費が均一ではなく偏らせる必要がある。
たとえば、連続してIDを取得する。そういう特徴があれば、それに応じた処理にして節約すればいい。しかし、それはランダムとは言えない。
その次に「なら」ってかいてあるがな
>>884 いまさらだけど、配列の中身は0か1って書いてあるんだからshortは必要ないだろ
そこかしこのレスから揚げ足を取りたがってるオーラを感じるのは俺だけでいい
文章構成がアレだね。 前半は、「パターンがランダムでも、メモリ8KBも取る必要はない」って言ってて、 後半は、「パターンがランダムでなければ、節約する方法がある」みたいな。
えと、つまり、vectorのvがあるとして、 初期値として、(65535〜0)を入れとくわけね で、こうするとO(N)で触れる、ってだけの話。 要求(){ return v.pop_back() } 解放(id){ v.push_back( id ); }
それ O(N) じゃなくて O(1) だろ。 解放でデタラメな id 食わされたら死ぬとか言う問題もあるかもね。
あーそうそうO(1)だね。 でたらめなIDって言っても、if文一発で済むでしょう。 同じIDが複数解放されてきたららドナノヨって話は知らない。
>>908 大きな配列の変わりにvector使うのかと思ってたw
同じIDのチェックまでするならsetの方がよさそうだな
Cでbool型って使えたっけ?
>>902 もちろん、同時利用者数が最大 65536 と言うなら、ビットマップの方が
効率がいいのは自明だけど、
>>868 が「そんな大きな配列」とか書いて
るから同時利用者数はそれほどじゃないのかも知れないと思っただけの
こと。
同時利用がたとえば30なら、IDを65535も用意しとく必要無いじゃん。
>>890 いいえ違います
ほかの単語は検索すればわかる、だけど記号は検索できないから質問してるの
検索できない単語が他にも沢山あるならまた質問しまくるかもしれませんが
幸い、検索不可能な記号はこれだけのようなので質問しました
>>891 手持ちの入門書には「System::〜と書けばこう動く」という記述はあったが
「::は〜という意味です」という記述はなかった
>>915 もうちょっとまともな本を買うべきです。
入門書どころか入門サイトにも名前つきで紹介されている件について。
>>915 いいから、独習Cと独習C++あたりでも一通り読んできなさい。
つうか碌に参考書やサイト読み込んでないのバレバレじゃん
大漁大漁^^
今時釣り宣言とかwww
ファイル書き込みについての質問なんですが #include <stdio.h> typedef struct{ char no[6]; char name[21]; int tanka; }SHOHIN; void main(void) { int i; SHOHIN shohin[5]; FILE *fp; if((fp=fopen("shohin.txt","w"))!=NULL); { for(i=0;i<LEN;i++){ printf("商品番号、商品名、単価\n"); scanf("%s,%s,%d",shohin[i].no,shohin[i].name,&shohin[i].tanka); fprintf(fp,"%s",shohin[i].no); fprintf(fp,"%s",shohin[i].name); fprintf(fp,"%d\n",shohin[i].tanka); } fclose(fp); } return; } 文字化けが起きてうまくいきません 例えば a,a,1と入力すると a,a,11245072 となってしまいます 単純なミスだと思うのですがどうか教えてください! コンパイラはbcc55を使用しています
>>923 <scanf("%s,%s,%d",shohin[i].no,shohin[i].name,&shohin[i].tanka);
>scanf("%s,%s,%d",shohin[i].no,shohin[i].name,shohin[i].tanka);
こうするとどうだ
>>923 次の二行を削除(もしくはコメントアウト)してみな
fprintf(fp,"%s",shohin[i].name);
fprintf(fp,"%d\n",shohin[i].tanka);
,の認識どうなってんだろうね
>>925 文字化けが消えました!
どうもありがとうございました!!!
>>914 将来の拡張のために ID の範囲は余裕を持っておく
ぐらいのことは普通にあるだろ。
>>928 そうじゃなくて %s でひと続きの文字列として shohin[i].no 以下に格納されてるだけってのを見て欲しい
突然ですが、実際のプログラム(main)って、 tryの中にほとんどの記述を入れるのでしょうか。 とある本で例外処理の部分を読んでいる初心者ですが、 この章だけは、mainのほとんど(catch以外)を tryの中に入れてます。だけど、この後の章では ざっと見た限りほとんど入れてないように思います。 例外をことごとく捕まえたいときには、実際の 現実的なプログラムだとどうなるのでしょうか。 先走っているのかもしれませんが気になるので教えてください。
例外がキャッチされなかった場合、 自動変数のデストラクタが走る保証はない。 もしそれで致命的なリソースリークが起こるなら、 例外をキャッチするべきなんだろうな。
〜皿 只只 只只只只 只只 只只只 | 凸
エラー処理と復帰処理のできるところで捕まえればいい。 mainの処理全体をtryで囲むのは、例外即終了でおkな場合でしょ。
>>931 mainでキャッチしても、エラーメッセージ出すくらいしか使い道無くないかな
例外でアプリを落としてもいい場合は、キャッチしなくてもいいかな
落としたくない場合は、落としたくない箇所でキャッチすれば良い。たとえばメッセージループとかかな
質問だけど、DLL書いたとき、エントリのところで例外全部キャッチしたほうがいいかな
>>934 基本は全部囲っておかないと、 catch 漏れが無いか気をつけないといけなくなる。
>935 まあ、COM入門で出てくる話だが、「例外はDLL境界 超えられないものとして扱うべき」だな。
938 :
931 :2008/02/03(日) 23:43:24
>>932 -
どうもでした。
mainの中で全部っていうのは、
この本の(この章の)説明の都合なんですね。
こういうことでよろしいのでしょうか。
・mainの中でcatchしてもエラーメッセージを出すくらいの
処理しかできないので、基本は処理できるところで捕まえる。
・ただし、catchもれの心配もあるのでmainも全部囲う。
(もしかしてここはプロの方でも人によるとか、、?)
例外なんかキャッチしない仕事の人もいるぜ
>>932 確認させてください。スタックの巻き戻しってのは
例外だろうが何だろうが、スコープを抜けたら
構築済みのローカルオブジェクトは正しくデストラクタ
が呼ばれて解放されるんではないんだっけ?
これがRAIIを使ったリソース管理のメリットだと
思ってたんだけど。throwされた例外は確実にcatch
されないとリークするの?
{
boost::shared_ptr<Widget>(new Widget);
throw Reigai();
}
この場合、例外でスコープを抜けても
どこかでcatchされないとデストラクタ
が呼ばれずに、そのままterminateしてしまう?
terminate da Human.
試したけど本当に呼ばれないな。 そういう規格なんだろうか。 ハーブサッターの本の例外の話は嘘か?
例外を捕まえるハンドラがなければ、 throwした時点でterminate呼んでも良いみたいな話?
本当だ。 規格に書いてあった。
>>943 Exceptional C++の例外安全の話
項目13 P53とか
”例外が投げられてスコープから出たときにデストラクタが
呼び出され。。。”
って書いてあるから勘違いしてたかも。
最終的にどっかでcatchされるという前提なんだろうな。
しかしわかりにくい。。。 それじゃ、”例外が投げられてスコープから出たときに デストラクタが 呼び出され。。。” じゃなくて、 「その例外がcatchされたとき、。。。」って書けよなあ。
本当そう思う。 でもわかって良かった。
要するにmainで全ての例外をcacheすればいいってことか。
そういうことになるね。こんな記事見つけた。 Stack Unwinding in the Event of an Uncaught Exception When an exception is thrown and no matching handler can be found for it, C++ invokes the function terminate(). By default, terminates invokes the function abort(). (ここまでは規格の話だろうね) Some compilers guarantee that at this point, the stack has been unwound, i.e., all local automatic objects have been fully destructed, streams have been flushed, and open files have been closed. Other compilers don't unwind the stack in this case. In other words, whether the stack is unwound in the case of an uncaught exception is platform-defined. Therefore, you should check your compiler's documentation to know how it behaves in the event of an uncaught exception.
testというクラスがあって、 test::test(){各変数の初期化}というコンストラクタがあった場合 test *p; p=new test [n]; とした場合も*p[0〜(n-1)]の全てがコンストラクタが実行されて初期化されますか?
初期化されます
>>952 ありがとうございます。
かなり時間かけてクラス作ったのにコンストラクタ実行されなかったら泣くところだった
>>949 本当にそれした方がいいかどうかは分からんね。
どちらにしろ強制的に terminate される状況もあるわけだし、
よほど呼んでもらわないと困る処理は
set_terminate 側で対処した方がいい気もする。
955 :
951 :2008/02/04(月) 10:45:38
vector使った方が上手く処理できそうなのでvectorを使ってみたんですが、デバッグ で追いかけてみたところコンストラクタが実行されてません。 もしかしてvectorで確保した場合はコンストラクタ実行されないんでしょうか?
956 :
デフォルトの名無しさん :2008/02/04(月) 10:49:29
STLのvectorでintとかdoubleなどの値を保持しているとき、それらの和は どうやって計算するのが一番よいですか? 自分は、boost::lambdaをつかってるんですが、なんかもっと他の書き方が ありそうな気がして。(自分的にはboostがインストールされてないとダメなのが 嫌なんだけど、和、積、など他の演算にも対応がしやすくていいと思ってる) int tmp = 0; for_each(v.begin(), v.end(), tmp += boost::lambda::_1); ここのスレの他の人のやり方を見せてください。
957 :
デフォルトの名無しさん :2008/02/04(月) 10:54:39
ふつうは0からv.size()-1まで足すだろ
958 :
デフォルトの名無しさん :2008/02/04(月) 11:24:24
>>957 そうか、、、。
そういわれると、そういう気もする。
なんだか956が恥ずかしいな。わすれてください。
しかもSTLにあるしなw tmp = accumulate(v.begin(), v.end(), 0);
a > b であるunsigned int同士の引き算 b - aの動作は仕様によると どうなるのでしょうか? それと、ビットシフト演算子が算術シフトか論理シフトになるかどうかは 環境依存であってますか?
962 :
デフォルトの名無しさん :2008/02/04(月) 11:55:12
すみません。windowsXPで、eclipse+CDT+cygwinで勉強しています。 scanfなどで変数値を入力するプログラムを書いたとき、 事前に表示する「数字を入れてください」などの文章が出ず、 scanfに値を入力する待機状態になってしまいます。 どうしたらよいのでしょうか。 すみません。お教えください。
>>961 1) b - a + (UINT_MAX+1)
2) 左右シフトともに負の値のシフトに関して未定義。
いきなりエラーで落ちても文句は言えない。
C規格の専用スレもあるので活用してください。
964 :
962 :2008/02/04(月) 12:11:12
すみません。自己解決しました。 putsなりprintfなりを書いた後、fflush(stdout)をしました。 失礼しました。
>>963 すばやい回答ありがとうございます。もうひとつ質問がありました。
たびたびすいません。
両方ともunsigned intであるa * bが表現可能な数値の範囲を超える場合、
仕様による動作は未定義であってますでしょうか?
その動作に依存するコードを発見したので、書き直そうかどうか迷ってます。
ただ、画像処理(アルファブレンディング)に関するコードなので、書き直す
と命令数が増大して遅くなってしまうので、躊躇してます。
>C規格の専用スレもあるので活用してください。
初心者お断りと書いてあるのですが、このような質問でも大丈夫
なのでしょうか?
>>965 a * b % (UINT_MAX+1)
符号なし整数型の算術演算の結果があらわせる範囲を超えた場合はループする
頭の悪いやつがつけたスレタイを気にする必要はない。
>>966 ループするのですね、ありがとうございます。
コード書き直す必要が無いとわかって助かりました。
今度からこのような質問は規格スレに持っていく事にします。
968 :
デフォルトの名無しさん :2008/02/04(月) 12:26:25
>>959 <numeric>ですね。これほとんど使ってなかったんだよな。
恥ずかしいが、自分的にはaccumulateとか知ったからよかったよ。
ありがとう。
>>965 そもそもαブレンディングでオーバフローするような数字を扱うわけじゃないだろ。
そこを吟味せずにオーバフロー対策なんて意味ないぞ。
例えば、rgb各8ビットの画像から画素の値を取り出す場合は通常0-255の値域を取る。
そこで、unsigned intのr, g, b, ra, ga, baがあるとしたらr * raは何があってもオーバフローしないわけだ。
なんかずれてる気がするんだけどなあ。
猫でもわかるC言語プログラミングという本で勉強し始めたのだが、 誤字脱字ありすぎで正直自分が悪いのか本が間違ってるのかコンパイラの問題なのかわからん。 Borland C++ Compiler 5.5 #include <stdio.h> #include <float.h> int main() { double pai = 3.14159265358979; int mon = 2; printf("%d\n", mon = 3); printf("%e\n", pai); printf("%05d\n", mon); printf("%20.18f\n", pai); return 0; } で 3 3.141593e+000 00003 3.141592653589790000 と表示されるらしいのだが、 @二行目が 3.141593e+00 、四行目が 3.141592653589790007 になる。 Aコンパイラが警告を出す。('mon'に代入した値は使われていない) どうしたらいいのか教えてください。
>>971 正常。浮動小数点演算は丸め込みとかでコンパイラによって結果が若干変わる場合がある
gcc 3.2.2 [FreeBSD]
3
3.141593e+00
00003
3.141592653589790007
bcc32 5.6.4
3
3.141593e+00
00003
3.141592653589790007
cl(VC++) 13.00.9466
3
3.141593e+000
00003
3.141592653589790000
警告はint mon = 2;の後に値を読み出さずに3だを代入してるから出る。基本的に無害。
>>969 コードは載せられませんが、アルファブレンディングは
alpha*src + (1 - alpha)*dst
になりますが、そのコードでは一時変数を嫌って、
alpha * ( src - dst ) + dst
になってました。
演算子オーバーロードのような感覚で、 クラスのインスタンス名を書いたときに、特定の処理結果を返すようにする方法はありませんか? 具体的には class ClassA{ int val; } ClassA ca; があったとして cout<<ca.val; と書くところを cout<<ca; で出来るようにするという事です。 宜しくお願いします。
977 :
975 :2008/02/04(月) 22:31:18
すみません、<<は確かにそうでした。 条件式に単独で入れたときにvalの値でboolに変換されるようには出来ませんか?
bool ClassA::isPlus(){ return val > 0; } とかじゃだめなん?
bool operator !()constと operator void *()constあたりを定義するのが常套手段だが。
operator bool をオーバーロードするだけじゃダメなのか?
intへの暗黙のキャストが許せるなら、それでもいい。
>>980 訳わかんねえことがいっぱい起こるから、やめといた方がいい。
0xではこの辺の暗黙的型変換を禁止できるようになるんだよな、たしか。
984 :
975 :2008/02/04(月) 23:19:06
変換関数を定義しておけば良いんですね。
そういうものがあるというのは読んだんですが用途まで考えていませんでした…。
>>980 の方法で良さそうです。
>>979 のoperator void*でも上手くいきましたが
条件式の中身はboolにキャストされると思っていたんですが、
void*でも動くのはどういう意味なのか教えてもらえないでしょうか。
985 :
975 :2008/02/04(月) 23:23:45
すみません、
>>981 以降リロードしてませんでした…。
if( x )はif( x!=0 )と等価、というか。 void *m = malloc(len); if( m ) { return m; } else { abort(); } みたいな処理ってやったことないの?
>>984 982でも書いたが、operator boolのオーバーロードはやめとけ。
ClassA a, b;
int c = a + b;
int d = abs(a);
みたいのがコンパイル通っちまう。
>>979 が常道。
988 :
975 :2008/02/05(火) 00:02:09
わかってきました。 条件式に入るクラスは数値かポインタへの変換を持っていれば良くて、 operator void*を定義しておけばそちらに変換されると。 でintからboolよりもintからポインタの方が予期せぬ動作が少ないのでvoid*を使うべきと。 知識が足りてなくてレス読みつつググったりして勉強になりました。 どうもありがとうございました。
>>984 ポインタはboolへの暗黙の変換がある。
cinもそれを利用してif(cin)を可能にしている。
その方法が
>>979 の方式だ。
boolへの暗黙の変換はおすすめできない。
>>987 bool 値として使用したいのならそんなもんじゃね?
そうでないならそもそも演算子オーバーロードで解決すべきじゃないと思う。
boostは徹底してて、関数ポインタとか返してくるし(w
992 :
デフォルトの名無しさん :2008/02/05(火) 00:31:24
int a = 123; bool b = !!a;
>>991 すごー。でもそのくらいの方が有り難い。
まえに operator bool()を定義してて、コンパイラがブッ壊れたかと思った。
>>991 つまり、関数呼べちゃうってことか?
メンバポインタとかの方が良くね?
・ ・ ・ ・ ・ ・ ・ ・ メンバ関数ポインタだぜ? そうそう呼べはしないとおもうが。
なんだ。メンバ関数ポインタか。 ならいいが。
さーて来週のスレは?
お疲れ様でした。次週も環境依存コードをお楽しみください。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。