トップページ⇒tech
1001コメント330KB

【初心者歓迎】C/C++室 Ver.54【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2008/05/14(水) 01:00:02
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.53【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1208989385/l50
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0002デフォルトの名無しさん2008/05/14(水) 01:11:50
前スレ>>996はstringstreamやstringの代わりに
(あるなら)wstringstreamとかwstringを使えって意味ね
0003デフォルトの名無しさん2008/05/14(水) 01:14:32
お、995はstringとstringstreamなのか。
wstringとwstringstreamだと思い込んでいた。
0004前スレ9952008/05/14(水) 01:22:30
STLをwstringstreamとwstringに変えてLPWSTRをLPCWSTRに変えたら出来ました。
本当にありがとうございました。

int i = 123;
std::wstringstream ss;
ss << i;
std::wstring mes = ss.str();
LPCWSTR omes = (LPCWSTR)mes.c_str();
MessageBoxW(0, omes, L"型変換", MB_OK);
0005デフォルトの名無しさん2008/05/14(水) 02:21:48
その場合キャストは要らないはず、というか
キャストでなんとかするってのは、はじめのころは
あんまし感心しないコードになることが多い気がする。
0006デフォルトの名無しさん 2008/05/14(水) 04:09:31

◆6月にマネージャパン、月刊アスキー、週刊アスキーの3誌が賞金総額2000万円の「シストレFXグランプリ」を開催
http://system-trading.jp/news/index.php?cID=3

5月22日より登録受付開始、6月2日よりグランプリ開始の予定。賞金総額2000万円。
  デモトレードの優勝者には賞金三百万円がプレゼントされます。


▼トレード部門
初期資産500万円で、デモ取引のトレード収益を競っていただきます。
http://www.fx-gp.com/about/

▼賞金総額
■社長特別賞(シストレソフト買取価格) 10,000,000円
●シストレソフト部門賞 1位300万円 2位100万円 3位50万円
●トレード部門賞 1位300万円 2位100万円 3位50万円
●前期MVP賞 50万円
●後期MVP賞 50万円
0007デフォルトの名無しさん2008/05/14(水) 15:04:43
どこにも情報が無いのでこちらで質問をさせていただきます。
eVC++4.0 にて組み込み開発を行っているのですがどうしても下記のwarningが出てしまいます。

class 'Hogehoge' needs to have dll-interface to be used by clients of class 'Foo'

上記エラーが発生した原因はメンバインスタンス変数を static に変更し、かつ、ポインタ
ではなく実体を持つように修正したからだと思われます。

class Foo
{
public:
Hogehoge *hogehoge;
};
    ↓
class Foo
{
public:
static Hogehoge hogehoge;
};

warningの意味は何なのか? 原因は何なのか? また、解決方法のご存知の方、回答お願いします。
0008デフォルトの名無しさん2008/05/14(水) 16:07:44
strncpy, snprintf, memcpy などの関数でサイズ引数を0にした場合の挙動って定義されてるんでしょうか?
やっぱり自分でチェックした方が無難?
0009デフォルトの名無しさん2008/05/14(水) 18:20:01
>>7
そのメッセージの前に警告番号とか出なかった?
あと警告やエラーはそれのみ?

>>8
それぞれの関数の仕様を確認すること。
「など」に対しては定義されてないので。
未定義や不定の条件に書いて無ければ、サイズ0もOK。
ただしサイズが負の数みたいな、
有り得ない値は逆に、何も書いてなければNG。
0010デフォルトの名無しさん2008/05/14(水) 18:31:03
size_tだから負の値はない。
それでももちろんsize_tで表現できる最大値とか明らかにおかしいだろって値は存在するけど。
0011デフォルトの名無しさん2008/05/14(水) 18:33:43
>>7
Hogeは具体的に何のクラス?
デフォルトコンストラクタがないとか値として持てないクラスじゃね?
0012デフォルトの名無しさん2008/05/14(水) 18:34:27
>>8
ありがとうございます。WG14/N843というのを拾ってきたので読んでみました。

snprintf() についてはサイズ0を指定してもよくて、その場合書き込み先バッファはNULLでもいいみたいです。
strncpy()とmemcpy()ではサイズ0の場合については何も書かれてないので、サイズ0もOKみたいですね。
サイズ0のときにバッファをNULLにしてもいいのかどうかまではちょっとわかりませんでしたが…。

