【初心者歓迎】C/C++室 Ver.53【環境依存OK】
1 :
デフォルトの名無しさん :
2008/04/24(木) 07:23:05
3 :
デフォルトの名無しさん :2008/04/24(木) 07:46:05
3
4 :
デフォルトの名無しさん :2008/04/24(木) 07:53:38
'1'はCだとintだけどC++だとcharなんだよね。 オーバーロードの関係でそうしたのかな。
5 :
デフォルトの名無しさん :2008/04/24(木) 10:43:42
前回59にしてしまったものです。53で立ててくれてありがとう。
6 :
デフォルトの名無しさん :2008/04/24(木) 12:51:25
>>4 簡単に言えばそういうことだ。
「std::cout << '\n';」で「10」とか印字されても困るだろ。
7 :
デフォルトの名無しさん :2008/04/24(木) 17:10:31
C++のtry〜catchって メソッドの中で入れ子になっていても問題ないですか? void CHoge::Method() { try{ // 処理1 try{ // 処理2 } catch(...){ // 処理2の例外処理 } // 処理3 } catch(...){ // 処理1、3の例外処理 } } みたいな感じです
問題ない
ちなみに、C++ではメソッドじゃなくてメンバ関数という あと、 void func() try { } catch (...) { } なんて書き方もOK
10 :
7 :2008/04/24(木) 17:18:39
virtual int sample() const; みたいな関数のプロトタイプ宣言があったのですが、なぜこの位置にconstがあるのでしょうか?? またこのような感じの関数はどういった呼び出し方をすればよいのでしょうか。 どなたか教えていただけると幸いです。
後ろに付いてるconstはその関数が (メンバ)変数を書き換えないという指定
template <template<class> class T> このようなテンプレートテンプレートパラメータが なぜこんな書き方ができるのか今一理解できません。 どこか詳しく解説してるとこはないものでしょうか?
14 :
デフォルトの名無しさん :2008/04/24(木) 19:35:22
すいません、教えてください。 --- ヘッダ ---- typedef struct _STRUCT1{ long code; CArray<long, long> data; }STRUCT1; CArray<STRUCT1, STRUCT1&> code_data; --- ソース ---- STRUCT1 st; st.code = 1; st.data.Add(100); code_data.Add(st); みたいな感じでやると、最後の行でコンパイルエラーになるんですが CArrayの中にCArrayを含む構造ってダメなんでしょうか? 途中までいい気でコーディングして、最後にエラー出てしまって 途方にくれています。 今更ほかの方法で似たような事やるのは大変で・・・。 よい方法ないでしょうか。
15 :
デフォルトの名無しさん :2008/04/24(木) 19:38:36
bool型のa[3] a[0] = 0; a[1] = 0; a[2] = 0; a[0] = 1; a[1] = 0; a[2] = 0; a[0] = 0; a[1] = 1; a[2] = 0; a[0] = 0; a[1] = 0; a[2] = 1; a[0] = 1; a[1] = 1; a[2] = 0; a[0] = 1; a[1] = 0; a[2] = 1; a[0] = 0; a[1] = 1; a[2] = 1; a[0] = 1; a[1] = 1; a[2] = 1; 行と行の間には何かしらの処理が入る。 これをfor文でまとめて書くにはにはどうすればいい?
0..7で回すのはダメなのかな・・・と思ったけど順番が微妙に違うのか?
17 :
デフォルトの名無しさん :2008/04/24(木) 19:56:28
綺麗なのが思いつかん くやしいわ
>>14 STRUCT1 st;
STRUCT1 st2 = st;
st2 = st;
の3行を書いて、コンパイル通る?
あとコンパイルエラーのメッセージは?
>>14 for( int i = 0; i < 7; i++ ) {
a[0]=(0xb2>>i)&1;a[1]=(0xd4>>i)&1:a[2]=(0xe8>>i)&1;
std::bitset<32> bits(0x76534210UL); for (int i=0; i < 8; ++i) std::cout << bits[i * 4] << ", " << bits[i * 4 + 1] << ", " << bits[i * 4 + 2] << "\n";
i<8だったorz
for( int i = 0 ; i < 7 ; ++i ) { const m = 076534210 ; bool a[] = { ((m>>(i+0))& )!=0 ,((m>>(i+1))&1)!=0 ,((m>>(i+2))&1)!= 0} ; なにかしらの処理 } うーん、いまいち
多重ループで挑戦してるけど・・・ 綺麗なのできねぇかなぁ
076534210 の 3 と 4 をきれいに入れ替えられたら勝利。
素直にやるなら #define NELEMS(array) (sizeof (array) / sizeof (array)[0]) #define GET_BIT(n, b) ((n) & (1u << (b))) static const unsigned int flags[] = { 0, 1, 2, 4, 3, 5, 6, 7 }; for (int i = 0; i < NELEMS(flags); i++) { GET_BIT(flags[i], 0) と GET_BIT(flags[i], 1) と GET_BIT(flags[i], 2) を使う }
配列 a[] を四つに拡張したい場合どうするかでも書き方をどうするか変えたくなるな 結構頭の体操としては面白い
どこが素直なんだよw
29 :
デフォルトの名無しさん :2008/04/24(木) 20:30:11
長いパスにアクセスするにはどうしたらいいですか? たとえばファイルオープンするときなどです。
長いパスにアクセスすればいい
31 :
15 :2008/04/24(木) 20:32:32
皆さん考えていただいてありがとうございます。 今回はなんとかできました。 ヒントをいただいたので配列の長さがNの時も考えようと思います
一般化するなら再帰使うといいよ。再帰。
33 :
デフォルトの名無しさん :2008/04/24(木) 20:40:34
255文字以上のアクセスできない場合にアクセスする方法ってありますか?
Unicode 版の CreateFile を使って、 パスの前に "\\\\\?\\" を付けるといいらしいが、 実際にやってみると出来ないと聞いたこともある。
35 :
デフォルトの名無しさん :2008/04/24(木) 20:45:50
トン!
36 :
デフォルトの名無しさん :2008/04/24(木) 20:48:52
オフラインで使える C と C++ のリファレンスって何か良いのありますか?
VC6 の MSDN
なんだかんだ言ってMSDNが一番纏まってて読みやすいんだよな… しかし最近のはwebも新形式ヘルプも重い罠
>>36 古めの C/C++ のドラフトとか。英語だけど。
41 :
デフォルトの名無しさん :2008/04/24(木) 21:28:34
>>34 すみません 100文字は出来ますが300文字だと無理になります
どうすればいいですか?
#include <windows.h>
int main(){
int r; wchar_t e[1000]=L"\\\\\?\\c:\\";
//100文字のディレクトリを生成してみる
fore(r,100)e[r+7]=L'a'; e[7+r]=L'\\'; e[8+r]=0;
CreateDirectoryW(e,NULL);
//300文字のディレクトリを生成してみる
fore(r,300)e[r+7]=L'b'; e[7+r]=L'\\'; e[8+r]=0;
CreateDirectoryW(e,NULL);
}
42 :
デフォルトの名無しさん :2008/04/24(木) 21:32:49
Windowsでは生成は出来ないけれど、別の環境で作成されたパスにアクセスはできるという事ですか?
確かディレクトリ名やファイル名はMAX_PATHまでだったと思う。 でフルパスの時32767まで。
44 :
デフォルトの名無しさん :2008/04/24(木) 21:37:09
45 :
デフォルトの名無しさん :2008/04/24(木) 21:55:42
>>43 トン できました!
int main(){
int r;
wchar_t g[1000]=L"\\\\\?\\c:\\",h[]=L"aaaaaaaaaa\\";
for(r=0;r<30;r++){wcscat(g,h); CreateDirectoryW(g,NULL);}
wcscat(g,L"bbbbb\\"); CreateDirectoryW(g,NULL);
}
初めてのプログラミングでCをやるのですがお勧めの参考書があったら教えてください
47 :
46 :2008/04/24(木) 22:52:57
しまった、age ちなみにVC使う予定です
CなのかC++なのかMFC使うのかWIN32APIなのかなど、 どういう使い方をしたいのかで変わってくると思う。
それすらチンプンカンプンなのでもう少し調べてみます
何でやるのか書いた方が良いよ。 学校の勉強か、趣味か、仕事か、作りたいものでも有るのか、他。 それと基礎知識。 多言語の経験有るとか、プログラミング初心者とか。
VCでCの勉強するって書いてあるから [やさしいC]あたりでいいんじゃないでしょうか? 個人的意見ですけど最初はIDE(VC等の統合開発環境)使わずに コンパイラだけ用意して勉強したほうがいいかと。
仕事ですね アプリ系らしいけども プログラミング自体初心者なので何から始めたらいいやらで
職場の先輩にでも聞いた方がいいと思うけど
初心者なら windows なんてやめて UNIX系で慣れろ 使いもんにならんwindows 育ちなど
Windows プログラミングするなら それでも Windows で慣れてないと困るけどな。 ただ、Web 系するだけなら別に Windows である必要は無いな。
>>52 仕事(実務がてらの教育な気もするけど)なら、最短経路ってことで、
プラットホーム(LinuxとかWindowsとか)と、
本当にCなのか、それともC++でもいいのか聞いた方がいい。
>>54 概ね同意だけど、一つのプラットホームしか知らない奴も結構使えない。
メンバ関数のポインタのとり方教えてください。 コメントの部分でエラーになってしまいます……。 class ca { public: int (*pa)(); int nasi(void); ca(void); }ca1; int ca::nasi(void){return 0;} ca::ca(void) {pa = nasi;} //コンパイルエラー
60 :
11 :2008/04/25(金) 00:36:57
void
62 :
58 :2008/04/25(金) 00:51:53
>>59 ありがとうございます。おかげでできました。
これからはもう少し自分でも調べるようにします。
class ca {
public:
int (ca::*pa)();
int nasi(void);
ca(void);
}ca1;
int ca::nasi(void){return 0;}
ca::ca(void) {pa = &ca::nasi;}
>>13 亀レスですまんけど、何故そういう書き方ができるか、というより
そういう書き方をする意味ならある。
確かそのようにニ重にテンプレート指定すると、
template <template <class> class T> class hoge{};
とした場合に、hogeのインスタンスを宣言するときに
hoge< fuga<monyu> > Hoge;
ではなく
hoge<fuga> Hoge;
で済むというメリットがあったと思う。
fugaもテンプレートクラスであるにも関わらず、fugaのテンプレート引数は
指定しなくていい(ただしデメリットもあったと思うけど)。
あまり覚えてないので大して助言できなくてスマン。
補足。確か、そのような二重のテンプレートの場合 hogeクラスがmonyuの型を要求するような実体化を伴う場合、 (hogeクラスからfugaクラスのメンバ関数を呼ぶ場合でも。中でmonyuの型が必要なら) 実体化に失敗するんだったと思う。 その代わり、hogeクラスはfugaクラスのテンプレート引数に自由に型を 指定して利用することが出来る(もちろん文法が通る場合に限るが)。
>>63 ,64
詳しい説明感謝です。
他スレでも聞いてしまってましたが、
そっちとはまた違った説明で、おかげで
かなり納得できました。
>>65 すまん、そっちの説明どんなだったか教えて欲しいかもw
あんま使ったことない用法だから自信ないので・・
ダイアログ1のOnInitDialogにダイアログ2を1の子としてCreate、ShowWindowするコードを追加したいのですが、ダイアログ2の変数の作り方がわかりません。 ダイアログ1のヘッダーに paintDlg2 m_dlgPaint; を記述しても ';' が、識別子 'm_dlgPaint' の前に必要です。 というコンパイルエラーがでます。 インクルードの順序は確認したのですがうまくいきません。 2008で自動で変数追加しようとしても変数の種類が選べなくてよくわからないんです。
しかし template <template <class> class T> これ、関数ポインタと同じ様な書式で template <class T<class> > と書くほうが自然な感じがするのは自分だけ?
>>68 thx。
しかし色んな書き方できるんだなぁ・・・
templateといえば template<class T> class A { } template<class T2> class B { } A< B<型> > a; ってなテンプレート型にテンプレート型を渡したときに、Aのスコープ内で Bのテンプレート引数(T2の実体型)を知る方法って無いよね?
template<class T2> class B { typedef T2 hogeT2; } A< B<型> > a; a::hogeT2 hoge; で行けない?
あ、Aのスコープ内か。 そんならT::T2でいけるかもしれないし、だめなら↑のtypedefで行けるはず
>>73 T::T2 は無理。
typedef すればいけましたが、
A<B<x>> が A<C<x>> や A<D<x>> になった時に
対応が大変なので、
template<template<class> class TemplateT, class ParamT>
class Typenamedef {
typedef TemplateT T_TYPE;
typedef ParamT P_TYPE;
};
template<class T>
class A {
T::P_TYPE x ;
};
A< Typenamedef<B, 型> >
こういう形に落ち着きました。
そのBにあたるクラスって何個かあるの?
それだと直接 template<template<class> class TemplateT, class ParamT> class A { ParamT x; } でいいじゃんと思うのだが
>>75 ありますし、今後増えるかもってことで。
>>76 Bにあたるクラスのテンプレート引数の数が変わった場合でも、
Aを書き換えずに対応できるようにする為に74の用に1クッション
入れたほうが良いかなと思ったのですよね。<Aも何種類かあるので
78 :
77 :2008/04/25(金) 21:50:44
読み返すと分かり難かったので、もちょっと具体的に書くと、 Aはboost ptr_containerの代替品で、ポインタを格納するコンテナ型を受け取ります。 BはSTLコンテナ、または自作コンテナ。 例えばvectorだとテンプレ引数にアロケータがあるので、 template<template<class, class> class T>と引数が2つになるが、 自作コンテナはアロケータまで取ってないので引数が1つだったりするし、 A内でアロケータまで知る必要もないので >74 で済むってな寸法です。
79 :
デフォルトの名無しさん :2008/04/25(金) 21:52:10
関数でwchar_t *型をリターンするには、newで確保するしかないですか? メモリリークしますよね いい方法無いですか?
>>79 aout_ptr 又は shared_ptr で検索
すまん auto_ptr の間違い
82 :
デフォルトの名無しさん :2008/04/25(金) 22:01:51
標準のやつでは無理でしょうか?
84 :
デフォルトの名無しさん :2008/04/25(金) 22:21:35
トン
85 :
デフォルトの名無しさん :2008/04/25(金) 22:50:10
すっげー、意味不明な質問かもしれませんが 四則演算を駆使して16桁の2〜36進数までを10進数に直すプログラムって可能でしょうか?
86 :
デフォルトの名無しさん :2008/04/25(金) 22:55:58
>85 読み直してみろ それで質問の答えが返ってくると思うか? 何がやりたいのかをきちんとまとめてから文章にしろ あて主語がなにかはっきりしろ
普通に 四則演算だけを用いて16桁のn進数を10進数に変換しろっていうだけだろ? 日頃やらないから、凄く面倒くさい手段しか思いつかん
// ex. "3A"を58に変換する private static int toDecimal(string hex) { int n = 0x0; switch (hex[0]) { case '0': n = 0x00; break; case '1': n = 0x10; break; (省略されました・・全てを読むにはここを押してください) ⁻⁻⁻⁻⁻⁻
すげー、かったるい方法だけど 配列のCharで取得して0番目なら15回基数をかけた奴と入力された値をかけt(ry
>>78 うーん、やっぱり自作コンテナ内で
typedef T value_type;
したほうがいいと思うのは俺だけ?
92 :
デフォルトの名無しさん :2008/04/25(金) 23:36:38
STLのstackは、pushとpopがつかえますが、popしたときに入力した型で帰りますか? コンパイラがvoidを返すようなメッセージだします。受け取れません
93 :
92 :2008/04/25(金) 23:38:11
すみません。データ取り出して一つ消すのかと思ったら、消すだけでした。
94 :
デフォルトの名無しさん :2008/04/25(金) 23:50:02
これがうごかないのはなんでですか? class cls{ public: string a; int n; }; cls x=(cls)("aaa",5);
>>85 strtolとかstrtoulとか。
宿題なんで使用禁止なら宿題スレ行け。
>>92 なるべく厳しい例外安全を達成するため、
stackの先頭を読み取るのはtopメンバ関数として、popから分離されている。
>>94 そういう構文が存在しないから。
cls x = {"aaa", 5};
>>91 それ以前に、B<T>とTをそれぞれ引数として渡した方が
遥かに楽だったことにさっき気が付いたorz
>>96 それってstd::vectorなど標準コンテナののテンプレート引数では、
Tと(デフォルト引数で)std::allocator<T>を渡すのと同じ感じだよね。
>>80 配列と想像される可能性が高いのに
そんなもんを薦めるなよ
emun型を宣言してVSC++でビルドしようとすると 宣言の前に"{"がないって怒られて通らないんですがどうしてでしょう・・orz
100 :
デフォルトの名無しさん :2008/04/26(土) 12:16:45
この初期化方法に名前ついてますか? ググり方教えて下さい。 見た事、やったことないです。 class Meibo{ public: int GakuseiNo; string Name; Meibo() : GakuseiNo( -1 ), Name( "" ) {} Meibo(int n, string name) : GakuseiNo( n ), Name( name ){} bool operator<(const Meibo& a)const{ return GakuseiNo < a.GakuseiNo; } };
エラーの行かそれより前で{か;を忘れてるところがある
103 :
デフォルトの名無しさん :2008/04/26(土) 12:25:58
トン
>>101 そう思ったんですが、enumの宣言行をコメントつけるとエラーでなくなるんです
enumの最後にセミコロンないだけなんじゃないのか・・・
enum { HOGE = 0 }; ←このセミコロンだな
>>105 ソレも確認しましたが、ついてます。
どうして通らないのかちんぷんかんぷんで・・・orz
その前後のコードをコピペしようよ…。
emun ってところがミソだな
#include <iostream> using namespace std ; int main ( void ) { enum baba_t {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, g,}; baba_t zizi; return 0; } たった、これだけの最低限にしても}が定数の前にないっておこられます
111 :
デフォルトの名無しさん :2008/04/26(土) 13:02:33
enumって普通 enum baba_t { A = 0, B, C, D, E }; baba_t zizi; こういう風に使うんじゃないのか
enumが何なのかわかってるんだろうか…
そもそも
>>110 って書いた場合どういう風に使うの?
>>110 整数リテラル0の前に}がないって怒られてるんだよ。
そんなものenumの要素になりえないから。
enumってキーワードに数値を割り当てるんですね、判ります。
本読みながら適当に打ってみたら通らなかったので悩んでました あほでごめんなさい・・・orz
これは酷い。 ってか、ちょっとでも解説書やサイトを見ていれば こんな記述は考えもつかないと思うんだけど…。
118 :
デフォルトの名無しさん :2008/04/26(土) 14:01:32
最大公倍数をユークリッド互除法を用いて求めたいんだが 入力した2数の小さいほうがそのまま出力してしまう… #include<iostream> using namespace std; int func(int x,int y); int main(){ int a,b,gcd; cout <<"数値を二つ入力してください\n"; cin >>a>>b; gcd=func(a,b); cout <<"最大公約数は"<<gcd<<"です\n"; return 0; } int func(int x,int y){ int r; if(x<=y){r=x; x=y; y=r;} while(1){ x%=y; if(x==0) break; r=x; x=y; y=x; } return y; } すごく初歩なんだろうけどお願いします
119 :
118 :2008/04/26(土) 14:02:59
ミスった 最大公倍数なんて求まるわけないwww 最大公約数の間違い
>>118 r=x; x=y; y=x;
↓
r=x; x=y; y=r;
121 :
デフォルトの名無しさん :2008/04/26(土) 15:01:57
r=x; x=y; y=x; ↓ x ^= y; y ^= x; x ^= y;
それは邪悪な誘惑だぞw
それよりもC++なら<algorithm>のstd::swapだろ。
クラスに^=演算子を定義して
>>122 だろ、常考・・・。
???
ブラインドタッチで[とか]とかどうやって打ってるんだお前ら
Enterの横に薬指引っかけて人差し指で押す
そこで英字配列
第六感
>>127 他の人はどうか知らないけど、俺は頻繁にホームポジションを崩す。
[]←たとえばこれは、半角/全角キーを左手の中指で押して日本語入力切って、
そのあと右手の中指と親指でタタンと上から下に流すように[と]を打って、
すぐまた半角/全角キー押して日本語入力モードにしてホームポジションに戻った。
これくらいの動きなら、手元をみなくてもまず間違えないし。
そもそもホームポジションの無い俺には関係無い話だな
小指で押すだろ普通
[を入力したら適切に]も挿入するようにスクリプト組む でそれを@に割りあてる @なんか連打しないでしょ?@@@@@@@@@@@@
135 :
デフォルトの名無しさん :2008/04/26(土) 21:54:35
C++で変数の名前に変数って使う方法ってありませんか? Perlで言う$$testみたいなものです 具体的に言うと、 id1 id2 id3と末尾だけ変わっていく変数の処理が同じなのでforループしたいんです。 現状だと if( id1 != 0 ){ ... } if( id2 != 0 ){ ... } となってしまうので。
無理 最初から配列にしとけばいいんじゃね
本読みながら勉強してて、よくわからないのですが cherの中に整数値として16進数を入れた時、これをint型の整数に変換する事は可能なのでしょうか?
cherじゃなかった・・・charだった・・・orz ごめんなさい
何が死体の川からンが、これは理解できるか? char foo = 0x41; printf("%d, %x, %c\n", foo, foo, foo); foo = 'A'; printf("%d, %x, %c\n", foo, foo, foo); foo = 65; printf("%d, %x, %c\n", foo, foo, foo);
>>140 文字コードを16進数で突っ込んで表示させてるだけですよね?
入力された文字コードからソレゾレ差分を引けばいいのかもしれないと考えて見ましたが
どうしたらいいのかと、どんどん泥沼にはまりました・・・
142 :
デフォルトの名無しさん :2008/04/26(土) 22:20:02
>>136 やっぱり無理ですよねorz
配列にしとけって指摘は完全同意なのですが、
あほな先輩が作った部分でそこいじっちゃいけない空気なので・・・
char a = 0x41; int b = a; って話じゃなく?
先輩に向かってあほ呼ばわりって時点で終わってるな
>>142 int id0, id1, id2, id3;
int *id[4] = { &id0, &id1, &id2, &id3 };
for(size_t i = 0; i < 4; ++i) *id[i] = 0;
どうしてもって言うならこういう弄り方しかないな。
だがあほ・だめな上司・先輩がいるのは業界問わずいるのは事実。 一度採用しちゃうとなかなか切れないからね。組合強いとこは。
148 :
デフォルトの名無しさん :2008/04/26(土) 22:45:05
veector<string>で小さくリサイズすると、stringは自動で解放されますか?
149 :
148 :2008/04/26(土) 22:51:52
自己解決しました メモリーリークしました。 x.resize(1);をx.swap(vector<string>());にしても駄目でした。 STLもまだまだ駄目なんですか? main(){ vector<string> x(100); for(int n=0;n<100;n++)x[n].resize(1000000); getchar(); x.resize(1); getchar();}
そりゃぁ、正しく使わなければ使えないだろう。
151 :
148 :2008/04/26(土) 22:56:37
これでうまくいきましたよ class str{ public: string s; str() { s.resize(1000000); } ~str() { s.swap(string()); }}; main(){ vector< str > x(100); getchar(); x.resize(1); getchar();}
152 :
148 :2008/04/26(土) 22:59:55
STLは関数のリターンで消滅するというのは本当と思いますが、 resizeでは消滅しないですよね なんでですか?
153 :
デフォルトの名無しさん :2008/04/26(土) 23:01:29
vector<int>だと、また増やすことがあるので、消えない方が良いですけど <>内で巨大な確保していると困りますよね?
155 :
デフォルトの名無しさん :2008/04/26(土) 23:08:54
149のコードで、stringが消滅しないのが不便です…
>>149 では2度目の getchar 時にもメモリ使用量は変わらないと思うが、
メモリリークしてるわけではない。
単に、delete されたメモリがすぐ OS に返されるわけではないというだけの話。
>>155 VC++2005で普通に解放された。↓のBの時点で。
std::vector<std::string> x(100);
for(int n=0;n<100;n++){
x[n].resize(1000000);
}
std::cout << "A" << std::endl;
getchar();
x.resize(1);
std::cout << "B" << std::endl;
getchar();
158 :
デフォルトの名無しさん :2008/04/26(土) 23:46:45
トンクス
>>154 swapは必要最小限のメンバ交換だから、
それ以上の処理をすることは無いんじゃないかな。
>>155 newの裏にいるmallocが再利用するために持ってるだけだと思う。
stringのデストラクタは呼ばれてるはずなので。
↓でも1GB確保しっぱなしになる?
//※テストコードなので例外安全とか無視。
std::vector< std::vector<std::string>* > xv;
for(int i=0;i<100;i++){
xv.push_back( new std::vector<std::string>(100) );
std::vector<std::string>& x = xv.back();
for(int n=1;n<100;n++){
x[n].resize(100*1024);
}
x.resize(1);
}
std::cout << "A" << std::endl;
getchar();
for(int i=0;i<100;i++){
delete xv[i];
}
160 :
159 :2008/04/26(土) 23:52:39
× x = xv.back(); ○ x = *xv.back(); ごめん、コンパイル通してなかったから。
3Dアクションゲームを作りたくてアマゾンで3DRPGの作り方系の本を数冊買おうと思うのですが 数学や物理ができないとかなり無謀ですか? 一応高校は卒業していて、やる気は◎です。 数学と物理の評定はだいたい3〜4でした
間違ってあげちゃいました すいません;;
163 :
デフォルトの名無しさん :2008/04/27(日) 00:29:59
>>161 かなり無謀だけど、そこはやる気でカバー。
>>161 いいから本屋に行って立ち読みしてこい
発言内容からするとプログラミング初心者か?
いきなりそんな本買ってもムダだ
>>161 質問はageで良いよ
無謀かどうかは作るものによると思う
エンジン自作とかは無茶だろうし
本買うのは良いけど、言語(C++?)とかプラットホーム(Win+DirectX?)の知識は大丈夫?
本が前提としてる知識が無いと読んでも躓くだろうから
166 :
デフォルトの名無しさん :2008/04/27(日) 00:37:11
>>161 ホットスーププロセッサーでサンプル動かして様子を見る。
とりあえずウィンドウ出す ↓ 点とかでいいから図形描く ↓ 一点透視の簡単な3Dを出す とか?DirectXとか使うなら余計な部分でやる気削がれないようにすればできる
const オブジェクトは変更できないとでるのですが、わかりません 間違い教えて下さい class A { public: int a; A(int n){a=n;} bool operator < (const A &z) const {return a < z.a; }}; void fnc(set<A>::iterator p) {p->a=0; } main(){ set<A> w; w.insert(5); set<A>::iterator p=w.begin(); fnc(p); }
171 :
170 :2008/04/27(日) 01:38:33
イテレータを引数にして、その内容を変更したいんです…
172 :
170 :2008/04/27(日) 01:39:56
エラーのでる箇所は、p->a=0;の部分です。 なにがいけないのかわかりません。教えて下さい。
set は平衡木で実装されるが、 平衡木のノードの内容は勝手に変えられると 順番変わる恐れがあるから、 set のイテレータは内容を変えられないようになってる。
174 :
デフォルトの名無しさん :2008/04/27(日) 01:48:45
ありがとう。 わかりました 削除して新たに追加します。
【環境】 WindowsXP + VisualC++ 9.0 【質問】 色々なページを見て回ってサンプルコードをコンパイルしようと思ったのですが、うまくコンパイル出来ません。 以下ソースコード #include <windows.h> int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { MessageBox(NULL,lpCmdLine,"MessageBox",MB_OK); return 0; } cl c:\test.cpp としても test.obj : error LNK2019: 未解決の外部シンボル __imp__MessageBoxA@16 が関数 _WinMain@16 で参照されました。 と出て失敗します。どうすればコンパイルできるのでしょうか?
cl test.cpp kernel32.lib user32.lib
>>176 素早い回答、どうもありがとうございます。本当に助かりました。
>>159 std::string().swap(str);
こう書くとswap先のインスタンスが即デストラクトされるて元の中身が解放される。
自分はこんな風に使ってる
template<class T>
void SwapDelete(T &rCn) {T().swap(rCn);};
vector<string> x(100); string が 100 個確保される。 for(int n=0;n<100;n++)x[n].resize(1000000); それぞれの string のサイズが 1000000 になる。 x.resize(1); x[0] を除いた全ての string が破棄される。 string が破棄されるということは、string 内のメモリは解放される。 ただし、vector 内のメモリの最確保は行われない。 また、メモリが解放されても即座に OS にメモリが返されるわけではない。 これだけの話。
virtualなテンプレート関数って無理なのか。 STLコンテナ汎用な関数をテンプレートで実装する クラスの継承で詰まった・・・
残念ながら無理だね。仕様的に。
virtual なメンバ関数テンプレートは無理だが クラステンプレートの virtual メンバ関数は可能なので それを間に入れて何とかするしか
183 :
161 :2008/04/27(日) 10:36:41
スレ違いかもしれませんが最後に質問させてください。 英雄○説Yみたいなゲームを作りたいのですが 今C言語とWindowsAPIというやつを勉強しています。 ↑のようなゲームを作るためにはどんな言語を覚えれば ベストですか? ゲームの専門学校の入ったのですが先輩が2年間学んでも テトリスくらしか作れないと言っていたので自分で勉強しようと思いました。
とりあえず、DirectXを学んでくるといいと思うよ。 RPGツクールでもやってろ
185 :
デフォルトの名無しさん :2008/04/27(日) 10:41:23
>>183 ゲーム会社にアルバイトに行く 技術を現場で学ばないと無理 独学では一生でも無理かもしれない
186 :
デフォルトの名無しさん :2008/04/27(日) 10:43:13
初心者は何をどうやれば作れるのかわからない物 しかしゲーム会社は生産しないと利益でないから 入れば生産方法がわかる
>>183 やる気は大事だね。持ってる事はいいこと。
coding はしなければできるようにはならない。
どうせ C 勉強してるなら C++ を勉強するのが良いと
思うけど。今更 C から学ぶ必要は無い。
Java とか ruby とか python とかでもいろいろゲームを
作れるし、そちらの方が手軽かもしれん。けど、プログラミング
初心者ならいろいろ手を出すより一つ言語をある程度使いこなせる
ようにするのが良いと思う。
ゲームが専門で2年間でテトリスは寂しすぎる…
188 :
デフォルトの名無しさん :2008/04/27(日) 10:48:22
189 :
デフォルトの名無しさん :2008/04/27(日) 10:50:53
ゲーム作りたいのか、プログラムやりたいのかはっきりさせよう。 堀井雄二はプログラム出来ないけど大ヒットゲームを何本も作った。
アドバイスありがとうございます。 やる気出てきました、がんばります!
191 :
デフォルトの名無しさん :2008/04/27(日) 10:57:32
bcpadがダウンロードできなくなったね。 あれ便利だったのにorz まあ運良く404になる前にパソコンに入れてたからいいけど。
もはやbccの需要なんてあるの?
193 :
デフォルトの名無しさん :2008/04/27(日) 11:07:40
BCC使ってるよ コンパイル速度が速くて実験・学習向き 中身は5.5.1ではなくて最新版のやつに変更してる GUIは使わない
>>187 なるほど、
学校の先生はc++は一行のプログラムで色々処理できるから便利と言っていたけど
普通のCからやらないと絶対ダメ!と言っていましたw
195 :
デフォルトの名無しさん :2008/04/27(日) 11:25:48
皆インターネットが悪いんだろうな。単なるプラザ表 示のゲームだから昔の人は偉かったなすべて、何もか も最初から造る。本の通り出来る訳ない。みんな嘘構 造文に嘘説明。神田の明倫館とか書泉もう時代遅れ。 高岡が儲かり指南の教本がインターネットだから楽な んだろうな。
>>194 とにかく書かなきゃ書けるようにはならんから便利な方から
やりゃいいのよ。目的達成できればいいし、オブジェクト
やテンプレートがある思考法に初めから慣れた方が良い。
C++ に自信が無い人は大抵 C からやらなきゃダメ、と言って
C だけ教えるんだよね。好意的に解釈すると、プロになるならば
C も読めなきゃいけないし、C 的文法も知る必要がある、という
事は言えるかも。ただ、それを初めにしなきゃいかん理由は無い。
197 :
デフォルトの名無しさん :2008/04/27(日) 11:44:56
C言語よりも、C++のほうが易しいと思う。 失敗しにくいような工夫が盛り込まれている為。 ポインタが面倒なので参照いれたり、 型が厳密な為に複雑になるのをオーバーロードやテンプレートで単純化したり 誰もがよく使う処理をSTLとしてまとめたりしてある。 STLを実現する為に必要な文法を勉強するとなると大変だが、使う分には易しい。
charとstringにはほぼ互換性ありますけど(変換したときに内容は同じ) wchar_tとwstringの中身も同じになりますか?
はい
サンクス 実験しても平気でした。 main(){ int n,k; char a[]="あいうえおアイウエオ"; string b=a; k=b.size(); for(n=0;n<k;n++) if(a[n]!=b[n]) cout<<"kobetu err\n"; if(memcmp(a, &b[0], k))cout<<"memcmp err\n"; wchar_t c[]=L"あいうえおアイウエオ"; wstring d=c; k=d.size(); for(n=0;n<k;n++) if(c[n]!=d[n])cout<<"kobetu err\n"; if(memcmp(c,&d[0],2*k))cout<<"memcmp err\n"; return 0; }
202 :
198 :2008/04/27(日) 12:45:30
memcpyで送っても同じになりました。 main(){ wchar_t a[]=L"あいうえおアイウエオ"; wstring b,c=a; b.resize(10); memcpy(&b[0],a,20); if(b==c)cout<<"itti\n"; }
現時点ではbasic_stringのバッファは連続性が保証されてないはずなので memcpyはダメだ。
もうひとつ質問いいですか? wchar_tはUTF16なんですよね? これは基本単位が16bitで一語が32bitになることもありますよね? char を wchar_tに変換しようとするとき、確保を2倍にしたら不都合でますか?
>>204 > wchar_tはUTF16なんですよね?
そんな決まりはありません。
> char を wchar_tに変換しようとするとき、確保を2倍にしたら不都合でますか?
もちろん。
wchar_t が UTF16 なのは VC 限定の話。 一般的にはどうなるか不明。
学校のテキストにc++のはなかったので TUTAYAに売っている入門書でも大丈夫でしょうか?
>>208 どの入門書がオヌヌメなのか聞きたいの?
アマゾンのレビューで★が一番多い奴でも選べば
ありがとうございます!
>>211 入門書のレビューがほとんど無いじゃん。
Cが分かるなら、C++って入門書じゃなくって仕様書読めば分かると思うが
それはない。
217 :
デフォルトの名無しさん :2008/04/27(日) 17:27:28
CとC++は全く異なる言語だ。
218 :
デフォルトの名無しさん :2008/04/27(日) 17:33:49
全くってことはないだろ Cのソースの拡張子をcppに変えてもちゃんと動くのは偶然じゃないだろ?
一部はちゃんと動かないよ。
>>219 そりゃそうだけどさ・・・
最初っから「C++はCをベースに作られた言語だよ」って書けばよかったのか
C で組んだプログラムと C++ で組んだプログラムは、 両方がその機能を十分に発揮している場合、 全く異なる感じになるだろう。 もしそうなっていないようなら、C++ をちゃんと使いこなせてないってこった。
そうだけど、CとC++の差は、 少なくともC++未経験者にとって仕様書を読んだだけでは分からないだろ。 オブジェクト指向やジェネリックプログラミングなどの概念を身に付けないと。
223 :
デフォルトの名無しさん :2008/04/27(日) 17:54:11
C++でバイナリファイルから浮動小数点を読む時の定番手法はどんな感じでしょうか? 整数読むときみたいに、ios::binaryを設定した後、ifstreamのreadで読もうとしても ifstream.read( char*, int) なので1byte単位での読み込みになり、1bit仮数部だけの読み込みはできないですし、 atofはアスキーデータからしか変換できません。 どんな方法で浮動小数点読み込むのがベターですか? やっぱり<cstdio>のfread使うのでしょうか。
系統的に近い言語ならCを理解できる頭があるなら 日本語で方言扱うのと同じ様にC++分かるつってるだけなんだけどなぁ・・・
225 :
223 :2008/04/27(日) 17:56:33
仮数部じゃなく符号部ですね。
方言程度の違いしか無い訳が無いだろう・・・。
>>224 かなり無理があると思うな。他の人も言っているが、class や
template の考え方や override みたいな使いかたは経験無ければ
仕様書読んだだけでは普通無理。Java バリバリ使っていて C も
知っています、というのならまだわかるが。
もちろん C も基本的に C++ として有効なので、仕様書読んだだけでも
使える、と言って C++ のメリットを生かしていない場合は結構あるだろうな。
>>223 reinterpret_castしてそのistream.readの引数に渡せばいい。
>>223 普通に
double d;
read((char*)&d, sizeof d);
みたいに読むけど。
あ、こういう感じね。 double d; is.read(reinterpret_cast<char*>(&d), sizeof d);
俺の感覚が変なんですね・・・。 まぁ、初めてC触ったのが幼稚園で小学校でアセンブラとかやってた 変態チックな俺が世間とずれてるのはよくあることですよね
逆に低級言語で頭が止まってるんじゃないかと
233 :
223 :2008/04/27(日) 18:25:15
>>228-230 ありがとうございます。納得です。
reinterpret_castの使いどころなんですね。
>>231 アセンブラを教えてくれる幼稚園や小学校があるならぜひ紹介してくれ
>>234 関係ないが、ロシアにはハッキング教室がある。
企業情報を盗んで生計を立ててる卒業生もいるらしい。
俺も幼稚園からやってたな小学校でアナログ時計とか作ってた 本の英小文字とキーボードの大文字がリンクとれなくて大文字のフリガナを親に書いてもらってたのを思い出した
なんかPC6001に会いたくなってきた
238 :
デフォルトの名無しさん :2008/04/27(日) 19:53:59
***.exe 等の実行可能ファイルを実行したらどうなりますか? いったんメモリに命令群が展開されてそこから(?)実行されると思うのですが、 プログラムがメモリのどの位置に配置されたか分る方法ってないのでしょうか? メモリに配置されたプログラムをダンプするプログラムを作りたいです (´・ω・`) ヒントだけでもいいので教えてください。よろしくお願いします。
240 :
デフォルトの名無しさん :2008/04/27(日) 20:35:26
>>239 ヒントどうもありがとうございます。色々調べてるんですが、なにぶん初心者なもので理解に苦しみます ^^;
OpenProcess に ReadProcessMemory , CloseHandle 色々あって難しいですね。。。
あまり好き勝手に他のプロセスに干渉できる作りだとセキュリティ的に問題アリだろ。 それでもWindowsはヌルい方なんだけどな。
ファイルを削除する処理のあるコード書くときはいつも緊張する
わかるw
削除するだけじゃなくて上書きがありうる場合もね。 必ずテスト気を付けてしてるよ。
245 :
デフォルトの名無しさん :2008/04/27(日) 22:00:16
テンプレートクラスの親クラスを作って、それを継承した子クラスを作ったとき、子クラスから親クラスのメソッドを 参照できないのは、どうしてそういう仕様になっているのでしょうか? this->付けたりとかusingしたりすれば良いのは知識としては知っているのですが、いまいちこの仕様に納得できません。 template <typename T> class base { public: void func() {} }; template <typename T> class deri : public base<T> { public: void func2() {func();} }; みたいにしたときです。
func2 から見えるところにフリー関数の func があったりすると T によって呼ばれる関数がフリー関数になったり、メンバ関数になったりするのが わかりにくくて嫌な挙動だからだと思う
#include <windows.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){ MessageBox(NULL,"Kitty on your lap","メッセージです", MB_OK); return 0; } これってどこか間違ってますか?
Linux環境なんだけど、gccとg++から両方リンクできるライブラリってどうやって作るの? gcc -c func1.c func2.c ar rcs libtest.a func1.o func2.o だとオブジェクトファイルを生成したコンパイラでしかリンクできない
249 :
デフォルトの名無しさん :2008/04/27(日) 23:33:32
>>247 bccならそれでコンパイル通るけど、VC++なら
#include <windows.h>
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
TCHAR *lpCmdLine,
int nCmdShow
){
MessageBox(NULL,_T("Kitty on your lap"),_T("メッセージです"), MB_OK);
return 0;
}
こうやってうにこーどにしなきゃ駄目
251 :
249 :2008/04/27(日) 23:35:05
あ、#include <tchar.h>を追加するの忘れてた
252 :
デフォルトの名無しさん :2008/04/28(月) 00:15:18
>>246 返答ありがとうございます。
でも、先の例だとTに何が来ても、func()はbaseクラスに必ず存在すると思うんですが、、、
違いますか?
フリー関数というのは、baseクラスやderiクラスの外部にある関数ということですよね?
>>252 T内でtypedef 〜 func
とかやってる可能性もあるから。
質問です。 テンプレートクラス内で、別のテンプレートクラスを使用する時にエラーが出ます。 例: template< class TYPE > class List { // Listに使うメソッドなど }; template< class TYPE > class AAA { public : List< TYPE > m_List; // ←エラー }; 凄く初歩的な質問かもしれませんが、何が悪いんでしょうか?
どんなエラーが出るんだよ
>T内でtypedef 〜 func ごめんよく読んでなかった。間違い
258 :
246 :2008/04/28(月) 00:29:08
>>252 template<> class base<int> {};
259 :
223 :2008/04/28(月) 00:29:30
typename List<TYPE> m_LIST; でどうよ?
>>256 すいませんちょっと違いました。
例:
template< class TYPE > class List
{
// Listに使うメソッドなど
};
template< class TYPE > class AAA
{
public :
function() { m_List.Add( new T ); } // ←「m_List」は宣言されていません
List< TYPE > m_List;
};
って感じにエラーが出ます。
>>258 やってみましたが、やっぱりエラーが出ます。。。
だから、どんなエラーが出るんだよ
説明が・・・orz
function() { m_List.Add( new TYPE ); } の間違いです。
>>258 エラーは、「m_Listが宣言されてません」と出ます。
また、この例ではメソッドをクラス内で書いてありますが、
実際にはクラス定義のすぐ下で、
{
〜〜〜クラス定義
};
templeate< class TYPE > typename
class AAA::function()
{
m_List.Add( new TYPE );
}
のような感じでヘッダーファイルに記述してあります。
>>261 C2065 m_Listは定義されていない識別子です。
とでます。
264 :
デフォルトの名無しさん :2008/04/28(月) 00:47:33
>>260 g++ ならそのまま普通に通る。VCの場合は知らんけど
g++ -ansi -pedantic
でも通るからC++標準からみて問題はなさそう。
問題が再現するソース作ってコピペし、VC++使いに見てもらうのが良し。
すいません、単純に「m_List」に当たる名前を間違えてましたorz 本当にすいません; お騒がせしました。
あと回答してくださってありがとうございました。 もう少し勉強してからまた来ます;
もう来なくていいように勉強してください。
269 :
デフォルトの名無しさん :2008/04/28(月) 00:57:53
>>257 >>258 ありがとうです。
テンプレートの特殊化があるために、baseクラスの定義が信用できないということですね?
270 :
デフォルトの名無しさん :2008/04/28(月) 02:46:37
メモリダンプツール作りたいが手順がよく分らない。。。 プロセスIDの指定→メモリ上の位置の取得→指定されたサイズだけデータを読み込む→ファイルに保存 といった感じかな??メモリ上の位置の取得とデータの読み込みの方法が分らない。。。。 誰かサンプルコードを書いてくれ。いや、サンプルコードを提供して頂けないでしょうか? よろしくお願いします。
自分で作るよりソフトを探した方が早そうだけど
272 :
デフォルトの名無しさん :2008/04/28(月) 03:01:29
>>271 ツール自体は持ってるんですけど、どんな風に動作してるのか、動作原理に興味があって質問しました。
邪魔になるようだったら以降控えます。すみませんでした。
273 :
デフォルトの名無しさん :2008/04/28(月) 03:13:10
すみません。OSはXPです。
274の脳内にはOSと言えばWindowsしか存在しないようだ。 それはともかくReadProcessMemory。 あとOpenProcessも必要になるかな。
276 :
デフォルトの名無しさん :2008/04/28(月) 04:36:53
質問ばかりですいません。 テンプレート化されたクラスは、特殊化すれば中身は全然違うクラスになりうるということですよね? どうしてこんな仕様になっているのでしょうか?特殊化する際は、インターフェイスは特殊化する前の ものと同じにしないとだめ、という仕様の方がよっぽど自然な感じがするのですが、、 なんかいいことがあるんですか? template <typename T> class base { public: int a; }; template <> class base<int> { public: void a() { std::cout << "aaaa" << std::endl; } };
すいません、最近C言語を始めた初心者です。 Borland C++Compilerとbcpadがあればcとc++の開発はだいたいできますか?
gccとVisual C++ Expressを勧める。
C++(またはC++0x)の規格に完全に準拠したコンパイラはありますか。exportとかも使えたり。 その代わりpragmaが一切ないとか、実用性0でもいいです。
280 :
デフォルトの名無しさん :2008/04/28(月) 10:55:20
内部にファンクタへのポインタを持っているクラスがあるとして、そのクラスからファンクタを呼び出すときは、 operator()(引数)と書かなくてはならないですか? class aaa { public: functor* fp; }; class functor { public: int operator()(int); }; aaa A; A.fp->operator()(10); // これはコンパイルできる A.fp(10); // これはできない。 これはしょうがないですか?
これでは駄目? class A { public: int m; A(){m=0;} A(int n) {m=n;} }; class B { public: A *p; B(int n){p=new A; p->m=n;} }; main(){ B z(10); }
functor& rf = *A.fp; rf(10);
(*A.fp)(10)
aaaのoperator()(int)からfp->()(int)呼べばいいんじゃね
>>276 メタプロにおけるテンプレート特殊化というのは、通常プログラミングの
文脈で言う条件分岐(switch)にあたる。
実利的には、特殊化が無いとboostライブラリの大半が実現できなかったり
能力が落ちたりする。
boost/utility/enable_if.hppなんかは何やってるか解りやすいと思う。
>>279 export が使える、準拠率の最も高いコンパイラとして知られているのは Comeau C++ だな。
#include <stdio.h> main() { printf("hello!"); return 0; } をコンパイルしてできたexeファイルをダブルクリックしてもコマンド プロントっぽいのが一瞬でて消えてしまいます コマンドプロントからhello.exeで使用するとちゃんとhello!と表示されます 前者のほうはOSが壊れていたりするからですか? 不安なのでアドバイスください;;
コマンドプロンプト用のプログラムをダブルクリックで起動した場合は プログラムが終了するとコマンドプロンプトも一緒に終了する。 そういうもん。
>>288 ありがとうございます
自己解決しました
氏ね
おいおい、とんでもない発言してやがるな…。
292 :
デフォルトの名無しさん :2008/04/28(月) 20:29:26
>>285 みてみましたが、使い方とかがよくわかりません。ソースも中身がカラで無意味そうに見える(けど本当は意味があるんだろう)テンプレートばっかりで
ピンと来ませんでした。とりあえず
boost.org/libs/utility/
でも見てみます。あと、メタプログラミングを知れば利点がわかるということですか?
ありがとうございました。
実際に使えば納得できるよ
>>290 >>291 ごめんなさい、コンパイルしないで書き込んじゃいました
コンパイルしたらまた書き込みます
今まで学校でC++やってたんですが、家でやろうとVC++9.0インストールしたら単純なプログラムもコンパイル出来ません(Тωヽ) error C4430ってのが出て、もう意味不明です。どういう事なんでしょう?
顔文字貼る余裕があるならソースくらい貼ろうよ…
>>295 オマイが今まで書いてきたプログラムはC++のような何かだったってこと
>>296 #include<studio.h>
main()
{
}
これすらコンパイル出来ません…
ミス <stdio.h>
int main() { }
学校に騙されてたんだな 「C++はintを既定値としてサポートしていません」とか書かれてないか?
#include <stdio.h> int main(void) { return 0; }
拡張子を.cppから.cに変更する
出来ました。ありがとうございますm(__)m
>>301 書いてあります。
>>304 次からはそういう大事な情報を隠さないでくださいね
>>292 これならわかるだろうか?
template<class X, class Xs>
struct List;
struct Nil;
template<class Xs, class X>
struct Cons
{
typedef List<X, Xs> type;
};
template<class Xs, class X>
struct Append;
template<class X, class Xs, class Y>
struct Append<List<X, Xs>, Y>
{
typedef Cons<X, typename Append<Xs, Y>::type> type;
};
template<class X>
struct Append<Nil, X>
{
typedef typename Cons<X, Nil>::type type;
};
308 :
デフォルトの名無しさん :2008/04/29(火) 06:10:13
>>307 ありがとうございます。でもmain関数が書けません(泣)
簡単でいいですから、main関数も書いてもらえませんか?
int main(){return 0;}
310 :
デフォルトの名無しさん :2008/04/29(火) 07:39:34
はじめまして質問させていただきます。 class MyShip{ private: float x; float y; public: void GetMyShipLocation(float* X,float* Y); void SetMyShipDefault(); void MoveMyShip(int keybordstate); }; void GetMyShipLocation(float* X,float* Y){ *X = x; *Y = y; } GetMyShipLocation関数を使って、描画関数に値を渡したいのですが、 値がぶっとんでしまい、-107374176.000000と表示されてしまいます 自分ではもう訳がわからなくなってしまいました。解決方法をご教示願います。
メンバのx,y初期化した?
はい。 SetMyShipDefault関数を初回に動かして、 x = -55.0f; y = 100.0f; という値を入れています。
>>311 色々とダメすぎ。C++を真面目に勉強することをお勧めする。
それはさておき、「描画関数」と「値を渡す」ところと、「値がぶっ飛んでしまう」ところのソースを晒せ。
[値を渡す場所] VOID GameBody( HWND hWnd ){ FPS_NOW = timeGetTime(); if(FPS_FLAG < 0){ FPS_FPS = 1000/(FPS_NOW-FPS_LAST) ; FPS_FLAG = 20 ;} else{FPS_FLAG--;} int keystatus = getKeybordState( g_pKeyboard ); char bill[256]; sprintf( bill, "%f %f %.02f" , g_Billbord[9].objPos.x , g_Billbord[9].objPos.y , FPS_FPS); if(g_FullScreenFlag == FALSE){SetWindowText( hWnd , bill );} switch(GameFlag){ case GAME_STANDBY: MyShip Player; Player.SetMyShipDefault(); GameFlag = GAME_START ; break; case GAME_START: //Player.MoveMyShip(keystatus); Player.GetMyShipLocation(&g_Billbord[9].objPos.x , &g_Billbord[9].objPos.y ); break; } FPS_LAST = FPS_NOW; return; }
謎の関数とか定数とか多すぎ DxLibって奴か?
ダメだこりゃ。
-107374176は0xccccccccだから vcのデバッグビルド時の未初期化変数の値と一致する
とりあえず、メンバの初期化はコンストラクタでやろうね
case GAME_STANDBY: MyShip Player; どう見ても原因はここだろ
そんなんでコンパイル通るんだ…
スコープがまったく理解できてないの?
>>320 その通りでしたorz
すみません、自分でもすっかり見落としてました。
回答してくださった皆様、お手数おかけしました。
自分でもまさかそんな事は無いだろうと、GameBody側のソースを全く見直してませんでした。 久々に寝ることにします・・・。
エラー出るんだけどなぜですか? #include <stdio.h> main() { int c; scanf("%c", &c); printf("%c", c);[ return 0; } エラー E2188 001.cpp 8: 式の構文エラー(関数 main() )
その[なにw
328 :
325 :2008/04/29(火) 22:37:25
あ・・・ すいません;; ありがとうございました
329 :
デフォルトの名無しさん :2008/04/30(水) 02:41:59
すいません、質問したいのですが・・・。 VisualStudio2005でライブラリを作りたくて色々試行錯誤してみたのですが・・・。 いまいちよくわからない状態でして。 用途についてですが、自分は学生でゲームを作っています。 言語では DirectX OpenGL を使っています。 それに自分で使いやすいようにライブラリを作るつもりで調べてみました。 どうかやさしくおねがいします・・・・。
>言語では >DirectX >OpenGL >を使っています。 やさしく突っ込むと意味不明。 まずは自分の使ってる言語がCかC++のどちらなのか、 DirectXとOpenGLのどちらのライブラリを使うつもりなのか 基本的な部分を書くべきだと思う
Dark GDKはDirectX9cフルサポート。マイクロソフトVS2008/VC++のオプションとして無料配布。 初心者を強く意識した設計になっているので、あとは日本語の入門書でもあれば、小学生がひとりで、 3Dゲームを作ってしまう、なんてこともできそうです。もともと DarkBasic というホビーユーザー向けのゲーム開発ツールがあって、 その開発スタイルを C++ に持ってきたのが DarkGDK ということらしいですが、悪くありません。
新しいプロジェクトの作成 ↓ Win32プロジェクト ↓ スタティック ライブラリ ↓ int.cppに int test ( int a ){ return ( a ); } ↓ ビルド ↓ フォルダにlibが生成
↓ libをVisualStudioのlibフォルダに入れる ↓ 新しいプロジェクトを作る ↓ リンクさせる ↓ int main ( void ) { int a = 10; a = my_print ( a ); printf ( "%d", a ); return ( 0 ); } でerrorがでました・・・。 そもそもmy_printが使えてないので、libがだめなのか、リンクがだめなのか。。。 その次元でわからないのです。。。
>>321 ありがとうです
>>332 すいません、説明が不十分でした。
DirectXかOpenGLでゲームをつくり、ライブラリはC++をつかっています。
あ、ライブラリがDirectXかOpenGL です。 あほだ俺・・・
>>336 それだと my_print が存在しないんじゃね?
DirectXかOpenGLのどっちを使うんだよ まだ決まって無いってことか?まずそこから選べよ
>>339 うぉっと、すいませんmy_printじゃなくってtestです・・・
ごめんなさい
errorが出たならそのエラーを貼付けろ
>>341 #pragma comment(lib, "ほにゃらら.lib")
とかやってみては?
>>340 DirectXでやると思うんですが、OpenGLでもつくるつもりです。
>>342 失敗した後色々弄ったので廃棄してしまったんで・・・
もう一回やり直してエラー貼り付けます
>>343 やってみたんですが駄目でした
ヘッダをインクルードしてなくてコンパイルエラー出てるんじゃないの
まずはエラーをよく読むクセをつけないと駄目だな 最近のコンパイラは日本語で懇切丁寧に解説してくれるだろ
VCならMSDNでエラー番号で調べれば説明もあるし
#include <stdio.h> #pragma comment(lib, "test.lib") int main ( void ) { int a = 10; a = test ( a ); printf ( "%d", a ); return ( 0 ); } エラー test 識別子が見つかりませんでした
>>349 関数プロトタイプを含んだヘッダはどこ?
C++としてコンパイルしているなら必須
>>351 prototypeのヘッダ・・・
もしかしてtestのprototypeをヘッダで宣言している必要があるということでしょうか。
全くやってないです
>>352 これでどう?
#include <stdio.h>
#pragma comment(lib, "test.lib")
int test ( int a ); // <- これ追加
int main ( void )
{
int a = 10;
a = test ( a );
printf ( "%d", a );
return ( 0 );
}
>>352 やってみました
test.libを開けませんでした
とエラーが吐かれました
test.libのあるフォルダにパスが通ってないだろ
357 :
デフォルトの名無しさん :2008/04/30(水) 03:27:32
>>356 ソリューションエクスプローラのプロジェクトを右クリック → プロパティ
リンカ → 追加のライブラリ → libを入れたフォルダを指定
じゃだめなんでしょうか
だあーーーー。 すいません、本当にすいません。 作成したlibが test2.lib でした・・・・ 吊ってきます
359 :
デフォルトの名無しさん :2008/04/30(水) 04:44:23
だれか307のカキコに、テンプレート使ったカッコいいmain関数をつけてください お願いします。
自己解決しました
http://i-get.jp/upload500/src/up16228.txt 基数計算のプログラムを書いて来いという宿題が出たのですが何度コンパイルしてもエラーが出てしまいます・・。
直しかた教えてください;;
エラー 1 error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました。 MSVCRTD.lib c++001
エラー 2 fatal error LNK1120: 外部参照 1 が未解決です。 C:\Documents and Settings\igumasatosi\My Documents\Visual Studio 2008\Projects\c++001\Debug\c++001.exe 1 c++001
基数変換のプログラムでした 連投すいません
h抜き忘れた・・・ 樹海行ってきます・・・ ごめんなさい
main()の部分を、 int main(int argc, CHAR* argv[]) か int wmain(int argc, WCHAR* argv[]) に置き換えても通らない?
だめみたいです;;
エラーメッセージも変わってないのかな? いっそのこと「Win32コンソールアプリケーション」 で新しくプロジェクトを作っちゃって、 最初から書いてある int _tmain(int argc, _TCHAR* argv[]) の中にmain()の中身をコピペしてしまったほうが早いかもしれん。
VC++ 9.0だが正常にコンパイルできた。バージョンによるのかもね。 それともどこか書き間違えてるとか? どうでもいいが、ユーザー名・・・・ igumasatosi さんw
ここまでスルーしてたのにw
>>368 なるほど、ありがとうございます
もうちょいがんばってやってみます。
ユーザ名^^; うっかり^p^
あ、Visualstdioでやったらだめだったけど BCCでやったらできました 連投失礼しました
>>359 少しの修正を加えて
template<class X, class Xs> struct List {};
struct Nil {};
template<class X, class Xs>
struct Cons
{
typedef List<X, Xs> type;
};
template<class Xs, class X>
struct Append;
template<class X, class Xs, class Y>
struct Append<List<X, Xs>, Y>
{
typedef typename Cons<X, typename Append<Xs, Y>::type>::type type;
};
template<class X>
struct Append<Nil, X>
{
typedef typename Cons<X, Nil>::type type;
};
↓つづく
つづき #include <iostream> #include <typeinfo> typedef Append<Nil , unsigned char >::type UC; typedef Append<UC , unsigned short>::type UCS; typedef Append<UCS , unsigned int >::type UCSI; typedef Append<UCSI, unsigned long >::type unsigned_ints; void print(std::ostream& s, Nil) {} template<class X, class Xs> void print(std::ostream& s, List<X, Xs>) { s << typeid(X).name() << std::endl; print(s, Xs()); } int main() { print(std::cout, unsigned_ints()); return 0; }
374 :
デフォルトの名無しさん :2008/05/01(木) 03:57:25
>>373 すげえ、まだみたばかりで内容はよくわからんけど、勉強させてもらいます。
ありがとうス。
Visualなstdio・・・
コンソールアプリ選択してなかったって意味だろ
stdio.hをstudio.hって書く人はよく見るけど、 Visual StudioをVisualstdioなんて書く人はじめてみたよw
>378 ごめん、なんか胸が痛い…… もう何年も前なのに……。
380 :
厨房 :2008/05/01(木) 14:38:31
1)下の実験プログラムでWaitForSingleObject関数から抜けなくなります。 2)Sleep(1000) が無いとプログラムは最後まで通ります。 環境はVC++6.0です。 理由がわかる方、原因をお教えください。 ------------------------------------------------------------- #include <windows.h> #include <process.h> #include <stdio.h> #include "resource.h" int isContLoop; HWND hDlg; unsigned __stdcall thFunc(void* arg) { while(isContLoop) SetWindowText(hDlg, "string"); _endthreadex(0); return 0; } // 次に続く
381 :
厨房 :2008/05/01(木) 14:39:15
// 前の続き int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pchCmdLine, int iCmdShow) { HANDLE hTh; unsigned int idTh; // Create Dialog hDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL); ShowWindow(hDlg, SW_SHOW); // Start Thread isContLoop = 1; hTh = HANDLE(_beginthreadex(NULL, 0, &thFunc, NULL, 0, &idTh)); // Wait Sleep(1000); // Stop Thread isContLoop = 0; WaitForSingleObject(hTh, INFINITE); CloseHandle(hTh); return 0; }
382 :
厨房 :2008/05/01(木) 14:41:50
補足 3)SetWindowTextを使わないと、プログラムは最後まで通ります。
Sleep してる間にもの凄い勢いで SetWindowText を実行しようとして 何か変な事が起こってるんじゃなかろうか。
他スレッドが作ったウィンドウに対して、SendMessage系使うとデッドロックの可能性がある PostMessageを使うのが良い
別スレッドからSetWindowTextしても問題ないんだっけ
ttp://msdn.microsoft.com/en-us/library/ms633546.aspx > If the target window is owned by the current process,
> SetWindowText causes a WM_SETTEXT message to be sent to the specified window or control.
SetWindowTextはWM_SETTEXTをsendしようとするが
ダイアログを所有するメインスレッドがメッセージを受け取れる状態ではないので
SetWindowTextから返って来なくなる。
メインスレッド→WaitForSingleObjectで待つ(メッセージを受け取れる状態ではない)
別スレッド→メインスレッドがメッセージを処理するのを待つ
となり、デッドロックに陥る。
Sleepを抜くと通るのは、スレッドがwhileループに入る前にisContLoop = 0;が実行され
SetWindowTextが呼ばれないため。
ttp://msdn.microsoft.com/en-us/library/ms644927.aspx この辺読むといいよ。
387 :
厨房 :2008/05/01(木) 16:47:21
>>386 ご回答ありがとうございます。
やっと理由を理解できたような気がします。
このようなスレッドの終了法を未だ自分で思いつくことができないのですが、
とりあえずあるサイトに提示されていた下記の方法を参考にさせていただきます。
ご提示いただいたサイトやヘルプを元に改めて勉強しなおします。
------------------------------------------------------------
// メインスレッド側
MSG msg;
// 正常にWaitForが終了するまで最大50msecづつ待つ
while(WAIT_TIMEOUT == WaitForSingleObject(hTh, 50))
{
// おそらくタイムアウトになるので、
// 立ち上げたスレッド内でSendMessageされていた?メッセージを適当に処理する
GetMessage(&msg, NULL, 0, 0);
if(!IsDialogMessage(hDlg, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
for (;;) {
const DWORD r = MsgWaitForMultipleObjects(1, &hTh, FALSE, INFINITE, QS_SENDMESSAGE);
if (r == WAIT_OBJECT_0 + 1) {
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
}
else
break;
}
こういう方法もある。
ttp://msdn.microsoft.com/en-us/library/ms644927.aspxのMessage Deadlocksに書いてあるけど
PeekMessageを呼ぶとSendされてたメッセージを処理できる。
389 :
デフォルトの名無しさん :2008/05/01(木) 22:16:34
デストラクタをバーチャルにしろ、って言うけど、 Aクラスを継承してBクラスを作った場合、 B* b = new B(); A* a = b; delete a; で、Aクラスのデストラクタが呼ばれる代わりに Bクラスのデストラクタが呼ばれるのだよな? でも、ちゃんとインスタンスが消滅するには、 Bクラスのデストラクタが呼ばれた後、Aクラスのデストラクタが 呼ばれないといけないのじゃない? 結局、デストラクタをバーチャルにしても、 よく本に書いてあるような、その目的を達成することが出来ない 気がするのだが、違うのか?
Bのデストラクタが呼ばれた後にAのデストラクタが呼ばれるのはもちろんのことだよ。
> Bクラスのデストラクタが呼ばれた後、Aクラスのデストラクタが > 呼ばれないといけないのじゃない? ちゃんとそうなってる
B のコンストラクタが呼ばれる前に A のコンストラクタが呼ばれるのと同じくらい当然に B のデストラクタが呼ばれた後に A のデストラクタが呼ばれる。
393 :
厨房 :2008/05/02(金) 02:39:42
>>388 ありがとうございます。
大変参考になります。
デストラクタをvirtualにしてないと、基底クラスのポインタに 派生クラスを突っ込んだときの後始末で、基底クラスの デストラクタしか呼ばれないから。 派生クラスがこういう使い方をされないのなら、virtualに しなくても問題ない。
>394 デストラクタの呼び出しは特別だ、て話だと思ってたけど。 基底ポインタからの呼び出しに関して、 ふつーの仮想メンバ関数は、「派生のみ」しか呼ばれないけど、 仮想デストラクタは「派生」のあとに「基底」も呼ばれる、みたいな。
A のデストラクタが呼ばれなかったら { B b; } でも困ることになるよなー、と。
>>395 派生クラスのデストラクタの終わりに基底クラスのデストラクタ呼び出しが
自動挿入されてるみたいな感じだから、呼び出すこと自体は普通のvirtual関数と
同じ扱いですよね
398 :
デフォルトの名無しさん :2008/05/02(金) 19:23:55
wchar_t ***buffer; buffer[y][x] = new wchar_t[3]; 質問です。上記のようにnewでメモリを確保しようとすると、 6つぐらい余分に確保してしまうのですが、何が原因でしょうか? 環境はVC++です
初心者も上級者も vector<string>やvector<wstring> つかう
buffer = new wchar_t**[ysize]; for(int y = 0; y < ysize; ++y) { buffer[y] = new wchar_t*[xsize]; for(int x = 0; x < xsize; ++x) { buffer[y][x] = new wchar_t[3]; } }
>>400 それは398も既にやっているんじゃないの?
やっていないとしたら、アクセス違反で落っこちるって質問になるはず。
>>398 適当なことを書くと
4byte が new で確保したサイズ
6byte が自由にアクセスできる領域
2byte がアラインメント
ただし、根拠は無いので信用するなよw
どうやって監視してるのかどうかしらんけど
デバッグ用に先頭と末尾にマジックナンバー埋め込んでる可能性もある
どうやってチェックしたかと、デバッグ版かどうかの情報が欲しいな。
404 :
398 :2008/05/02(金) 21:05:26
みなさんどうも。 newした直後にブレークポイントを設置してみた結果、 buffer[y][x] = "???######gg" と見られますし、またwcslen(buffer[y][x])で長さを調べても 上記の余分な配列幅が観測できました。 ※ ?は想定している数の分、#は四角の絵文字で6つぐらい。
405 :
398 :2008/05/02(金) 21:07:12
追記 コンパイルはReleaseではなくDebag、 VC++は2008Expressです。
まあ、初心者のうちは、 最初からちゃんとやったことを話すことだね。
>>404 wcslen でどうやって確保したメモリの長さを調べられるんだ?
まあそれはいいが、デバッグ版の場合はバッファオーバーランを検知するために
前後に余分にメモリを確保し、そこを特定のデータで埋めるようになっている。
フフフフフフwww
それは初期化されていない変数に埋められる値だな。 確か前後を埋める値はそれとは別だったと記憶している。
DEADBEEF
412 :
398 :2008/05/02(金) 21:36:40
int m_Col=m_Row=0; void fReadData() { char c; int row = col = 1; fstream stream; // [1][1][0] vector<vector<vector<char>>> buffer; buffer.resize(row);buffer[row-1].resize(col);buffer[row-1][col-1].clear(); stream.open(m_FileName,ios::in | ios::binary);if(!stream.is_open()) { return; } while(!stream.eof()) { stream.get(c); if(c == EOF) { return; } if(c == ',') { col++; buffer[row-1].resize(col); } else if( c == '\r') { // \nだと余計なスペース入っちゃうから m_Col = max(m_Col,col); row++; col = 1; buffer.resize(row); buffer[row-1].resize(col); } else { buffer[row-1][col-1].push_back(c); } }
413 :
398 :2008/05/02(金) 21:38:43
m_Row = max(m_Row,row)-1; m_Col = max(m_Col,col); char sb[2]; wchar_t wb; int sBuf; m_String = new wchar_t**[m_Row]; for(int y=0; y<m_Row; y++) { m_String[y] = new wchar_t*[m_Col]; for(int x=0; x<m_Col; x++) { int size = (int)buffer[y][x].size(); // ワイド文字の字数とANSIの字数の差異を調整 int wSize = size; for(int i=0; i<size; i++) { if(IsDBCSLeadByteEx(CP_ACP,buffer[y][x][i])) { wSize--; } m_String[y][x] = new wchar_t[wSize];
414 :
398 :2008/05/02(金) 21:42:55
良く考えれば長々と見せても鬱陶しいだけか・・・
>>407 が答えかも。
作ろうとしていたのはCSVの文字列を格納する関数です…。
悪い事言わないから vector< vector<wstring> > 使おうぜ。 delete し忘れて泣きたくないだろ?
>>414 実装やOSの都合上、指定したサイズ以上確保される事があるが
そんなことは気にする必要ないし、それを期待して書いてもいけない。
>>415 まぁ、基礎知識として知っといた方が良いだろう。
使うのはvectorで良いけど。
すみませんが、質問させて頂きます。 fgets( buf, 256, stdin ); で入力を取りたいのですが、コンパイラがgccだと 何故かこの処理が華麗にスルーされてしまいます gccだと使えないんでしょうか? gccはcygwinに入っていたのを使ってます
普通に使えるけど fgets(buf, 256, stdin); ちなみに gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) だよ
それはないと思います その問題を再現する簡単なコードとgccのバージョンを
レス有難うございます。
gccのバージョンですが
>>419 さんのと全く同じです
問題のソースですが、少し長いのでその部分だけを抜粋しますので
改めてレスさせて頂きます
問題のコードです #include <stdio.h> main( ) { char buf[256]; int i; scanf("%d",&i); rewind(stdin); fgets(buf,256,stdin); printf( "%s\n", buf ); } このコードでfgetsがスルーされてしまいます
>>422 fscanf の %d の後にスペースを1つ入れると良いでしょう
理由は調べてください
てst
>422 まず、これ↓ rewind(stdin); は無いだろw それから、scanf()を止めて、fgets()+sscanf()にしてみてはどうだろう? ※想像だがscanf()への入力に[Enter]していると思うんだが、そいつが次のfgets()にひろわれていると思われ
いいか、ここで間違ってもEOFがどうとか言うんじゃないぞ。判ったな。
>>423 有難うございます。まだ試してはいませんが、調べてみます
>>425 getchar( );
を実行すると改行コードが残るので
rewind(stdin);として、stdinを先頭に持っていくと
次回からgetchra( )でとれたもので・・・
このコードはgcc以外では動作しましたので安心していましたorz
確か stdinをrewindすると内容はクリアされると記憶してたけど ちょっと調べてみたら コンパイラに依存するみたい VC, BCはクリアするみたいだけど、gccは何もしない そのため、rewind(stdin)->単純にポインタが先頭に移動するだけなのでfgetsで拾われていると思われる
>>428 生半可なことを書くとまた変な人が沸くから要注意。
標準入力をrewindしても、(対象がブロックデバイスでないから)巻き戻しは発生しませんよ。
>>429 指摘サンクス
stdinをrewindしても、stdin自体が移動するわけではないんだな
VCとかではrewind(stdin)でバッファをクリアされるけど、gccでは何もしないから
クリアされずに次にfgetsで拾われているに訂正します
蛇足ながら、ファイルにリダイレクトすれば、きちんと巻き戻しするけどね。
ファイルにリダイレクトされてるかどうかを判別する 規格準拠コードって書けるの?
>>432 AnsiCではファイルシステムに依存する関数は極力排除する方針なので書けない。
POSIXなら、isatty()で判る。
ちょっとした疑問なのですが、C++で自作クラスなどに演算子を定義することを 演算子オーバーロードと言いますよね。オーバーロードは多重定義という意味 なのに、どうして多重に演算子の定義をしない時でもオーバーロードと言うのでしょうか。 単に演算子の定義で良いような気がするのですが。
演算子てのは組み込みかつグローバルに既に定義されてるじゃん? それをユーザー定義型に適用するためにオーバーロード(多重定義)するんじゃん?
int operator+(int, int) double operator+(double, double) : : と沢山オーバーロードされている演算子の定義に さらに定義を追加するから演算子のオーバーロード。 まあ、単に演算子の定義でいいような気もするけど。
演算子の「上書き」のニュアンスがあるからじゃないかな。 まぁ、日本人にゃoverloadとoverwriteとoverrideの微妙な違いなんて判らないよね。
439 :
435 :2008/05/03(土) 20:47:25
>>436 ,437
レス有り難うございます。
なるほど、と思いましたが、グローバルに定義する他にクラスのメンバとして
定義する場合もありますよね。
メンバとして定義しようが定義を追加する事に変わりはない。
441 :
435 :2008/05/03(土) 21:00:39
>>440 ああ、なるほど。
「演算子」と「普通のメンバ関数」の違いを意識すると、確かに多重定義ということになりますね。
すっきりしました。レスして下さった方、ありがとうございました。
本読み見ながらC++勉強してるんですが、2元配列の初期化がよくわからないのですが ループ処理でChar型の2元配列を初期化するとき、どのような記述を行えばいいのでしょうか? VC++のスレに、間違えて書いてしまった・・・OTL
一口に初期化と言われても、いろいろあるわけで。
char[][2] ={"a","b","c","d"}; char型ってことはこういうことか?
>>443 入力された年・月のカレンダーを出すプログラムを書いてみようと思ったんで
5*7の配列に対して一度0書きしようと思ったんですが、全てに0書きするために
for文を以下のように書いてみたんですが
for ( r=0; r<5; r++){
for ( c=0; c<7; c++) {
cal [ r ] [ c ] = '0' ;
}
}
これじゃ、だめみたいなんです。
int r, c;
char cal [ 5 ] [ 7 ];
と、宣言しています。
何が駄目だったんだろう というかカレンダーを作るのに5*7で足りるんだろうか
>>446 初期化した状態でとりあえず(0, 0)を呼び出すとメモリーエラーで落ちます。
一月最大五週じゃないですか・・・ね?一週間七日なのは、固定ですし。
>>445 間違いすぎのような気がする
あなたの質問力では正解にたどり着くのに手間が掛かりすぎるだろう
落ち着いて本をよく読んだほうが早い
カレンダーをよく見るのが先だろ
延々と読んでるけど、そう理解したのが間違ってるのか・・・orz いくつ進んだのか?だから実際、6*8確保してて8列目は\0書きさせて 7以下の時だと、実質的8列目は初期化されませんね。
そもそも、一ヶ月は最大6週必要だし一日一文字じゃ表示できない。
>>452 最大6週必要という意味が分かりません。
31日なら最大五週ではないでしょうか?
何もない一週間がない限り6週にならないと思うんですが。
万年カレンダーなら必ず5行で足りるよね。
>>447 つきのコードを私の環境で実行してみましたが、特に問題はありませんでした。
実行環境:WindowsXP/cygwin, 処理系 gcc 3.4.4
#include <stdio.h>
int main() {
int r, c;
char cal [5][7];
for (r = 0; r < 5; r++)
for (c = 0; c < 7; c++)
cal[r][c] = '0';
printf(">%c\n", cal[0][0]);
return 0;
}
実際に問題のあるコードを見せていただければ、なにか問題がわかるかもしれません。
0 クリアならこれでおkだろ。 char cal[5][7] = { 0 }; あるいは char cal[5][7]; memset(cal, 0, sizeof cal);
メモリエラーで落ちるなら初期化以外の場所が問題だろ 0クリアの方法を複数知ったところで意味がない まずはカレンダーがどんなものだったかを思い出すのが先だと思うが
>459 違う気はするが、とりあえず今は関係ないからいいんじゃね?
大抵の場合同じだと思っちゃって良いと思うけどな。
0x00じゃねーの?
うん。48ぐらい違うな。
465 :
デフォルトの名無しさん :2008/05/04(日) 00:56:44
ごめん、今ナチュラルに間違えた。
幻のバックスラッシュが見える人がいる
'0'と'\0'は全然別物だよね。
金に目がくらんだのか
うん。48ぐらい別物だな。
ソースファイルの分割ってどのような決まりに沿ってやってますか? たとえばクラスの系列ごとにとか機能郡ごとにとか
クラス毎に分割。 Cにはクラスは無いが、考え方は同じで。
ちょっとしたプログラムのはずなのにクラスの数が膨れ上がって ソースファイルの管理も面倒になってきたのでどうしたものかと・・・
単純にJavaみたいに1クラス1ファイルにしとけば
フォルダや名前空間を分ける
むしろとりあえずetagsか何か導入したら?
マルチスレッドのプログラムで 無限ループしてるスレッド関数を終了させるにはどうするのが良いでしょうか? やはりクラス化してメンバ変数に終了フラグを用意してあげるのが無難ですかね
ヴぉぁちぇ も忘れずに。
>>480 最適化抑制ですか
最適化抑止といえばイマイチ何処を最適化抑止していいのかわからんのです
別スレッドから変更される変数に。
volatle ってクラスや構造体につけると 中身全部の抑止してくれるんだっけ? あとポインタに付けた場合はポイント先も 抑止するんでしたっけ?
してくれる。 ただ、volatile クラスや構造体には面倒くさい話があって、 volatile オブジェクト用のコピーコンストラクタや代入演算子が自動的に生成されないので 自分で作らなければならないのと、 volatile メンバ関数か const volatile メンバ関数しか呼ぶ事ができないという制約がある。
Releaseとdeleteの違いって何かあるんですか?
Releaseとやらが何なのかによる
コンパイラの最適化がどのようなところに働くのかイマイチ判らん どういうシーンで抑止しておけば良いの?
488 :
デフォルトの名無しさん :2008/05/04(日) 17:50:31
C/C++ でオーバーフローを検知する手段は用意されているのでしょうか? 調べてみてもよく分りません。 あと、オーバーフローが発生しないことがほぼ確実に保証されてるとき、 if( a と b が等しいとき) return 1; を if( オーバーフローが発生していないとき) return 1; に書き換えても問題ないような気がします。実際にこのような書き換えをおこなったとき 発生しうる問題はどのようなものが考えられるでしょうか? お暇な方いましたら、ご回答のほどお願いします。
>>487 最適化 抑制 volatile あたりで検索すると、例が幾つか出てくると思う。
490 :
デフォルトの名無しさん :2008/05/04(日) 18:17:15
このプログラムってちゃんと解放されてますか? class Test{ int x; public: Test(int x){ this->x=x; } ~Test(void){ delete this; } }; Test *New(int x){ return new Test(x); } void main(void){ Test *data; data=New(20); }
>>488 C/C++ の範囲ではオーバーフローを検知する手段はない
浮動小数点なら処理系が関数を用意しているかも知れない
前の if と後の if では意味が違うんでは?
492 :
デフォルトの名無しさん :2008/05/04(日) 18:38:16
>>491 > C/C++ の範囲ではオーバーフローを検知する手段はない
なるほど、そうですか。分りました。
> 前の if と後の if では意味が違うんでは?
そうですね。
if( a と bが等しいとき)
{
return 1; // 入力されたパスワードが正しいものとする
}else{ exit(-1); // 入力されたパスワードが間違っているので終了 }
を
if( オーバーフローが発生していないとき)
{
return 1:
}else{ exit(-1); }
としたとき何か問題はあるかな?条件を書き換えて常にフラグが立つ(立たない)ようにしてやれば
パスワードチェックが意味をなさなくなるかな?かな?というのが疑問。
>>490 そのデストラクタはいつ呼ばれるのかね。
deleteしたときではないのかね。
>>490 入門サイトなどで「スコープ」「自動変数」「delete」「デストラクタ」について勉強。
>>492 オーバーフローが何か分かってる?
意味が分からないよ。
>>490 if(デストラクタが呼ばれる == 今まさに開放される途中){
デストラクタ内でdeleteする = 開放途中のオブジェクトを開放;
}
496 :
デフォルトの名無しさん :2008/05/04(日) 21:12:48
class Test{ int x; public: Test(int x){ this->x=x; } ~Test(void){ //delete this; そもそもこれは危険なコード } }; Test *New(int x){ return new Test(x); } void main(void){ Test *data; data=New(20); delete data; //デストラクタが呼ばれる Test data2(20); //こうした場合コンストラクタが呼ばれスコープを抜けると自動的にデストラクタが呼ばれる }
>>488 matherr(3M) が使えるはず、と思ってググったのですが、どうもうまくコンパイルできません。
何が間違っているのでしょうか?
>cat matherr.c
#include <stdio.h>
#include <math.h>
int matherr(struct exception *x) {
switch(x->type) {
case DOMAIN:
case SING:
printf("%s domain error %lf\n", x->name, x->arg1);
break;
default:
printf("%s range error %lf\n", x->name, x->arg1);
}
return 1;
}
int main() {
double x, y, z;
x = log(10.0);
y = sqrt(-1.0);
z = log(-10.0);
printf("%lf:%lf:%lf\n", x, y, z);
}
>gcc matherr.c -lm
499 :
498 :2008/05/04(日) 21:48:14
環境は cygwin/WindowsXP, gcc 3.4.4 Vine Linux 4.2/gcc4 です。
メソッド内で、引数に対して変更を加えない場合は、 引数に対して const修飾子 を付加すべきという説明を見かけて、 それ以来、上記に該当するメソッドは全て引数に const を付加しています また、クラスのメンバに変更を加えないメソッドは、 全てメソッド宣言の後に const を付加しています。 しかし、他所のソースを見ていると、 const をいちいち付けてるソースをあまり見かけません。 const を付けるソースって無駄な労力を費やしてるのでしょうか。 勉強不足で申し訳ありません、よろしくお願い致します。
>>498 普通に compile できるけど。出力は 2.302585:nan:nan で予想どおり。
matherr 定義して全然使ってないんじゃない? compile には問題ないはずだけど。
>>498 >何が間違っているのでしょうか?
「うまくコンパイルできない」のにエラーメッセージも書かない捻くれた根性。
>>500 基本的にプログラマは怠け者ってことと、通常教えたりする時には
const はかえって説明する事を増やすからそれを説明する時じゃ
なければ使わない事が多い。しかし const を使うのは決して無駄な労力じゃない。
実際 coding していれば compile error が出る事が事があるはずで
それから教えられる事はあるはず。安全のために付けましょう。
付けて悪いことはない。
>>501 エラー発生時にユーザーが定義した matherr() を呼び出さないのでしょうか?
私が挙げた例では、ソースに記述している matherr() にある、
printf("%s domain error %lf\n", x->name, x->arg1);
を実行したいのです。
>>500 引き数にconstをつけると、その関数内で変更することを防止できる。
逆に言えば、判ってて変更するなら別に制限する必要もないから書かない人が多い。
ポインタ参照先やメンバ関数に関しては、呼び出し側に対する制限なのでつける方がいい。
matherrはPOSIX標準じゃねーからLinuxではサポートしてませんから。残念。 ってぐぐったら出てきたけどホンマかな
>>502 私の語句が稚拙でした。
コンパイル自体は通り、エラーも warning もないです。
いや、間違いが無いようにconstつけたほうがいい
>>506 たしかに/usr/include/math.h を覗いてみると、「 SVID のもとで定義されている」みたいですね。
コンパイルしてもエラーにならないのに、使えないのは不思議なのですが。
_beginthreadの第一引数に仮想関数を取ることは可能でしょうか? 仮想関数のアドレスを取ろうとしました。 と怒られてしまうのでやっぱり無理なのでしょうか?
仮想関数もメンバ関数も無理です
マジですかorz
staticなメンバ関数ならおk
そういうのってクラス関数って言うのかな?なんて言うんだっけ・・
>>515 staticならOKですか・・・
純粋仮想関数を引数にとっていて
継承によって渡す関数を変えたかったのですが
staticならOKとなると結構変更が大きいなぁ
staticな奴にthis渡してそれ経由で呼び出すのが常道だろうに
大変部もないでしょ struct A { virtual void f() = 0; }; struct B : A { void f(){} }; void g(void*p) { ((A*)(p))->f(); } void h() { B b; _beginthread(f, 0, &b); } つまり、g を書けば良いだけ
>>517 void*型のデータを別に渡せるから、そこにthisを注入すべし
>>520 第3引数にthisを渡すんですよね
そうすると、今まで使ってた第3引数は別のメンバ関数でクラス内部に持たさないといけないか・・・
>>521 必要なら構造体を渡す手もあるぞ
struct ThreadData {
...
};
_beginthread(.., new ThreadData(...));
とやって、スレッド関数の中でデータをdeleteする。
boost::bindで生成した関数オブジェクトとか渡せたら面白いのにな・・・ え、そのためのboost::threadって?
>>523 boost:function渡せばいいんだから、余裕でできるでしょ。
こんなの考えた class ThreadCallback { public: template <class F> explicit ThreadCallback(const F& f) : f_(f) {} static void callback(void* arg) { const std::auto_ptr<ThreadCallback> callbacker(static_cast<ThreadCallback*>(arg)); callbacker->run(); } private: void run() const { f_(); } const boost::function<void ()> f_; }; struct Hoge { void f() {} } hoge; _beginthread(&ThreadCallback::callback, boost::bind(&Hoge::f, &hoge)); // Hoge のメンバ関数でスレッド作成 でもこれだと void () なメンバ関数しか渡せない・・・こういうことやってくれるライブラリってありそうだけど、どうやってんだろ
別に任意の関数をバインドできなくてもいいような。
527 :
デフォルトの名無しさん :2008/05/05(月) 12:00:43
スーパークラスと派生クラスがあるとき、派生クラスのコンストラクタからスーパークラスのコンストラクタを 呼び出す時、派生クラスのメンバ初期化を先に書くべきですか?それともスーパークラスの初期化を先に書く べきですか? super::super(int a); というコンストラクタがある時 hasei::hasei() : super(10), hasei_member1(10),... と書くべきか、 hasei::hasei() : hasei_member1(10), super(10),... と書くべきでしょうか? よろしくお願いします。
記述の順番に関係なく初期化順はBase→Derived
実行順は 基底クラスのコンストラクタ→メンバののコンストラクタ→自身のコンストラクタ で、 それぞれ宣言順に実行される。 例えば class E : public A, public B { C c; D d; }; なら、A, B, c, d, E の順にコンストラクタが呼ばれる。 だから、初期化子もこの順に書いた方が紛らわしくないし、 そう書かなかった場合に警告出すコンパイラもあるから、 この順に書いた方がいい。
void dice(int*, int*); int main() { int dice_a, dice_b; dice(&dice_a, &dice_b); return 0; } void dice(int *a, int *b) { srand((unsigned)time(NULL)); *a = rand % 6 + 1; *b = rand % 6 + 1; return; } このスクリプトなのですが、コンパイル時に「ポインタの不正な使用」と出てきてコンパイルできません。 ググってみたのですがよくわかりませんでした。何がおかしいのでしょうか?
>>530 エラーメッセージを貼れと何度言ったら…
randってなんだよ?ってことだ。
あとsrandは一回でいいんじゃね?
>>531 すみません。下のようなエラーが出ます。
エラー E2087 testx.c 17: ポインタの不正な使用(関数 dice )
エラー E2087 testx.c 18: ポインタの不正な使用(関数 dice )
警告 W8057 testx.c 20: パラメータ 'a' は一度も使用されない(関数 dice )
警告 W8057 testx.c 20: パラメータ 'b' は一度も使用されない(関数 dice )
stdlib.hは一応インクルードしているのですが……。
rand()
535 :
531 :2008/05/05(月) 15:20:41
>>533 だからrandが何か考えればわかるだろってこと。
randは関数なのにそのアドレスを6で割ろうとすれば型があわねぇからポインタの不正な使用ということになる。
>>532 てゆーかこの使い方だと同じ値しかでないなw
537 :
デフォルトの名無しさん :2008/05/05(月) 15:21:54
>>531 >>534 そういう意味でしたか、てっきりポインタの利用に間違いがあるのかと思っていました。
ありがとうございました!
関数名を括弧なしで使うと、関数のポインタを表すことになる
和む質問だなw
>>532 いいえ。「一回でいい」のではなく、「一回でなければいけない」のです。
>>536 ,541
srandの引数にtime使ってるんだから、一概にそうとは言えない。
diceを使うタイミングしだい。
>>542 ちょっと誤解があるんじゃね?
たぶん
>>536 に関してはrand関数のアドレスを使えば常に同じ値になってしまうという意味で、
srandとは無関係のレスだと思う。
一回とか回数の問題じゃなくて、diceの中で初期化してるのが問題だろ
>>542 diceが連続で呼ばれない保証でもない限り
「一回でなければいけない」だろ。
だからdiceを使うタイミングしだいって書いてあるだろ?
タイミング次第だからこそ「一回でなければいけない」んだろうが。 ボケっ!
//! \remarks この函数を連続で使用する場合は、1秒以上間をあけること。 void dice(int *a, int *b);
せっかくなんだから質問者にもわかるようになんで駄目なのか説明してやれよ 回数の問題じゃないだろう
randは乱数を作り出す関数、つってもコンピュータに完全な乱数を生み出すのは無理だから srandで乱数の元となる数字を変えて、乱数っぽくなるようにしてる
srandの引数にtime使ってるんだし、これまでの やり取りで何が問題なのか自分で気が付くと思うが。 もし分からないならまた質問してねってことで。
for(i=0;i<100;i++)dice(&a[i],&b[i]); 下手するとこれが、全部同じ目になるってことか
dice内にsleep(1000);入れとけばいいんじゃね?
乱数のために16分間ブロッキングする関数ってのもまた斬新だな。
パラメータが"ミリ秒"の処理系がある、と推理してみる
>>555 なんのパラメータ?
仮にclock()がミリ秒単位の値を返すとしても、それをsrand()の入力に使ったのでは
今時のCPUにとっては余りに遅すぎて話にならないわけだが。
もうミスなのは自明なんだからそろそろやめろよw
clock()ってのはどこからでてきたんだろう
560 :
553 :2008/05/05(月) 20:06:56
すみません、俺が間違ってた。 sleepは1秒単位なのか。Win32のSleepが_秒だからうっかり。 ということで、sleep(1);を入れれば万事解決ということで。
> 仮にclock()がミリ秒単位の値を返すとしても、それをsrand()の入力に使ったのでは > 今時のCPUにとっては余りに遅すぎて話にならないわけだが。 で、↑こっちはどうしたらいい? 放っておく?
放置でいいよ。それ以降でてこないし
テンプレート部分特殊化で型が配列かどうか判定することってできますか?
boost::is_array<T>::value
>>564 ありがとうございます
type_traitsに色々判定用のがあるんですね
ついでに、こんな感じでも書けますね template<class AryT, size_t N> void arrayargfunc(AryT (&ary)[N])
567 :
デフォルトの名無しさん :2008/05/06(火) 14:43:15
[3] 環境 [3.1] OS: Windows [3.2] コンパイラ名とバージョン: VC++ 9.0 [3.3] 言語: C/C++ C/C++ で大きな数値を扱うにはどうすればよいでしょうか? たとえば、円周率を小数点以下10万桁求めるとか、20000!を求めるとか。 long double を使った階乗を求める自作関数では、170! までが精一杯でした。 どうすれば巨大なデータを取り扱うことができるのか、想像も出来ません。 どなたか、ヒントだけでも教えてください。よろしくお願いします。
多倍長演算とかでググれば。
569 :
デフォルトの名無しさん :2008/05/06(火) 14:50:11
ヒント:自作クラス
570 :
デフォルトの名無しさん :2008/05/06(火) 14:51:09
>>568 ありがとうございます。早速調べてみます。
571 :
デフォルトの名無しさん :2008/05/06(火) 17:17:45
今、「猫でもわかるC言語プログラミング」を読破したとこなんだけど、次買うならどんな参考書がいいかな? 一応CマスターしたらWindowsプログラミングしたいと思ってる
572 :
デフォルトの名無しさん :2008/05/06(火) 17:34:35
このプログラムを面白おかしく改造してくれる人募集 #include <stdio.h> #include <stdlib.h> #include <time.h> main() { int computer; printf("ジャンケンゲーム\n"); srand(time(NULL)); computer = rand()%3 + 1; printf("コンピューターは %d", computer); return 0; }
576 :
デフォルトの名無しさん :2008/05/06(火) 18:03:15
std::mapをまるっとコピーする方法教えてください。
>>576 コピーコンストラクタでも、コピー代入演算子でも可能。
ファイル出力の関数で、プログラム中の”printf”出力を そのまま出力してくれるのがあったと思うのですが、 どなたかご存知ですか?
fprintfのことだろうか
prinft("printf("hello world");");
>>579 いえ、プログラム中で逐一fprintf()を使わないで、
コンソール(DOS)での表示をそのままファイルへ出力してくれる関数があったと思うのですが。
もちろんプログラムの始めと終わりにファイルオープン・クローズの操作は必要だったと思いますが。。。
たとえばコンソールプログラムのその表示をそのままファイルへ保存して、
実行終了後にprintfデバッグのように眺める、デバッグ用変数を使わずに済むなどメリットがあったと思います。
>>581 これか?
freopen("stdout.txt", "w", stdout);
C++では型変換の際に、 reinterpret_cast などの新しいキャストの使用が推奨されてるので、 キャストの目的をハッキリさせるため積極的に使用しております。 しかし、ウィンドウプロシージャ周りなどのキャストが多く発生する場面では ソースが長ったらしくなって、何となく気持ち悪いです。。。 ちょっと不安になってきたのですが、 型変換は全て新しいキャストを使用する姿勢のままで良いのでしょうか。
template<typename From, typename To> To r_cast(const From& f) { return reinterpret_cast<To>(f); }
>>581 関数じゃなくてコマンドプロンプトのリダイレクトのことじゃね?
C:\>app_name.exe > file_name.txt
>新しいキャストを使用する姿勢のままで良いのでしょうか。 良い。
>>582 なるほど。そういうのもあるんですね。
前に便利だと思ったきり使わないでいたので忘れてしまいましたが、
...
fopen...
hoge_printf利用宣言
...Program Body
printf("hoge statement 1\n");
...
printf("hoge statement 2\n");
...
fclose...
というような使い方で、出力ファイルのテキスト内容が、
hoge statement 1
hoge statement 2
となるようなものだったのですが。
>>585 リダイレクトってたとえば、VC++のデバッグ時にブレークしながらまた変数代入操作しながら使えましたっけ?
これができないと先の関数が生きてこないと思われて。
>>589 です
とりあえず、freopenを使ってみます。教えてくれてありがとう。
>>589 です
使ってみました。
stdioをそのまま流してしまうので、コンソールに表示されないので、
ファイルを幾一オープンしなおす必要がありますね。
VC++では、ブレークポイントがそのまま使えるので(当然ですが)、
それで何とか操作しながら出力させるようにしないといけないみたいです。
T *p1 = new T[cnt1]; があって、新しい領域に移動したいとき、素直に書くと(多分)こうなると思いますが、 T *p2 = new T[cnt2]; for (size_t i = 0; i < min(cnt1, cnt2); ++i) { p2[i] = p1[i]; } delete [] p1; これだと、全てデフォルトコンストラクタで生成された後、各々にoperator=を呼んでるので効率悪いと思います。 T *p2 = new T[cnt2]; // ここでコンストラクタは呼ばず、メモリの確保だけして for (size_t i = 0; i < min(cnt1, cnt2); ++i) { p2[i] = p1[i]; // ここでp2[i]に対して、コピーコンストラクタ T::T(p1[i]) を呼びたい } っていうことはできますか?(車輪の再発明中なのでstd::vector使えとかはなしで・・・
placement new
593に加えてstd::uninitialized_copy
C言語にも慣れてきたので visualstdio2005から2008に乗り換えたのですが 2005にあった機能のデバックなしで実行という機能がなくなっています・・・。 2008でデバックなしで実行 の機能はないのですか?
もしかしてCtrl + F5のこと? 俺の2008には[デバッグなしで開始(H) Ctrl + F5]がちゃんとあるんだが・・・ 2005は入れてないんでわからん。
ありがとうございます
またvisualstdioかよ
599 :
デフォルトの名無しさん :2008/05/07(水) 20:50:08
ネットで出されているCM/クイズなんで知っている人も多いと思うけど、 class A {}; A DoNothing ( A object) { return object; } main() { A object; DoNothing(object); } を実行するとコンストラクタは何回呼ばれますか? ってやつなんだけど、正解は1回なのはなんで? DoNothing(object);でも(コピー)コンストラクタ呼ばれるんじゃないの?
600 :
デフォルトの名無しさん :2008/05/07(水) 20:51:39
コンストラクタとコピーコンストラクタは別物だから。
無茶苦茶言うなw
まさか、最適化とか・・・いやーないか!!なんでもないです!
最適化で DoNothing の呼び出し自体が消されるってことか?
class A { public: A() {printf("A\n");} A(const A &) {printf("Ac\n");} }; A DoNothing ( A object) { return object; } int main() { A object; DoNothing(object); } っててしたら A Ac Ac ってなったんですが、やっぱコピーコントラクタが理由じゃないんですか?
一時オブジェクトの生成を最適化で消してもOKなのは規格に明記されてる。
606 :
デフォルトの名無しさん :2008/05/07(水) 21:09:54
>>604 乙っス。
やっぱり世間ではコピーコンストラクタはコンストラクタに含めないんですかね?
>>602-603 確かにコンパイラによっては消してしまいそう。
まず A object; だが、 A は POD 型なのでデフォルトコンストラクタは呼ばれない。 これは確か。 あとは空クラス(構造体)を関数に渡した際には オーバーロードの解決にしか使われないとかいう仕様があれば 戻り値でのコピコンしか呼ばれないってことになりそうな予感がするよ。
VC++いいかな? 2個のフォームを用意してボタンクリックイベントで、 他方を開く、自分を閉じる(隠す)をしたいんですけれども //Form1.h// … #include "Form2.h" … Form2^ form2 = gcnew Form2(); form2->Show(); this->Hide(); … //Form2.h// … #include "Form1.h" … Form1^ form1 = gcnew Form1(); form1->Show(); this->Hide … ってやると定義が存在しないって出てしまうんです。 相互includeが良くないのはわかるんですが、 どこに#includeを書けばいいのかがわかりません。 お願いします
609 :
デフォルトの名無しさん :2008/05/07(水) 21:28:13
//Form1_2.h// Form2^ form2 = gcnew Form2(); Form1^ form1 = gcnew Form1(); //Form1.h// … #include "Form1_2.h" … form2->Show(); this->Hide(); … //Form2.h// … #include "Form1_2.h" … form1->Show(); this->Hide … VC++なんてやったことないからこんな書き方ができるのかどうか知らん
//Form1.h// ・・・ class Form2; class Form1 { ・・・ }; #include "Form2.h" ・・・ Form2^ form2 = gcnew Form2(); form2->Show(); this->Hide(); ・・・ //Form2.h// ・・・ class Form1; class Form2 { ・・・ }; #include "Form1.h" ・・・ Form1^ form1 = gcnew Form1(); form1->Show(); this->Hide(); ・・・
型変換をせずに、ビット単位で正しくコピーするにはどうしたらよいですか? 具体的な例ですと、 int(32bit)の上位16bitをそのままshort(16bit)にコピーしたいのですが… (1/256されてshortになる) 256で割って代入しろと言いたいところでしょうけど、事情がありまして。
int = 32bit short = 16bit は仮定していいのか?
ポインタで8bitずつ持ってくるのは無し?
_asm { mov eax, int変数 mov short変数, ax } これで解決
あぁHIWORDをコピーしたいのか。 シフト使わないとダメだね
そうだ! バイナリ形式でsizeof(int)でファイルに書き込んで 読みだすときにsizeof(short)で読み出せばいいんだ うん!型変換はしてないな!
ところで、誰も 256 じゃなくて 65536 だろって突っ込まないのな。
>>612 共用体は甲斐ビット(上位アドレス?)にしかアクセスしないと思ったのですが…
>>613 ちょっと他にもアクセスしたい理由がありまして…
>>614 どちらかというと、intとかshortよりも、ビット数の方を重視願います
>>616 試してみます。
…てか、アセンブリ使えたの知りませんでした…
>>619 そうでしたww
きっとみんな心の目で256の後ろに書いてある文字を読んでくれたんだw
union int_short { int i; short s[2]; } int_short is; is.s[0]; // LOWORD is.s[1]; // HIWORD こうすれ
>>620 #include<stdio.h>
union hoge
{
int foo;
struct{
unsigned bar:16, boo:16;
};
};
int main(void)
{
union hoge huga;
huga.foo=0x12345678;
printf("%08x %04x %04x\n", huga.foo, huga.bar, huga.boo);
return 0;
}
#include <iostream> int hi() { union { int n; char c; }; n = 1; return c; } int main() { union { int n; unsigned short s[2]; }; n = 0x12345678; std::cout << hex << s[hi()] << std::endl; }
ってか供用体でいいんじゃねぇの? 下位から詰められるならdummyでも置いとけば済むはなしでは?
>>624 ダミー詰める事思いつきませんでした…orz
int main(void) { struct ST { short b; short c; }; union UN { int a; struct ST st; }; union UN obj; obj.a = 0x0001ffff; printf("%d\n",obj.st.b); printf("%d",obj.st.c); } 既出か?
構造体より配列にすべき
630 :
デフォルトの名無しさん :2008/05/08(木) 01:08:54
std::istreamからの読み込みコードを書く時、 std::istream &operator>>(std::istream &is, classname &obj) { is >> obj.member >> std::endl; } のように、最後にendlをつけたら駄目ですよね?付けても付けなくてもOKとかじゃなくて、 付けたらだめですよね?
それをつけて、どういう挙動を期待するんだ?
632 :
デフォルトの名無しさん :2008/05/08(木) 02:31:11
次の二つのプログラムをシステムコールで実現せよ。 (a) #include<stdio.h> main() { printf("Hello World\n"); } (b) (b)#include<stdio.h> main() { char s[50]; fgets(s,50,stdin); fputs(s,stdout); } システムコールで検索したのですが、どのようなものかよくわからなったので…
633 :
デフォルトの名無しさん :2008/05/08(木) 02:47:58
バッファ付きファイル入出力クラスやライブラリはありますか? 複数のファイルを一括して管理してなるべくHDDへのアクセスを減らすやつです。
634 :
デフォルトの名無しさん :2008/05/08(木) 03:49:39
CreateFileの入力バッファはどのくらい効果がありますか? NOバッファにして自分で管理しても、速度は上回りませんか?
635 :
デフォルトの名無しさん :2008/05/08(木) 04:03:43
テンプレートと、参照を使った場合、元のデータのサイズを知ることは出来ますか? たとえば、テンプレート無しだと、つぎの様に判明しますが、 f( int &x) { //xのサイズは4バイト} f( double &x) { //xのサイズは8バイト} ここで参照とテンプレート使ってもサイズは判明しますか?
637 :
デフォルトの名無しさん :2008/05/08(木) 10:39:36
上のほうで書いたのですが Form1.hとForm2.hを用意して Form1のクリックイベントでForm2を表示、Form1を非表示 Form2のクリックイベントでForm1を表示、Form2を非表示 と行ったところ、ビルドが通りません //Form1.h// #include"Form2.h" … Form2^ f2 = gcnew Form2(); f2->Show(); this->Hide(); … //Form2.h// #include"Form1.h" … Form1^ f1 = gcnew Form1(); f1->Show(); this->Hide(); … クリックイベントが.hファイルに含まれるため 相互に.hファイルのインクルードをした際に おかしくなっているのだと思います レスしてもらったやり方で試したのですがエラーが増えただけでした どなたかお願いします
638 :
デフォルトの名無しさん :2008/05/08(木) 10:41:34
639 :
デフォルトの名無しさん :2008/05/08(木) 11:19:44
640 :
デフォルトの名無しさん :2008/05/08(木) 11:29:06
>>639 うまく動作しなかったってのはコンパイルは通ったの?
641 :
639 :2008/05/08(木) 11:35:08
>>640 コンパイルは通ったんですけど、maxとminの値がありえない数字になるんです
642 :
デフォルトの名無しさん :2008/05/08(木) 11:40:51
>>641 どこかで
x.max = 0;
x.min = 100;
あと、Cではブロックの途中での変数宣言は認められないよ
例えばminの初期値が0だったらどういう結果になると思う? あと他に一箇所間違いがあるけど。
これは決まり文句だがc99ならおk
647 :
641 :2008/05/08(木) 13:24:52
>>642-644 ありがとうございます
x.max=0;
x.min=100;
で初期化してみたのですが、その値がそのまま結果表示されてしまいました。
648 :
デフォルトの名無しさん :2008/05/08(木) 13:33:04
>>647 お前どこで初期化したの?
forループより前でやれよ
649 :
647 :2008/05/08(木) 13:39:06
ひょっとしてこれか for(i=0;i<4,i++;)
651 :
647 :2008/05/08(木) 14:08:05
>>650 ありがとうございます
訂正したらうまくいきました!
ASCII文字とマルチバイト文字がごちゃまぜで格納されているStringオブジェクトのポインタを先頭から1つずつずらしていき、 特定のマルチバイト文字の文字列が出てきたらそれ用の処理、 特定のASCII文字の文字列が出てきたらそれ用の処理、 みたいなことをしたいのですが、どういった書き方をすればよいでしょうか?? アドバイス頂けると幸いです。
StringってC++/CLIの話か?
654 :
652 :2008/05/08(木) 14:41:13
CLIは違うと思いますが、C++です。
std::stringでもCStringでもなくてString?
656 :
デフォルトの名無しさん :2008/05/08(木) 15:00:36
STLのstringでいいです。
657 :
652 :2008/05/08(木) 15:02:16
656は俺じゃないっすw std::string です。
ごちゃ混ぜで格納なんてできたっけ?
>>652 混在させたらマルチバイト文字セット内の1バイト文字の一部とASCII文字で
コードポイントがかぶっちゃうから、混在は難しいんじゃないかな。
ASCII の バックスラッシュと、Shift_JIS の1バイト¥マークとか。
それはともかくとして、std::string はただのコンテナと割り切ってポインタ使って
普通に書いた方がいいと思うが。
降順にソートするプログラムを作っています。
ソースはこちらです→
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6476.txt *整数を5件入力させる→降順にソートする→ソートしたものを表示する
ここまで(プログラムの本題)は出来たのですが、
オマケである
*入力された文字を判断し、半角数字以外が入力された場合はエラーを表示し、再入力させる
この関数を作成し、main関数と繋げる事が上手く出来ません。
半角数字の場合は問題なく作動していますが、それ以外の場合が指定通りに作動してくれません。
なるべく自力で作らなければ意味がないので、答えよりもヒントや考え方を望んでいます。
Google先生を頼りにここまで出来ましたが、C言語を始めてまだ1ヶ月と少々で分からない事ばかりです。
judge()の部分は今後も使うので、もしおかしな部分があればそちらもご教示願います。
宜しくお願いします。
judge(s) int *s; { … return 0; } なにこれ?
662 :
652 :2008/05/08(木) 15:33:24
>>659 さん
レスどもです。
文字コードが同じものがある場合については、仕方がないので双方とも同じものとして扱う、というやり方を考えていました。
>> ともかくとして、std::string はただのコンテナと割り切ってポインタ使って
>> 書いた方がいいと思うが。
ただのコンテナとして割り切るというのは、どういうことでしょうか?このような場合はstringは使わない方がいいということでしょうか。
また、普通ポインタ使って書く、というのは、具体的にどういうことなんでしょうか。
ご教示いただけると幸いです。
(ちなみに、話に出しているのはとあるライブラリのメソッドから返ってくる値を走査するものなのですが、そのメソッドがstring型しか返してくれないんです。)
663 :
660 :2008/05/08(木) 15:33:41
>>661 すみません、消し忘れです。
return 0;
の部分は必要ないものです。
664 :
デフォルトの名無しさん :2008/05/08(木) 15:38:00
stringをwcharにする。
665 :
デフォルトの名無しさん :2008/05/08(木) 15:39:13
いやいや、 judge(int *s){ うんたらかんたら; } じゃね?ってことが言いたかったんだが
>>661 古い書き方
>>660 mainでscanfで%dで読み取れた時点で、それが数値であることは確定しているので、そのjudgeの処理はまったくの無駄
scanfは、読み取れたデータの個数を返すので、scanfの戻り値が1じゃなかった場合は数値を読み取れなかった=数値じゃないものが入力されたと判断できる
再入力させる場合は、さっき読み取れなかったデータは読み捨てる必要があるので、改行まで来るまでgetcを回すとか、scanfで%sして捨てるとかするといいかも
667 :
660 :2008/05/08(木) 16:20:00
レスありがとうございます。
古い書き方ですか…orz
>>666 judgeでの処理は丸々無視されているという事でしょうか。
理解不足で申し訳ないのですが、
>再入力させる場合は、さっき読み取れなかったデータは読み捨てる必要があるので、改行まで来るまでgetcを回すとか、
>scanfで%sして捨てるとかするといいかも
こちらの部分を詳しく教えていただけると幸いです。
そもそも入力方法に問題あり?
まだまだ勉強不足か…。
>>667 そもそもjudgeは引数でintを受け取るのだから、どんなintの値を渡したところで、半角数字以外と判定されることはありえない (※マイナスはある)
再入力の方は、scanfの動作をもうちょっとよく知る必要がある
int s, n;
n = scanf("%d", &s);
このようにしたとき、%dは数値入力の指示なので、数値が入力された場合はそれが読み取られ、sにその値が入って、nに1が返される
数値以外が入力された場合は、何も読み取られず、nに0が返される
ここで、何も読み取られないというのは、その文字列はまだ入力バッファに残っていて、次回scanf等を呼んだときに再び現れるという意味
そこでまた%dしても、その文字列は数値ではないので、何も読み取られず、また入力バッファに残ったままになる
この文字を何か他の方法 (getcとか%sとか何でもいい) で読み取って捨てない限り、%dは永久に成功しない
669 :
ブロンズ :2008/05/08(木) 16:49:56
WindowsのAPI使ってゲームつくろうと思ってるんですけど、ウィンドウを出すだけのプログラムがコンパイルできません。 Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照) って出たり int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) のhPrevInst lpsCmdLine nCmdShow が未使用ってでたり。 ソースは間違ってるはず無いんですよ。付録のCDのサンプルをコンパイルしただけなのに。 何が原因なんでしょうか?
670 :
デフォルトの名無しさん :2008/05/08(木) 16:54:05
コマンドライン引数で -Wってつけろ 未使用のやつは警告だから気にしなくておk
671 :
ブロンズ :2008/05/08(木) 17:04:16
>>670 ありがとうございます。秒殺でした。^^
C++のstring型変数で x文字目からy文字目までで"sample"という文字列がでてくるかどうか、探索 みたいなことがしたいのですが、一回substrを使わないと無理でしょうか??
const char* s = str.c_ptr(); int len = str.size(); for (int i = x; i <= y && i < len-6; i++) { if (strcmp(s+i, "sample")==0) { hoge; } }
size_type find(const char* s, size_type pos, size_type n) const なるメンバ関数があったはずだが
675 :
660 :2008/05/08(木) 17:39:05
>>668 丁寧な説明をありがとうございます。
sprintfでint型からchar型に代入を〜・・・と考えていましたが、
そもそもscanfでint型を指定して取り込んだ時点で文字は0扱いでした。失念していました。
char型で取り込み→judgeに渡す→判定→クリアした場合int型に変換→int型でmainに返す
の方法を取れば良いのでしょうか?
うpした物のと少し違ってしまうのですが、
mainから受け取った物がjudgeでは!isdigitが真と判断された場合-1を返して、
main側ではjudgeから-1が返された時にはエラー表示・再入力、
偽だった場合はそのまま進むようにしたいと思います。
25行目あたりのjudge(&s)の下に、if(s<0)を置いてみましたがうまくいきませんでした。
後半部分は大体理解出来ましたが具体的な方法は現在まだ調べ中です。
何度もすみません。
676 :
672 :2008/05/08(木) 17:45:07
レスくださった方々、ありがとうございます。 size_type find(const char* s, size_type pos, size_type n) const このメンバ変数、ありました。ありがとうございましたm(_ _)m
>>675 >mainから受け取った物がjudgeでは!isdigitが真と判断された場合-1を返して、
>25行目あたりのjudge(&s)の下に、if(s<0)を置いてみましたがうまくいきませんでした。
sは戻り値とは違うので。
n = judge(&s);
if(n<0)
こうじゃない?
678 :
660 :2008/05/08(木) 18:44:46
>>642 > Cではブロックの途中での変数宣言は認められないよ
C99では使えるよ。
680 :
デフォルトの名無しさん :2008/05/08(木) 20:08:28
681 :
ブロンズ :2008/05/09(金) 00:39:32
WindowsのAPIに奮闘してるんですが、 コンパイルしたら LRESULT が複数あるとか、再宣言の型が一致しないとかでるんですよ。 そんなとこひな型つくってからいじくってないのに。 どうすればいいですか?
エラーメッセージとソースのうpを要求する
683 :
ブロンズ :2008/05/09(金) 01:07:30
エラー E2238 C:\PK\PK\sample01.cpp 9: 'LRESULT' の宣言が複数見つかった
エラー E2344 c:\Borland\Bcc55\include\windef.h 173: 一つ前の 'LRESULT' の定義位置
エラー E2356 C:\PK\PK\sample01.cpp 9: 'LRESULT' の再宣言で型が一致していない
エラー E2344 c:\Borland\Bcc55\include\windef.h 173: 一つ前の 'LRESULT' の定義位置
エラー E2141 C:\PK\PK\sample01.cpp 9: 宣言の構文エラー
エラー E2451 C:\PK\PK\sample01.cpp 42: 未定義のシンボル WndProc(関数 InitApp(HINSTANCE__ *) )
エラー E2034 C:\PK\PK\sample01.cpp 115: 'void *' 型は 'int' 型に変換できない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
エラー E2451 C:\PK\PK\sample01.cpp 147: 未定義のシンボル TREU(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
エラー E2034 C:\PK\PK\sample01.cpp 147: 'int' 型は 'void *' 型に変換できない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
エラー E2342 C:\PK\PK\sample01.cpp 147: パラメータ 'hHandle' は void * 型として定義されているので int は渡せない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
エラー E2034 C:\PK\PK\sample01.cpp 148: 'int' 型は 'void *' 型に変換できない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
エラー E2342 C:\PK\PK\sample01.cpp 148: パラメータ 'hObject' は void * 型として定義されているので int は渡せない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
*** 12 errors in Compile ***
** error 1 ** deleting Debug\sample01.obj
ソースあげたいんですけど、
>>660 さんみたいなやりかた知らないんですorz
>>669 付録のCDのサンプルが間違ってるはずない?なぜだろうか
まさかとは思うが猫でもわかるなんたらかんたらじゃなかろうか
686 :
ブロンズ :2008/05/09(金) 01:18:01
一番下のclassのセミコロン
すいません vector<char> dt; と定義したdtを、関数の返り値にできるのでしょうか?
689 :
ブロンズ :2008/05/09(金) 01:33:48
>>687 ありがとうございます。
だいぶエラーがへりました。凡ミスでおはずかしい。
あとは細かいパラメータなんですが、イマイチわからないです。
もっと研究してみます。
>>688 試せば分かることじゃないか
どういう使い方をするか知らないけど、
普通に引数で渡した方がいいと思うけど
_ で始まる識別子はコンパイラが使うから、使うとどうなるかわからない、使うべきでないと聞いた覚えがあるんですが、 他人のコードを見ると、普通に使われてるような気がします。 本当はダメなんだけど、使っても問題ないことがおおいってことですかね。(それとも↑がウソで、まったく問題ないのか) あと、 typedef struct _hoge { ... } hoge; って感じで(両方hogeじゃなくて)違う名前にするのは、何か利点があるんですか?
>>691 まともなコンパイラなら警告やエラーを吐く
そうじゃ無い時代、コンパイラの話なんじゃ、と思うけどね…
そんなの自分や会社のルール、規則で好きにスタイルを決めれば良いと思うが
typedefの使い方は
struct _hoge -> hoge とする
つまり、struct付いてようが同じ名前にしたくないって感じじゃねーの
それかコンパイラ依存だけど、同名だとコンパイル出来ない環境があるとか
>まともなコンパイラなら警告やエラーを吐く 具体例をどうぞ。 >それかコンパイラ依存だけど、同名だとコンパイル出来ない環境があるとか C++だとエラーですね。 知識がないなら無理に回答しなくても宜しいかと。
>>691 エラーをはく場合があるのはたしか
しかしCではないがその習わしのようなものを受け継いだウェブプログラミング言語では
エラーはおこらないと言っていい(例:PHPなど)
全く参考にならなくて申し訳ないが
>エラーをはく場合があるのはたしか 具体例をどうぞ >しかしCではないがその習わしのようなものを受け継いだウェブプログラミング言語では >エラーはおこらないと言っていい(例:PHPなど) >全く参考にならなくて申し訳ないが あまりにも話題と関係なさすぎてワロタ
>>695 顔真っ赤にしてそんなレスしてどうしたんだい?
おれでよければ相談に乗るよ?
エラーを吐くコンパイラが見つからないからってムキにならなくても…
>>691 普通に使ってます
でもあんまりおすすめしません…その訳は…
現在
>>692 が自身の妄想どおりに動く
コンパイラを作成中ですので
気長にお待ちください。
ここまでおれの自作自演
_と__から始まる名前は処理系で予約されているのは確か。 名前が衝突して面倒な事になりたくなければ避けろ。
でも有名ライブラリとか至る所で使われてるんだよな…。
有名ライブラリって例えばどんなの?
具体例をどうぞ
初心者スレで初心者の質問に嘘の返事を書く奴が悪い。
流れがよくわからないけど
>>691 自分は struct を付けるべきかどうか覚えておくのが面倒なので全部 typedef してます。タイプ量も減るし。
タグ名については先頭にアンダースコアを付けるのでなく末尾に _tag とでも付ければ問題ないのでは。
>>709 typedef 必須だと前方参照が利かないから、タグ名に
変な修飾(アンダースコアとか _tag とか)つけないで欲しい。
うーん、必要なら struct Hoge_tag と書けばいい気もしますがわかりにくいですかね。 でもXLibとかMinGWのWindows関連ヘッダとかも似たような感じでタグ名付けてた気がしますが… 同名だと混同しやすいかなーと思ってたんですが、よくわからなくなってきた^^;
typedefを使わない場合 struct hoge{ int a; }; void main(){ struct hoge k; k.a = 5; } typedefを使う場合 typedef struct _hoge_{ int a; }hoge; void main(){ hoge k; /* struct hogeって書かなくていいから楽 */ k.a = 5; }
前方参照もしたい場合 typedef struct _hoge_ hoge; /* プロトタイプ宣言みたいなもの? */ typedef struct _hage_ hage; struct _hoge_{ int a; hage c; }; struct _hoge_{ double b; hage c; }; void main(){ hoge k; k.a = 5; k.c.b = 1.1; } とかやってる。最近は書き方統一したいから全部最後の方法で書いてます^^
>712 おおお、これは知らなかった。ソースコード直してきます^^
だから、変な修飾、しかもアンダースコアで始めるのやめてくれってばよ。 typedef struct hoge hoge; でいいじゃないか。
>>716 713=714=715です。
その通りですね、間違いを含んだ回答をしてしまって申し訳ない^^;
便序して質問なのですが_で始まる変数は予約されている可能性がある。
って事は
ヘッダーの宣言でよく以下のような書き方をしていたんだけど
#ifndef _STRUCT_HEADER_
#define _STRUCT_HEADER_
/* 構造体の宣言とかプロトタイプ宣言とか */
#endif
これも危ないって事かな?
正確には 先頭の_に大文字が続く識別子 __を含む識別子 グローバルかつ先頭の_に任意の文字が続く識別子 だった記憶がある 面倒だから先頭の_はやめとけと覚えた方が安全かと
719 :
688 :2008/05/09(金) 14:32:50
>>690 レスどもです。
vector<char> 型のオブジェクトを関数の返り値にするのはできたのですが、
vector<char>型のオブジェクトを
vector<char> dt;
....
fout << dt;
みたいに、ファイル出力しようとすると
no match for 'operator<<' in 'fout << dt'
みたいなエラーが出ました。
vectorオブジェクトはそのままファイル出力はできないのでしょうか??
>>719 メンバ関数に<<がないから
std::copy(dt.begin(), dt.end(), std::ostream_iterator<char>(std::cout, ""));
とかにするしかない
>>719 適当にコンテナをラップするtemplate classを定義してやって、
それと、ostreamを引数にとるようなoperator<<を定義すればできるけど
面倒だから適当に誰かが作ってるそういうものを利用すればいい
// pstade::ovenライブラリを使った例
#include <vector>
#include <iostream>
#include <boost/assign/std/vector.hpp>
#include <pstade/oven/io.hpp>
#include <pstade/oven/identities.hpp>
int main() {
using boost::assign::operator+=;
using pstade::oven::identities;
std::vector<int> v;
v += 1,2,3,4;
std::cout << (v|identities);
}
ちょっとお聞きしたいのですが 0x3cのような16進数を直接バイナリとしてostringstreamオブジェクトの中に書き込みたいのですが、どうすればよいのでしょうか?? ostringstream aaa: aaa << 0x3c などどすると、ASCII文字の文字列"60"として認識されてしまいます。
aaa << (char)0x3c
write使えば?
725 :
TOM :2008/05/09(金) 17:32:52
// interface class Interface { public: virtual int getValue() const = 0;}; // print class Print { public: void out(const Interface& interface) { cout << "## " << interface.getValue() << endl; }}; // class A class A : public Interface { public: virtual int getValue() const { return 0; }}; // class B class B : public A { private: Print p; public: virtual int getValue() const { return 1; } void out() { // オブジェクトがコピーされて、class Aの値が表示される p.out((A)*this); // class AのgetValueが呼び出される p.out((A&)*this); } }; オブジェクトをコピーすることなく、クラスAの値を表示できませんか?
A::getValue()
できません だってクラスAじゃないもの
class B : public A { private: Print p; public: virtual int getValue() const { return 1; } void out() { cout << "##" << A::getValue() << endl; } }; int main() { B b; b.out(); }
730 :
TOM :2008/05/09(金) 17:53:00
vptrとかで、なんとかならないの?
そもそもクラス設計ミスってるでしょ
そういうときには A 側に basicGetValue を定義しておくのが Smalltalk流
>>725 class B : public A {
class C : public Interface {
private: B *b;
public: C(B *b_):b(b_){}
virtual int getValue() const { return b->A::getValue(); };
};
private: Print p;
public:
virtual int getValue() const { return 1; }
void out() {
p.out(C(this));
}
};
>>712 あまりいい説明じゃないと思います。根拠をしめせていません。
結論からいうと、extern な変数・関数はアンダースコアで始まる名前は避けた方がいいと考えています。
構造体/共用体/列挙体 タグや、autoな、あるいは static な変数、static な関数はアンダースコアで始まる識別子をつけても問題ありません。
>>717 プリプロセッサの識別子はアンダースコアをつけても大丈夫です。
いやいやいやいや
いやいやいやいや
いやいやいやいや
どうぞどうぞ
740 :
702 :2008/05/09(金) 19:52:57
>>707 30レスも空いてるからちょっと恐縮だけど、
具体的にとのことなので一応マジレス返答を。
「たしかに」と同調の言葉を言いつつ、「ムキなのはお前(達)の方」という
趣旨のレスをしていたから、
ちょっと痛い煽り返しだなって思って。
それで傍観してたけど思わずツッコミを。
それと、そこで
>>699 をリピートする必要は無いんじゃないかな。
>>697 などがムキなのかどうかは知らないけど、
ムキだとするとあなた(達)の一連のレスも
同じくムキに(少なくとも俺には)見えるわけで。
741 :
702 :2008/05/09(金) 19:55:56
742 :
デフォルトの名無しさん :2008/05/09(金) 19:58:27
>>740 それなんてお前?
せっかく落ち着いてたのにぶり返すなよ
アンカ指定されたから返答しただけです。 昼は会社でレス出来ないんで、 半日くらいは大目に見て下さい・・・。
深夜にまで言い合いしてた連中に 半日は遅すぎなんだろww
745 :
デフォルトの名無しさん :2008/05/09(金) 20:21:27
クラスに関する素朴な疑問です。 クラスのメソッドを宣言する時、クラスの外で宣言する方法と中で宣言する方法がありますが、大半の解説サイトは外で宣言しています。 VB.NETやC#を使っている経験から中で宣言したいのですが、皆そうしないのは何か特別な理由があるのでしょうか。
746 :
デフォルトの名無しさん :2008/05/09(金) 20:24:46
>>745 別にどっちでもいいけど個人的には外に書いたほうが見やすい気がする
簡単なメソッド(etc. フィールドの値を返すだけ)なら中に書くとインライン展開される(正確にはされやすい)から中に書くこともあるけど
ちなみにC++ではフィールドをメンバ変数、メソッドをメンバ関数といいます
>>745 中外の意味は class hoge {}; 内外だと理解してるけど、そうすると
スタイルの問題だな。好みかチームならポリシー。
長い場合は中で定義すると紛らわしいから外というのが普通だと思う。
そうなると、常に外というポリシーがシンプルで選択されやすい。
一人なら勝手にどうぞ。
>>745 中に書くとヘッダに書くことになって、
変更すると、そのヘッダファイルをincludeしてるソースまで
再コンパイルが必要になるから。
ただinlineやテンプレートの関係で、中に書いた方適切な場合もある。
>>745 循環参照があった場合にうまく解決できない
分割コンパイルできない
>>745 Cのヘッダで宣言して別のファイルで定義する習慣を引き継いでいる。
>>746-747 ありがとうございます。
C++では用語も違ったのですね、勉強になりました。
VB.NETやC#で特に可読性が低いと思った事はないので、暫く両方で書いてみて可読性の高い方にしようと思います。
>>748-750 まだC++の学習を初めて1週間なので聞いた事のない用語が出てきていますが、C++にはpartialクラスがないので大規模クラスの時は外に書いた方が分割出来るという事でしょうか。
頭の片隅に留めておきます。
ありがとうございました。
typedef struct Foo{ int x; }Foo; class Hoge{ static Foo foo; }; こんな時にfooの初期化ってどこで行えばいいんでしょうか?
初期化どころか、そのままじゃ実体がないぜ。 そしてその実体を作ろうとすると、自ずと答えが分かるはずだ。
755 :
デフォルトの名無しさん :2008/05/09(金) 21:29:35
>>753 普通に
static Foo foo = 0;とか
756 :
デフォルトの名無しさん :2008/05/09(金) 21:30:14
今思ったんだがconstのつもりなんじゃなかろうか
757 :
753 :2008/05/09(金) 21:33:50
すんません!関係ないとこでのミスでした。 自己解決しました。スコープ解決演算子ってややこしいな・・・
ちょ
// pseudo-code template<typename T, typename U> void foo() { /* hogehoge */ } Class c; // any type foo(c); // ok foo<int>(c); // ok なるtemplate関数って作れますか? TもUも関数内で利用したいんです Uを指定しないときのデフォルトになる型も指定したいです
fooの宣言のところに引数は付けないのかい?
すんません 引数は(T& t)でおねがいします
関数テンプレートはオーバーロードできるけど、 デフォルトテンプレート引数をつけることはできない。
>>759 template<class T> T foo(const T& t){return t;}
template<class T, class U> U foo(const T& t){return U();}
foo(10);
foo<int>(20);
foo<int,int>(30);
2つ書かないといけなかったら意味ないじゃん・・・
それくらい応用しろよ・・・。 template<class T, class U=T> struct foo_impl{ static U f(const T& t){return U();} }; template<class T> T foo(const T& t){return foo_impl<T>::f(t);} template<class T, class U> U foo(const T& t){return foo_impl<T,U>::f(t);}
? foo<int,int> みたいに T をかかないといけないのは意味が無いという話だ。
そっちか。 foo<int>って書けるだろ?
上の奴にしかならんだろ、それ。
>>768 よく意味が分からないんだが、↓だと何かまずいのか?
template<class T> int foo(const T& t){return 10;}
template<class T, class U> int foo(const T& t){return 20;}
std::cout << foo(0) << std::endl; // 10
std::cout << foo<int>(0) << std::endl; // 10
std::cout << foo<int,int>(0) << std::endl; // 20
>>769 うぜぇ消えろ
コンパイラの具体例でもあるなら書け
>>770 >>759 の言ってるのは
foo(c); // T = cの型, U = デフォルト型
foo<int>(c); // T = cの型, U = int
みないな感じのことがしたい、という話だろ。
クラスじゃなくて関数だぜ?
>>771 template<typename T, typename U> に <int> したとき、
U に int を入れるってこと?
>>774 あくまで「みたいなこと」であって、
似た事が実現できる手段を知りたいってことだろう。
型を指定しなきゃいけないんだろ? 方法が知りたいのかどうなのかは質問者に聞かなければ
template<typename T> foo(const T& t) { } template<typename U, typename T> foo(const T& t) { } とすると、foo(c); はいけるが、foo<int>(c); はどちらにも当てはまるのでエラー。 型を指定するためのダミー引数をつけようとしても、 デフォルト引数からの型推論ができないためエラー。 まあ簡単に思いつく方法ではまず無理だなあ。
>>773 関数だとデフォルト指定できなかった?
それは失敬
>>775 それは流石にクラスでも無理じゃね?
セマンティクス的にも意味分からないし
テンプレート関数でデフォルトテンプレート引数みたいなことしたい、
ってことかと思ってたけど、違ったのか・・・
あ、デフォルト引数からの型推論じゃなくて、普通のオーバーロードならいいのか。 template<typename T, typename U> foo(const T& t, boost::type<U>) { } template<typename T> inline foo(const T& t) { foo(t, boost::type<int>()); }
これでこうなる。 foo(c); // U = int foo(c, boost::type<double>()); // U = double
なるほど、<>に拘らなければやれるのか
783 :
459 :2008/05/09(金) 23:42:20
やっぱり無理っぽいんですか…
やりたいことは
>>771 の通りです
あと関数じゃなくて関数オブジェクトでもいいんですが
結局operator()が関数テンプレートになるとおもいます
テンキーで数字を入力していることがよく分かる typo だな。
これじゃだめなのか? Uのデフォがintの場合 template<typename T, typename U>void func(){} template<typename T>void func(){ func<T, int>();} 呼び出し func<double>() →下が呼ばれる func<double, char>() 上が呼ばれる 確認環境はVC++2008
double 書く必要がある時点でダメだろ
普通書かないと無理だろ
これがゆとり脳か・・・。 何がやりたいかも理解できないのか。
テンプレート引数でない、通常の引数でも先の引数を飛ばすとか無理だしな
>>790 boostは使ってもOKだったか?
ならいいや
>>788 残念、エスパーじゃないから理解は出来んわ
>>792 type くらい自分で簡単に定義できるだろ。
template <typename T> struct type { };
template<typename T, typename U> foo(const T& t, type<U>) { } template<typename T> inline foo(const T& t) { foo(t, type<int>()); } foo(c); // U = int foo(c, type<double>()); // U = double
やっとの思いでC#を覚えたのに、 今度はC++を覚えないといけないオレに C++のメリットをどうか教えておくれ・・・・
はやい
あれ? コンパイルエラー出るわ。ちょい待ち。
戻り値の型がないだけだったw すまん。 template<typename T, typename U> void foo(const T& t, type<U>) { } template<typename T> inline void foo(const T& t) { foo(t, type<int>()); } foo(c); // U = int foo(c, type<double>()); // U = double
801 :
759 :2008/05/10(土) 00:12:53
なるほど、型情報を含んだインスタンスを渡してやるんですか
wrapper<type-arg>()とか少し冗長な部分もありますが
型を渡してるってのがわかりやすい面もありますね
でも結局func<type-arg>(value-arg)って形式という制約の上で
type-argにデフォルト値を持たせるのはほぼ不可能ってことなんですね
>>763 のだと戻り値の記述が制限されますし
>>801 template <typename U, typename V, typename T> void foo(const T& t) { }
template <typename T> inline void foo(const T& t) { foo<int, char>(t); }
foo(c);
foo<double, short>(c);
こういうのは可能。
今回の場合はオーバーロード解決に失敗するから無理だっただけだな。
>>801 デフォルト値の問題じゃなくて、引数の型を書かずに飛ばすのが不可能
>>806 まだ言ってんのか。
順番変えればいいだろ、そんなの。
>>796 thx!
関数の型が抜けてたけど、
勉強になった!
こういうことできるんだな〜。
>>801 コンパイルではじかれる場合は
大概使用方法が曖昧だから。
そして曖昧だと、ソースを見た人間もどれが動くか分からないから、
型は明記のほうがいい。
速い以外に C# と比べると C++ の方がいろいろとライブラリあるし、 プラットフォーム選ばないんではないかな。
>>813 ところがこうしちゃうと・・・
template <typename U, typename T> void foo(const T& t) { }
template <typename T> inline void foo(const T& t) { foo<int>(t); }
foo<double>(c); が foo<U = double, T = cの型> なのか foo<T = double> なのか
区別がつかないんだな・・・。
C++だと、public、protected、privateがまとめて書けるから楽
C++だとusing(...){}が不要
RAII と変態テンプレートこそ C++ の真骨頂
>>817 そのテンプレート引数の順番じゃないといけない、
なんて誰も言ってないってこった。
速いが多いけどあえていうなら 多重継承かなって思ってる
>>820 けどdeleteが必要、それもメリット!
コンパイルも、Pascalのように速ければいいのに
今丁度話にあがってる templateが使える、もだな
>>825 そこで自動変数とスマートポインタですよ
>それもメリット!
その通り!
>>831 new、deleteとか、メモリ管理は嫌われる対象になるけど、
プログラマならメモリ管理ぐらいできろよ、と思うわ。
それの経験になるからC++のメリットだと思う。
まあ大抵スマートポインタに突っ込むだけだけどな。
>>833 C畑からC++を勉強した身としてはスマートポインタあんまり使ったことないw
まあ、あれば便利だけどね
>>834 #include <iostream>
#include <typeinfo>
template <typename U, typename V, typename T> void foo(const T& t) {
std::cout << typeid(U).name() << "," << typeid(V).name() << std::endl;
}
template <typename T> inline void foo(const T& t) { foo<int, char>(t); }
int main()
{
foo(1);
foo<double, short>(1);
}
スマートポインタ使わないと、例外が怖いw
>>835 java→C→C++の順で来た俺にはCでfreeの文化を身に付けたものの、慣れてきたとたん
スマポやらSTLやらでjava回帰しとるよ。ぬるま湯はいいぞ
>>836 2個ってそのことか、それが出来ても意味無い
>>804 自身も言っているように、
今回の
>>759 の件では順番を入れ替えても無駄
で、
>>808 が順番変えればいい、と書いたから変えても不可能と言っている
飛ばすってのは、typename T, typename U という順番だと T を指定せずに U を指定するのは文法的に無理、 ってことをいいたいわけじゃなかったのか?
やっぱり楽なほうを選ぶよな〜w それは同意せざるを得ない
C++って高脳用言語だよな、それを低脳が使うと悲劇が起こるよな。 でも、日本ではPGって低賃金・底辺職業だから、高脳すくないよな。 とか、言っている俺は低脳なのにC++を使い糞コードを書いて悲劇をよく起している。 最低でもライブラリは高脳が作って欲しいよな。すると、俺の悲劇も少しは減るのにな
>>840 そうだけど?
で、それならUを前に→それも別の問題で不可能
だから飛ばす方法は無いってことがそれまでのレスで明らかだっただろ
>>842 boostが高脳過ぎて俺の脳が沸騰しそうです
>>841 楽な方というか、開発効率が良い方を選ぶよ
C++って低脳には開発効率悪すぎ。
>>843 Uを前に持って来た時点で、Tを「飛ばす」ことにはならないわけで。
Tの方が後ろにあるんだから。
開発効率なんて「使える」ライブラリがどれだけ充実してるかに結構寄るから その点で言うと仕事で使うC++なんてSTLすら不可だったりして最悪だと思うよ
STLが不可って組み込みか? そうでないのにSTL不可とするとどんな低能集団だよ・・・。
>>846 まだ理解出来ないのか・・・
順番を入れ替えても無駄なのは事実
書き方こそ違えど今の所妥当なのは
>>780 の方法
もうお前にレスしないから好きに煽ってもらって結構
>>849 引数の型を書かずに飛ばすのが不可能なのが問題なんじゃなくて、
その他の解決法が今回の場合使えないというのが問題の本質だろって話だ。
852 :
デフォルトの名無しさん :2008/05/10(土) 01:10:04
STLは開発効率が良い
MFC(笑) まぁでもSTLが標準に入って、浸透するまでの間、 Windows限定ではあるもののライブラリとして頑張ってた方だな。
CString は string より便利な所もあるからまあいいんだけどね。 GetBuffer とか string にはできない芸当だ。
>>854 けどVC6.0のだとバグがあると言う罠
今でも欠陥品といえるSTLがさらに欠陥品だった頃のものを挙げられても… 第一VC6ってC98以前のものじゃない
s/C98/C++98/
kwsk
>>853 MFCがC++のより良い使い方の普及を邪魔したんじゃねなんて、おれは思ったりする。
あれ、C with Class 用ライブラリじゃね。ほとんどAPIの簡易ラッパーだぞ。
低脳がライブラリ作ると....の良い見本と低脳な俺は思っている。
>>856 いや、最近働いたプロジェクトでもまだ現役だったりするw
>>860 CStringのメモリリーク
文字列指定してインスタンス化したとき、だったかな? 詳しい内容は忘れたw
調べてみるか・・・。
>>863 ひょっとして、こんな感じ?
LPWSTR* ポンタ= ::CommandLineToArgvW(....);
どっかに動的に生成したのは良いが、ポンタ先って誰がどの時点で開放するんだろ?
....
しょうがないな、俺がnew/mallocしたんじゃないが
LocalFree(ポンタ); // これCStringで忘れたんじゃね
>>817 嘘レスしかついてないんでいちおうマジレスしとくと、インクルードガードのそれもダメ。
ちょっと古い入門書や入門サイトの記事で使ってるのが多くて広まってる。なんで
入門記事がそういう名前を使ってたのかは、わからない。最近の記事では修正されてたり、
明示的に予約名についての注意が添えられてたりするみたい。
867 :
866 :2008/05/10(土) 02:31:48
>>865 記憶に残ってる感じでは
CString tmpstr("abcde");
とかすると残るらしい
>>866 お前いい事言うな。
やれんのか?
なら今すぐやれ。
まぁ今 C++ 使ってる人は STL+boost あたりで楽できるところは 楽してるんないかな。俺もそうだけど。結構快適。
871 :
719 :2008/05/10(土) 12:56:47
#include <iostream> int to; int from; int tmp; .... // str_length には文字列strの長さが入っている for(to=0; to<str_length; to=from) { tmp = to; from = tmp + 1; if(str.find("あ", to, from)){ cout << "a" << '\n'; } } これは文字列strの中で"あ"が出てきた回数分だけcout << "a" << '\n' を実行するプログラム、のつもりで書いたのですが、思ったとおり動作しません。 具体的には、どんな文字でも"あ"にヒットしてしまい、strの長さ分、 cout << "a" << '\n' が実行されてしまっています。 どなたかアドバイスいただけると幸いです。
find の戻り値が何なのかちゃんと調べれ
874 :
872 :2008/05/10(土) 13:46:52
ぐはっ ありがとうございましたorz
あと、文字コードは何だ? Unicode じゃないと変な結果になることがあるぜ。
876 :
872 :2008/05/10(土) 13:55:15
ありがとうございます。 sjisです。 文字コードはそのうちutf-8にまとめて変えようと思っているのですが、 if(str.find("あ", to, from)){ の部分を if(string::npos != str.find("あ", to, from)){ にしたら、とりあえずsjisでも今のとこ意図した通りに動きました。
まあ、たまたまだな。 「あ」なら大抵大丈夫だろうけど、 「い」だとヤバいな。 "Bob「ハロー」" から "い" を検索してみれ。
878 :
872 :2008/05/10(土) 14:25:42
おお、2つもマッチしてしまいました。 どっかでコードポイントが重複してるってことですよね。 これは、文字コードをUTF-8にしないと解決できないことなんでしょうか??
string::find を使う限りはね。 SJIS 用の比較関数を使うなら問題は無いが、 どんな関数があるかは環境依存なので何とも言えない。
880 :
872 :2008/05/10(土) 14:39:48
MinGW使ってるのですが、 GCCだとShift Jis 用の比較関数というのはどんなのがあるんでしょうか?? gcc shift jis 比較関数 とかでググってみてもそれらしいのが出てきませんでした。 何度もすいません。
実際にやってないので分からんが MinGW なら VC++ と同様 mbstring.h の _mbsstr が使えないのかな。
882 :
872 :2008/05/10(土) 14:54:07
grep '_mbsstr' みたいなことをしてみましたが、何も出てきませんでした。 MinGWにはないのですかねぇ。 でもUTF-8にすれば全く問題なくなるのなら、そうすればいいだけですね。 色々ご親切にありがとうございますm(_ _)m
とりあえず使ってみて コンパイルエラーになったら使えないと判断すればええ。
C言語でスタックを実装しようと思い、配列による実装と、構造体をノードとしたリストによる実装の 二つを書きました。(array_stack.cとlist_stack.c) スタックを操作する関数が同一であれば、二つの実装を簡単に切り替えられるだろうと考えて、 スタックを利用するソースファイルにincludeされるヘッダーファイルstack.hに、push,pop等の 操作関数を宣言しました。関数の定義はそれぞれarray_stack.cやlist_stack.cでされています。 main.cで#include "stack.h"とし、stack.hで宣言されているnew_stack関数やpush関数を使って Stack *stack = new_stack(); push(stack, 1); といった感じで、スタックを使えるようにしたいと考えています。 Stack型は実装によって実際の型が異なり、typedefで実際の型と関連付けられます。 配列による実装を使いたい場合は、 gcc -o test_array main.c array_stack.c リストによる実装を使いたい場合は、 gcc -o test_list main.c list_stack.c のようにして、プリプロセッサを使わずに、実装を切り替えられるようにする事は可能なのでしょうか。 可能ならば実現方法を教えて欲しいです。 main.cではStackへのポインタしか扱っていないので、できそうな感じがして質問しました。
それでできるはず。やってみな。 さらに、stack.hでStackをstruct Stack;と不完全にだけ宣言しておけば、 main.cの再コンパイルなく2つを差し替えられるようになるはず。
CreateHardLinkについてなのですが bool f; f = CreateHardLink("C:\\A","C:\\B",NULL); を実行すると'CreateHardLink': 識別子が見つかりませんでした と、エラーが出てしまいます。 必要なファイルを#includeしてないから ってのは調べて分かったのですが、一体何をincludeすれば良いのでしょうか ヘルプには Client Requires Windows XP or Windows 2000 Professional. Server Requires Windows Server 2003 or Windows 2000 Server. Header Declared in Winbase.h; include Windows.h. Library Link to Kernel32.lib. DLL Requires Kernel32.dll. Unicode Implemented as CreateHardLinkW (Unicode) and CreateHardLinkA (ANSI). と、ありますので #include <Windows.h> #include <Winbase.h> と、書き加えたのですが"識別子が見つかりませんでした"と変わりませんでした #include <Kernel32.lib> #include <Kernel32.dll> はincludeそのものでエラーが出てしまいます 環境はvista home pro、ビジュアルスタジオ2005のアカデミックです
>>886 WINVERとか_WIN32_WINNTでググれ
888 :
884 :2008/05/10(土) 21:35:13
>>885 レスありがとうございます。
stack.hでstruct Stack;と宣言を書き、両方の実装でstruct Stackを使うように変更しました。
すると、期待通りにプログラムが生成されました。
また、言われたように再コンパイル無しでも上手くいきました。
ありがとうございました。
>>890 なんかネタスレっぽいし
そのスレの
>>40 以降でそんなような流れなのですが
もやもやした会話になってるので、ココで聞いてみました
>>889 this の有無により意味の変わるコードを素で書くことがある。
その場合、他の人がそれを扱おうとした際にバグを埋め込む恐れがある。
893 :
デフォルトの名無しさん :2008/05/11(日) 00:53:34
dequeの最後の番号の配列にアクセスすると落ちるバグ発見しました どうしたらいいでいいですか? vectorでは平気なのに、dequeにすると最終のところが読めないです。 size()-1まではアクセスできるはずですよね?
894 :
デフォルトの名無しさん :2008/05/11(日) 00:55:40
かならず駄目なのではなく駄目な場合があるんです
>>893 とりあえず現象が再現する最小限のコードを貼るんだ
再現性のあるコードうp
std::deque<Hoge*> hoge; hoge.push_back(NULL); hoge[hoge.size() - 1]->Foo(); みたいなことやってんじゃないの?
こういうのって大抵「よーし、見てろ、落ちるコード作ってやるから!」 →あっ、バグが判った。ってなるんだよね。バグが判ることはいいことだが。
バグの九割は自分のせいだよね。テヘ
std::deque<Hoge> d; &d[0]+d.size()-1 とかやってると予想。
unsigned char 型のa,bのそれぞれ上位5bitと3bitを合成した変数を使用したいのですがのような方法があるでしょうか また、aとbの値が変更されたとき、その合成された変数の値も変更されるようにすることは可能でしょうか?
>>901 unsigned char c;
c = (unsigned char)((a & 0xf8) | (b >> 5));
aとbを変更したら、cを再計算すればいい。
C言語で変数の宣言をブロックの途中からでもできるようになったのは C99からだと思うのですが、 ブロック途中で変数宣言したものでも gccでそのままコンパイル通ってしまいます。 hoge.c int main(int argc, char**argv) { Func(); int i = 0; return 0; } gcc -std=c89 hoge.c どうしてなのでしょうか?
>>901 オヌヌメできない方法しか思いつかない。
参照時に合成じゃだめなの?
>>903 コンパイルオプションが足りない
gcc -g -W -Wall -std=c89 -pedantic test.c
とりあえずこれでどうだ
>>224 途中での宣言がgccの独自拡張でもあるからだな、だからそのオプションだと
c89とgccの独自拡張でやることになる
-pedantic -pedantic-errors で独自拡張は禁止できる
追記、両方つけるみたいになってるな -pedantic か -pedantic-errorsです 警告とエラーの違いです
void DataOutputStream::writef(const char*pFormat, ... ){ unsigned char tmp[2048]; va_list argptr; va_start(argptr, pFormat); vsprintf(tmp, (const signed char*)(pFormat), argptr); va_end(argptr); } このコードでコンパイラに異なる 'char' 型へのポインタが混在しているとの警告を受けるんですが どう直したらいいんでしょう?BCC5.5です。
const char*をconst signed char*にキャストするからだろ。
911 :
ブロンズ :2008/05/11(日) 14:59:56
デバッグしてください。
どうしてうまく動かないと思ったのかな? ここにいるおにいさんたちにせつめいしてみよう! OSなどの環境も書くといいかもね!
>>909 signed/unsigned char をただの char にすればいいんじゃない?
>>909 てか、キャストいらなくない?tmpの方ならまだわかるけど。
tmpも特に理由がなければunsignedにしなくていいような。
>>910 ,914,915
ありがとうございました。該当箇所を以下のように修正したら治まりました。
reinterpret_cast<char*>(tmp), const_cast<char*>(pFormat)
> (苦笑)
921 :
デフォルトの名無しさん :2008/05/11(日) 16:54:10
C++の初心者です。教えてください ベースクラス(Base)を継承してサブクラスを2つ作ります(Sub1,Sub2) メインから中間クラス(Chuukan)を呼び出して,そこで色々処理をしたいと思いました。そこで、 //Base.cpp class Base{ }; //Sub1.cpp #include "Base.cpp" class Sub1:public Base{ }; //Sub2.cpp #include "Base.cpp" class Sub2:public Base{ }; //Chuukan.cpp #include "Base.cpp" #include "Sub1.cpp" #include "Sub2.cpp" class Chuukan { Base a[2]; Sub1 b; Sub2 c; a[0] = b; a[1] = c; }; としたところ、コンパイル時に error C2011: 'Base' : 'class' 型の再定義 が出てしまいました。やりたいことは、Chuukanクラスで、Sub1,Sub2クラスをBaseクラスの配列に入れて処理をしたい、ということです。このような場合はどうしたらいいでしょうか?よろしくお願いします。
何でcppをincludeしてるのかお(# ^ω^)?
cppってことはオブジェクト作ってるだろ? Base/Sub1/Sub2を全部hにしてみそ。
924 :
デフォルトの名無しさん :2008/05/11(日) 16:58:14
windowsのAPIでのことなんですが、 CreateWindowでボタンなんかを画面上に作った後、 このボタンを画面上から削除する、または画面全体をクリアするにはどうすればよいでしょうか? どなたか、教えてください。
それとインクルードガードで検索するといいお( ^ω^)
926 :
921 :2008/05/11(日) 17:01:49
>>922 ファイルを分けているからです。
とりあえずヘッダファイルを使わずに書いてみようと思いまして
インクルードガードで検索してみます。
>>923 ヘッダ(.h)にしてみましたが、やはり再定義と・・・
927 :
921 :2008/05/11(日) 17:26:44
インクルードガードで無事解決しました。 Baseクラスが2度インクルードされていたのが原因だったんですね。 勉強になりました。ありがとうございます。
929 :
デフォルトの名無しさん :2008/05/11(日) 18:24:52
文字列を取得するプログラムを作るとします。 配列を使えば、 char str[30]; scanf("%s", str); /* scanfに配列strのアドレスを渡す */ でできますが、ポインタを使った場合、 char *pstr; scanf("%s", pstr); /* scanfにpstrのアドレスを渡す(?) */ では何故だめなのでしょうか? pstrに入っているアドレスをscanfに渡しているので、いけると思ったのですが……。
pstrはどこを指してるのか?
931 :
デフォルトの名無しさん :2008/05/11(日) 18:29:48
>>930 なるほど。最初の時点ではpstrは「00000001」をさしていました。
それでは、どうにかしてscanfでポインタを使って文字列を取得する方法はないのでしょうか?(getsを使えとかはナシでお願いします)
char str[30]; char *pstr = str; scanf("%s", pstr);
933 :
デフォルトの名無しさん :2008/05/11(日) 18:32:30
>>932 やはりそうするしかないのですね。
ポインタの謎が一つわかりました。ありがとうございました。
newかmallocで領域確保で使用し終わったらdeleteかfree
>>931 932 のとおり。
どのみちポインタの先はデータ型である必要がある。
const char* str = "honyarara";
みたいなことの scanf 版を考えてるなら、それは不可。
これは構文上、自動的にデータ型を作ってくれてるだけ。
936 :
デフォルトの名無しさん :2008/05/11(日) 18:39:23
newかmallocで領域確保で使用し終わったらdeleteかfree
とゆーか、平気でバッファーオーバーランなソース提示するなよな・・・
>>937 初心者はどこかでやらかすから、割り切りだよw
いいたい事はつたわるからいいよ
941 :
デフォルトの名無しさん :2008/05/11(日) 21:32:25
ファイルからデータを読み込む部分ですが、ファイルの実際サイズより、格納サイズが8バイト分多くなります。 どのような原因かわかりますでしょうか? vector<int> time; vector<float> rate; HANDLE fp = CreateFile( fname , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_ATTRIBUTE_NORMAL , NULL); while(1){ unsigned long size; int n; float x; ReadFile(fp , &n , 4 , &size , NULL);time.push_back(n); ReadFile(fp , &x , 4 , &size , NULL);rate.push_back(x); if(size==0)break;} cout<< GetFileSize(fp,NULL) << " "<< 8*time.size();
8*
943 :
941 :2008/05/11(日) 21:38:12
GetFileSizeとエクスプローラーでは、53,144バイトと表示されるのですが、 読み込んでみると53,152 になっています。 配列で1個分増えてます。なぜでしょうか?
944 :
デフォルトの名無しさん :2008/05/11(日) 21:39:09
>>942 float + int が8バイトなので、掛けています。
ReadFile(fp , &n , 4 , &size , NULL); if(size==0)break;} time.push_back(n);
>>941 読めなかったときにもpush_back()しているから。
947 :
デフォルトの名無しさん :2008/05/11(日) 21:42:01
あとデータはきっちり 4 + 4の倍数ずつ入っています 余分やエラーは無いはずです。
948 :
デフォルトの名無しさん :2008/05/11(日) 21:44:36
トンクス! 一致しました。
949 :
デフォルトの名無しさん :2008/05/12(月) 01:35:15
ちょっと質問なんですけど、C++の場合、sscanf()に取って代わる 機能って何ですか。"hogestr 0x1234 3456"みたいなトークンの 引数文字列を文字列や数値として切り出して読みたいんだけど。
950 :
デフォルトの名無しさん :2008/05/12(月) 01:36:41
sscanf
istringstream
int main(int argc, char** argv, char** env) こんなmain関数の定義をみかけたのですが、 envって何ですか? こういう定義ってありなんでしょうか? 普通にコンパイルは通るみたいなのですが。
環境変数。
954 :
952 :2008/05/12(月) 02:03:16
>>953 さんありがとうござます。
環境依存でありみたいですね。
変数宣言にextern "C"つける意味ってあるのでしょうか? 関数名はC++でコンパイルするとマングリングされますが 変数名はマングリングされないですよね?
956 :
949 :2008/05/12(月) 02:17:37
>>951 istringstream調べてみました。でもトークンにある要素が有る場合もあれば無い場合もあるし、
書式化での指定も出来ないみたいだし、>>とか演算子オーバーロードして使う系の関数って嫌いなんですよね。
sscanfと比べてメリットなさそうなんでsscanf使います。
外部フォーマットのテキストの読み取りならC++でも普通にsscanfでOK、 自分でフォーマットを決めれるなら、言語関係無く簡単に読めるように 妙なフォーマットにしない方が吉。 例えば空白TABカンマなどを区切り(メタ文字)にして、 要素にはメタ文字を出さない(エスケープする)とか。 要素にメタ文字が入っちゃうExcelのcsvとかは駄目な例。
>>955 All function types, function names, and variable names have a language linkage.
全ての関数型、関数名、変数名は言語リンケージを持つ。
変数名も当然マングリングされる可能性がある。
名前空間とかあるんだし。
>>955 クラス内staticメンバ変数なんかはマングリングされますぜ。
ど素人にHelp、このエラー、宣言されてないってことだろうけど、 MString.cpp:382: error: ‘::Left’ has not been declared token = ::Left(*this, length) ; MString.Hのなかでは、 String& Left(int n = 1) ; friend String Left(const String& s, int n = 1) ; ってある。 どう修正したらいいですか?
this はStringなのか?
964 :
960 :2008/05/12(月) 09:15:32
すみませんでした。 後ろの方で宣言されてました。前に持ってきたら、すんなり通りました。 こんなときはコンパイルどうすんのかな・・・
ostringstream str_stream; str_stream << "abcde"; string* str = new str_stream.str(); みたいな感じで、strを動的確保したいのですが、newの部分でエラーが出てしまいます。 ポインタが返ってきていないからだと思うのですが、このような動的確保をしたい時はどうすればよいのでしょうか??
string* str = new string( str_stream.str() );
>>660 です。
あれから修正を重ねてほぼ動くようになったのですが、1つ問題が発生しています。
数字入力→10桁以上か半角数字以外の時はエラー表示→5件分入力し終わったら降順にソートする
→プログラムを終了するか問う→Y(y)なら終了、N(n)なら最初に戻る、それ以外は質問をループ
ここまでは出来たのですが、終了選択でNもしくはnが入力された時、
1件目の整数入力が飛ばされてしまいます。
どうやら数値の"0"として読み込まれているらしく・・・。
おそらく"s"を初期化出来れば良いと思うのですが、
適当な文字を代入(ex. s='e';)させようとすると、incompatible types in assignmentというエラーが出てしまいました。
ソースは
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6528.txtにあります 。
968 :
965 :2008/05/12(月) 15:36:29
>>966 ありがとうございます!
そうやればよかったんですね。知りませんでした。
>>967 scanfの"%s"は、その後に続くであろう改行を読み取らない
改行が残ったままなので、次のfgetsでその改行(だけ)が読み込まれる
そのjudgeは、1文字も入力されなかったら0を返すぽいから、0が読み込まれたようになるのでは
まぁ、"%s"を"%s "にしてみるといいかもしんない
ところで%sは最後に'\0'の付いた文字列を読み込むので、
1文字分しか領域のない&selectに読み込んではだめだ
1文字なら%cを使え
970 :
968 :2008/05/12(月) 17:15:42
>>969 レス有難うございます。
ただ、どちらの方法も望む動きはしてくれませんでした。
"%s "→質問は繰り返されないが、文字を二回打たないと次に進めない
"%c"→変化なし
原因は改行コードが残っているようなので、これを削除するのが一番なのかと思いましたが、
ググってみてもなかなか見つかりませんでした。何か良い方法はありますか?
ところで970ですが、スレ立ては980か990でよいのでしょうか?
fflush(stdin);
972 :
968 :2008/05/12(月) 17:30:53
解決しました。
scanf("%[^\n]%*c", &select);
の記述で動くようになりました!色々レスありがとうございました。
>>971 すみません、上記の通りです。レスありがとうございました。
>>971 注意書きもなしにそんなものをすすめるなよw
// Open Directoy #include <iostream> #include <windows.h> #define MAX_LENGTH 1024 using namespace std; int main(void) { LPSTR CurDir; DWORD LEN; CurDir = (LPSTR)malloc(MAX_LENGTH); LEN = GetCurrentDirectory(MAX_LENGTH,CurDir); if(LEN == 0 || LEN > MAX_LENGTH) { cout << "Error occured." << endl; free(CurDir); return -1; } ShellExecute(NULL,"open","explorer",CurDir,NULL,SW_SHOW); free(CurDir); return 0; } 以前、さらっと書いたプログラムなんですが、APIを用いずに書きたいのですが、どうやればいいんでしょうか? カレントディレクトリの取得方法が分りません OTL このままでも問題はないんですけど、出来ればAPIを使わずに書き直したいです。どなたかヒントだけでも教えてください
標準C++にディレクトリの概念はない
標準でなくてもいいなら getcwd
>>977 レスありがとうございます!
getcwd でググったところ、いくつかサンプルコードがヒットしたので動かしてみたら、うまくいきました。
> 標準でなくてもいいなら
しかし、これは一体どういう意味なのでしょうか?
文字通り標準関数じゃないということ。 VC++ だと名前微妙に違うんじゃないか?
getcwd でカレントディレクトリを取得したあとエクスプローラでそのディレクトリを開くにはどうしたらいいんだろう? 調べてみたら int system(const char *str) というのが見つかったが、これを使うのか? それとも Exec() みたいなのを使うのか? うーん・・・ 修行し直してきます (´・ω・`)
その辺はC/C++とは関係ないから、Win32APIスレで訊いたほうがいい。
そこまで Windows べったりなら Win32API 使ったのでいいじゃん
system("expolorer .");
数値型変数から文字型変数に変換するにはstatic_castを使えとググったら出てきたのですが、 int test = 123; LPWSTR strtest = static_cast<LPWSTR>(test); MessageBox(0, strtest, L"型変換", MB_OK); 2行目で何故か「C2440: 'static_cast' : 'int' から 'LPWSTR' に変換できません。」と出て変換出来ません。 原因は何でしょうか。
>>984 >数値型変数から文字型変数に変換するにはstatic_castを使えとググったら出てきたのですが、
そんなウソを教えるページを晒せ
文字と文字列は違う
まったくウソは教えてないな。 知識を持たずに読んだ人が勘違いしただけで。
初心者にありがちな勘違いにツッこんでないで、
本題を教えてやれよ・・・。
>>984 stringstream
自分を賢いとかすごいとか思ってる奴が、数多くいて 初心者を馬鹿にすることで自己を保ってる馬鹿がいるんだから仕方がないじゃない
答えだけ教えても何にもならん気がするが、説明するのがめんどい
キーワード教えてあとはググらせればおk 自分なりに調べようとすらしない奴の面倒まで見ることはないと思うよ。 調べた上で分からないことがあれば勿論聞いて良いけど。
答えだけ教えるほうが慢心だと思
994 :
デフォルトの名無しさん :2008/05/13(火) 23:52:12
よーしパパ、reinterpret_castしちゃうぞー。
995 :
984 :2008/05/14(水) 00:44:35
叱咤激励ありがとうございます。 色々試してみて数値型から文字型に変える事自体は出来ましたが、そこから更にLPWSTR型に変える事がどうしても出来ません。 以下を実行すると謎の文字列が出てします。 別のキャスト方法も試しましたが全てコンパイルエラーになりました。 STLを使うのは今回が初めてで、ググってもUnicodeコード例に辿り着く事は出来ませんでした。 因みにUnicode専用プログラムにするためtchar.hはインクルードしていません。 int i = 123; std::stringstream ss; ss << i; std::string mes = ss.str(); LPWSTR omes = (LPWSTR)(wchar_t*)mes.c_str(); MessageBoxW(0, omes, L"型変換", MB_OK);
wstringstreamとかwstringって標準じゃないんだっけ?
>>995 それならLPCWSTRにすればいい。
LPCWSTRは、
1. MessageBoxWの2-3番目の引数の型
2. const wchar_t*のtypedef
const wchar_t*はstd::wstringのc_strが返す型。
>>996 もちろん標準。
それなのにCygwinなんかは持ってなくて殺意を覚える。
998 :
デフォルトの名無しさん :2008/05/14(水) 00:56:40
wchar_tの文字列を確保して、その先頭アドレスを、LPWSTR にいれればいいんじやない?
999 :
997 :2008/05/14(水) 01:00:40
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。