あと、サイズはだいたいsize_tで指定するので負になるという心配はあまりなさそうです。
0013デフォルトの名無しさん2008/05/14(水) 20:26:17
>>12
サイズ0のときはNULLにして良いよ。
サイズ0なら、指定したバッファのアドレス自体にもアクセスしてはいけないから、
アクセスしたら関数側のバグになる。
0014デフォルトの名無しさん2008/05/14(水) 20:55:42
何も書かれてないということは、未定義動作じゃないのかね?
0015デフォルトの名無しさん2008/05/14(水) 21:44:07
派生クラスのコンストラクタから、 初期化リスト?経由で基底クラスのコンストラクタ を呼び、
そこから派生クラスで実装されている純粋仮想関数を呼びたいのですが、不可能でしょうか?
これが出来ると基底クラスのコンストラクタを再利用出来るし、違う処理(初期化)が必要な部分は
仮想関数の実装を変えるだけでいいので便利だと思ったのですが。
0016デフォルトの名無しさん2008/05/14(水) 21:52:47
>>15
できません
基底クラスのコンストラクタ実行中は派生クラスは未構築だからです
0017デフォルトの名無しさん2008/05/14(水) 22:10:34
>>16
やはりダメですか・・・
うーん。自分の設計が悪いせいか、基底クラスのコンストラクタ今一役立たずだな・・・
0018デフォルトの名無しさん2008/05/14(水) 22:18:57
>>7
>warningの意味は何なのか? 原因は何なのか? また、解決方法のご存知の方、回答お願いします。
英文のままですね。英文の意味が判らないのなら鼬害でしょう。
まぁ、静的なメンバ変数は明示的に実体化しないといけないので普通の環境でもリンクエラーになるわけですが。
0019デフォルトの名無しさん2008/05/14(水) 22:22:21
>>17
簡略化した例を示せば賢い人が答えてくれるかも

多分C++ではそういうときにはテンプレートの出番になると思うけど
0020デフォルトの名無しさん2008/05/14(水) 23:36:19
>>14
>何も書かれてないということは
いや、書かれていることになる

上の例で出ている関数などでバッファポインタとバッファサイズを取るものは、
[buf, buf+size) の範囲内がアクセス可能ということを要件としているので、
size==0のときはbufのアドレスが何であれ要件を満たすことになる

>>15
似たようなことをする方法はいくつかある

・仮想関数をvfuncとして、基底クラスにinit()などを用意して、
 派生クラスのコンストラクタから呼ぶ
  ※ 基底ctor -> 派生ctor -> 基底init() -> 派生vfunc()

・基底コンストラクタに関数ポインタ類を渡す

・templateクラスにして継承関係を逆にする
  ※ template<class T> class base : T {};
0021デフォルトの名無しさん2008/05/14(水) 23:40:30
ostringstreamクラスに、
ostringstreamオブジェクトの先頭に任意の文字列を追加できる関数ってありますでしょうか??
探しても見つからなかったのですが。
0022デフォルトの名無しさん2008/05/15(木) 00:02:36
>>21
こんなことならできる

int main()
{
using namespace std;
string t("abc");
ostringstream s;
s << "xyz";
s.seekp(0);
s << t + s.str();

cout << s.str() << endl;

return 0;
}
0023デフォルトの名無しさん2008/05/15(木) 00:07:18
>>21
一応ストリームなんだから、そういう操作は仮に出来ても勧められないな・・・

前後だけで良いならfront側とback側にstringstreamを持ってstr()時に
結合するラッパーを作るという手はある
超手抜きで書くと
struct {
  ostringstream front;
  ostringstream back;
  string str(){return front.str() + back.str();}
};

またはstd::list<std::string>で構築して、必要になった際に全結合するなど
0024232008/05/15(木) 00:10:53
リロードしてなかった
>>22が手軽で良いかもな

それと>>23のfront云々のところは素でボケてたので無かったことに・・・
0025デフォルトの名無しさん2008/05/15(木) 02:38:37
>>19-20
レスありがとうございます。
なるほど、テンプレートや関数ポインタですか。
しかしC++は奥が深そうですね・・・
0026デフォルトの名無しさん2008/05/15(木) 07:14:40
Yo Yo俺ニート!
002772008/05/15(木) 12:11:02
>>9
質問するのに肝心な部分を書いてませんでした。
warning C4251 がエラー番号に該当すると思います。
>>11
規約としてデフォルトコンストラクタ、デストラクタは定義
しなければならないのでその点は問題ありません。
>>18
>まぁ、静的なメンバ変数は明示的に実体化しないといけないので普通の環境でもリンクエラーになるわけですが
cppファイル内で実体化させているのか、という意味ならば実体化させているので
その点は問題ないように思います。
試しにstaticをはずしてみたのですが、同様のエラーでした。

NULLチェックやdelete処理などが面倒なので実体を持つようにし、かつ、1つのシステム内で
唯一1つのインスタンスしか使用しないのでstaticで良いじゃないか?
staticにするとわざわざどこかのクラスから参照やポインタで辿っていかなくても Foo::hogehoge
とアクセスできるから楽じゃないか?
と安易に思ったのが失敗だったんでしょう。
0028デフォルトの名無しさん2008/05/15(木) 12:14:39
C4251 だけ書いて内容書かないのは、こっちで調べろってこと?
002972008/05/15(木) 12:30:25
>>28
言っている意味がわからないのですが、こちらでどう調査しても
warning C4251: 'hogehoge : 'class 'Hogehoge' needs to have dll-interface to be used by clients of class 'Foo'
しかわからない
上記warningが発生した原因は特定インスタンスメンバをポインタではなく、static かつ 実体として持つようにした
というのは 7 で書いたつもりです。
言葉足らずのところはこちらのミスですので謝りますが。
エラー番号ではなく警告番号でしたが、どう調査してもC4251しかわかりません。
0030デフォルトの名無しさん2008/05/15(木) 12:40:36
>>29
Hohehogeの宣言を晒してくれなきゃワカンネ。
エラーが起こる最小のコードをup
0031デフォルトの名無しさん2008/05/15(木) 12:46:16
平均点の高い順に並べ替えて表示するプログラムを作りたいのですが、結果が表示されません;
どこをどのように直したらいいか教えてください。お願いします。

http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/6554.c
0032デフォルトの名無しさん2008/05/15(木) 12:55:41
>>31
sort()とやらはgccの拡張機能である、関数内関数定義を行っているだけで呼び出していないから。
他にもいろいろ突っ込みどころだらけだが……
0033デフォルトの名無しさん2008/05/15(木) 12:57:32
なんか、ロジックをいろいろ寄せ集めただけっぽいな。
ソートを自分で書くのが目的なら、渡すデータ型に注意だ。
003472008/05/15(木) 13:00:59
>>30
そういうことですか!!
確かに質問するにあたって情報が足りなかったですね。

warningが発生するHogehoge最小ソースは

class Hogehoge
{
public:
Hogehoge(){};
virtual ~Hogehoge(){};
};

です。
0035312008/05/15(木) 13:05:37
>>32
main関数の前に
void sort(int *p,int n);
を付け加えました。

他に間違ってるところってどこですか?
0036デフォルトの名無しさん2008/05/15(木) 13:08:23
>他に間違ってるところってどこですか?
たくさん。あり過ぎて指摘する気にもならん。
まぁ、作った関数は呼ばなきゃ意味がないことくらいは判るだろうから、
後はコンパイラのエラーメッセージをよく読んで順に潰せ。
そうそう、gccを使っているだろうから、gcc file.c -ansi -Wall -pedanticすることをお勧め。
0037322008/05/15(木) 13:10:43
>>35
私の指摘をちゃんと読んでますか? 「関数呼び出し」って、理解できますか?
0038デフォルトの名無しさん2008/05/15(木) 13:11:36
class HogeHoge
{
public:
HogeHoge(){};
virtual ~HogeHoge(){};
};

class Foo
{
public:
static HogeHoge hogehoge;
};

int main ()
{
Foo myClass;

return 0;
}
問題なく通るけど…
0039382008/05/15(木) 13:14:35
VC++2005EE
0040322008/05/15(木) 13:15:08
>>34
>38だとhogehogeの実体を参照しないからエラーにならないかと。
Hogehogeだけ抜き出さずに、実際にそのエラーが出るソースを作って貼ってみては?
004172008/05/15(木) 14:08:53
さらに色々調査してみたところ、ソースコードというよりも環境が怪しい気が
してきました。
もう少し調べてみます。
0042デフォルトの名無しさん2008/05/15(木) 14:10:17
もうこなくていいよ
0043デフォルトの名無しさん2008/05/15(木) 15:58:58
>>7
C4251でググったりはしたよね?
0044デフォルトの名無しさん2008/05/15(木) 16:09:49
> HogeHoge(){};
> virtual ~HogeHoge(){};
セミコロン要らないだろ
0045デフォルトの名無しさん2008/05/15(木) 17:54:36
struct point{
double x;
double y;
};


struct point q[200];

memcpy(q,p,(n+1)*sizeof(struct point));

これってどういう事をやってるんですか?
0046デフォルトの名無しさん2008/05/15(木) 18:02:55
pが指す所から(n+1)*sizeof(struct point)バイトqの所にコピーしてる
0047デフォルトの名無しさん2008/05/15(木) 18:08:27
>>45
恐らくはstruct point * pがあるとして、
先ずはpoint構造体の要素数200の配列qを宣言している。
続いてその配列qに、point構造体(n+1)個分のデータを配列pからコピーしている。
この部分は、for (int ic = 0; ic < n + 1; ++ic) q[ic] = p[ic];とほぼ同等。
0048デフォルトの名無しさん2008/05/15(木) 18:19:35
すいません。

int func(int n,struct point p[],double d){
struct point q[200];

;
memcpy(q,p,(n+1)*sizeof(struct point));


}

みたいに構造体が引数で渡されています。
0049デフォルトの名無しさん2008/05/15(木) 18:21:52
>>48
「構造体」ではなく、「構造体へのポインタ」ね。つまりは、>47。
0050デフォルトの名無しさん2008/05/15(木) 18:24:31
なるほどわかりました。

実際のpの大きさがソースを書くときには不定なので、
for文での代入をしていないってことでしょうか?
0051デフォルトの名無しさん2008/05/15(木) 18:27:58
>>50
いや違う。pの大きさは、常に一定だ。何故ならpはポインタ変数だからだ。
pが指す領域のサイズについてはnに依存するわけだが、forループでも勿論巧くコピーできる。

では何故memcpy()を使うかというと、保守性よりも(見かけ上の)効率を優先したか、単に習慣か、
書いた人間にでも聞かないと判らないだろう。
0052デフォルトの名無しさん2008/05/15(木) 18:29:13
for文で1個ずつでもいいけど、丸ごと全部いっぺんにやったほうが早いべ
0053デフォルトの名無しさん2008/05/15(木) 18:42:40
いいえ、一概には言えません。まともなコンパイラにまともに最適化させてやれば恐らくは、目に見える速度差はないでしょう。
0054デフォルトの名無しさん2008/05/15(木) 18:46:59
書く量だって少ないし、コーディングも早いだろ。
0055452008/05/15(木) 18:49:17
いろいろ教えていただきありがとうございました。

0056デフォルトの名無しさん2008/05/15(木) 19:00:21
>>54
>memcpy(q,p,(n+1)*sizeof(struct point));
39文字
>for(int i=0;i<n+1;++i)q[i]=p[i];
32文字
0057デフォルトの名無しさん2008/05/15(木) 20:30:03
VC++でインラインアセンブリを使うとき、
疑似命令によくある、生データを直接コードに埋め込む事って、どのようにすればいいのですか?
テーブル参照のようなことを仕様と思ったのですが、やり方がよくわからなくて…
0058デフォルトの名無しさん2008/05/15(木) 20:34:29
>>53
逆に言えば
memcpyみたいな動作をする命令があるから、
まともでない(古い)コンパイラだとfor使うより遙かに速く動作する

そういう意味では書く人の習慣の影響が強いが
0059デフォルトの名無しさん2008/05/15(木) 22:04:53
だんだんコンパイル速度が遅くなってきたので、参照箇所の
多いクラスにPimplを導入しようかと思ってるのですが、Pimplに
すると問題のあるケースなんてのもあるんでしょうか?
0060デフォルトの名無しさん2008/05/15(木) 22:11:37
>>56
>memcpy(q,p,(n+1)*sizeof(*p));
29文字
0061デフォルトの名無しさん2008/05/15(木) 22:27:54
std::copy(p,p+n+1,q);
21文字
0062デフォルトの名無しさん2008/05/15(木) 22:45:30
>>59
pimplを経由することによる性能上のオーバーヘッド
0063デフォルトの名無しさん2008/05/15(木) 23:02:23
>>59
メモリ確保のオーバーヘッドと、メモリ確保に失敗する可能性の増加。
0064デフォルトの名無しさん2008/05/15(木) 23:23:16
>>62,63
なるほど。速度が重要な物や大量に生成される物には
避けた方が良さそうなんですね。
0065デフォルトの名無しさん2008/05/15(木) 23:24:01
>>59
仮にPimplによる問題が出ても、
大した手間無く対処出来るから気にする必要無いよ。
0066デフォルトの名無しさん2008/05/15(木) 23:36:11
>>59
相互参照の必要な場合が多いとソースが汚く見えるようになる。
0067デフォルトの名無しさん2008/05/16(金) 02:57:03
すいません、質問お願いします。
独習Cで勉強しているのですが、月での実効体重だす問題で関数を作ったのですが
float moon(void)
{
float weight;

printf("体重を入力してください:");
scanf("%f",&weight);
return weight*(17/100);
}

という関数を作った時に
「return weight*17/100」や「return weight*0.17」時は正しい値を返してくれるのですが、
自分が分かりやすいように式を()で囲うと正しい値を返してくれずに0.00000という値が返ってきます。
理由がわからないのですが、どなたか分かる方教えて下さい。
■ このスレッドは過去ログ倉庫に格納されています