スレを勃てるまでもないC/C++の質問はここで 2 at TECH
[2ch|▼Menu]
1:デフォルトの名無しさん
07/05/07 11:02:46
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。

スレを勃てるまでもないC/C++の質問はここで
スレリンク(tech板)


2:デフォルトの名無しさん
07/05/07 18:25:57
dynamic_castってどんな時に有用なのですか?

3:デフォルトの名無しさん
07/05/08 10:13:05
forループをインテルコンパイラを使いSSEで並列計算させるようにしています。
floatはdoubleの倍並列度が上がるはずなのですが、floatにしてもループの計算速度が
1.2倍程度にしかなりません何故なのでしょう
ループの中身は主に画像処理で、ほとんどが三角関数です。

4:デフォルトの名無しさん
07/05/08 10:42:37
注:私の有意義な発言に対し、自分の理解不足を棚に上げ煽り、1行レス
で返す方が多いようですが、そのような方はスレの皆様を混乱させるだけでなく
スレの雰囲気を崩しかねないのでお黙り下さい。
また質問者は回答者に知識を披露する場を与える貴重な存在なので、
質問者を見下した回答、あまりにも儀礼を欠いた回答も厳重に禁止いたします。
忙しい中、少ない時間の合間を縫って質問しに来てるわけですので、
その辺ご承知下さい。なお、当方が質問に対して有意義な答えであると
判断した方には評価いたしますので各自よく調べ、よく考え正確な回答をするように。

5:デフォルトの名無しさん
07/05/08 10:56:12
>>2
dynamic_castにより、従来のキャストでは不可能であった クロス・キャスト、
そして抽象基底クラスからのダウン・キャストが可能になりました。


6:デフォルトの名無しさん
07/05/08 11:02:51
>>3
近年のプロセッサではdoubleの計算速度はfloatとあまり変わらないためです。

7:デフォルトの名無しさん
07/05/08 11:11:21
うそつき

8:デフォルトの名無しさん
07/05/09 01:10:40
>>3
一応マジレスしておくと、その情報だけでは一概に言えないとしか。
「演算速度」と一口に言っても実数計算だけしているわけではないから1.2倍なら御の字だろう。

処で、まさかとは思うがfloat版でもsin()を使っちゃいないよな?

9:デフォルトの名無しさん
07/05/09 12:34:09
>>3
45度分の三角関数表ぶち込んで置くのオヌヌメ

10:デフォルトの名無しさん
07/05/11 11:37:54
>>8
c99にはsinf()などのfloat専用関数があるのに意外に知られてないよね。

11:デフォルトの名無しさん
07/05/13 23:47:46
タスクを意識したプログラムを仕事で使うので勉強しています。
ディスパッチていう関数とアイドルタスクの実行関数ってのがあって
main関数で、初期設定(アイドルタスクのTCBの設定)をしてから、
ディスパッチの関数をコールすると、
そのディスパッチの関数がリターンされると
アイドルの関数を呼び出してもいないのに、
アイドルタスクが実行されました。
さっぱりわからないんですけど、こういうのって
普通のつくりなんでしょうか?


12:デフォルトの名無しさん
07/05/14 01:25:43
>>10
C++だとsinでfloat版も多重定義されていることも意外に知られていないよね
勿論3がCとC++のどっちを使っているのかはわからないけど

13:デフォルトの名無しさん
07/05/14 16:08:02
>>11
よーわからんが、「ディスパッチ」というからには
「何かが起きれば対応する処理を呼び出し、
 何もなければアイドル処理を呼び出す」のは
極々ふつーかと。

14:デフォルトの名無しさん
07/05/15 18:40:58
Borland C++をつかってピアノをシミュレートするプログラムを組もうと思ってます。
つまり、キーボードAでドの音、キーボードSでレの音、キーボードDでミの音をだすわけです。

初めはDXライブラリつかってAキーを押したらあらかじめ用意してあるドの音が記録された
wavファイルを再生しようと思ってました。

しかしながら、これだとキーを押している間のみ音を出す事ができないわけです。

そこで、wavファイルを再生するという方法を諦め別の方法を考えてるわけですが、
なにか良い方法はないでしょうか?


15:デフォルトの名無しさん
07/05/15 18:43:25
簡単なのはMIDI使うやつだなあ

16:デフォルトの名無しさん
07/05/15 18:47:20
>>14
単純な音でごく簡単にやるなら、Beep()を使うのはどうだろう。
それはさておき、なんでDXでwav再生だと「きーを押している間のみ音を出せない」のだろう……

17:デフォルトの名無しさん
07/05/15 18:53:31
なんで組み込み系の型は継承できないの?

18:デフォルトの名無しさん
07/05/15 18:57:49
>>15
ありがとうございまする
C++からつまりMIDI音を生成できるというわけですか。ちょっと調べてみます。
>>16
ありがとうございます
さすがに、Beepでは。せめてMIDIくらいはクオリティ欲しいです。
「きーを押している間のみ音を出せない」はたぶん誤解していらっしゃるみたいです。
つまり、ドの音がwavに6秒記録されていて、Aキーを1秒間しか押してなくても
6秒再生されてしまうわけです。

”押している間のみ音を出す”という事ができないわけです




19:デフォルトの名無しさん
07/05/15 19:03:15
「押している間のみ音を出すことができない」は、「離したら音を止めることができない」と言いたかったわけねw

短めのwavを用意して、キーリピートのたびに繰り返すなり、再生を途中で止めるなりすればいいのでは?

20:デフォルトの名無しさん
07/05/15 19:08:56
>>17
C++は効率も重視してるので、そのような設計になっている。
ってのが模範解答かな

21:デフォルトの名無しさん
07/05/15 22:49:44
C言語で
1 -0.5から0.5までの間のdouble型の乱数の発生のさせかた
2 0から1までの間のdouble型の乱数の発生のさせかた

を教えてください。rand()関数を使うなどの簡単なプログラムの方がありがたいです。
ググって見たら、整数の乱数の発生させかたは幾つか見つかったのですが
小数の乱数の発生させかたを見つけることができませんでした。
よろしくおねがいします。

22:21
07/05/15 22:58:43
書き忘れてました。

毎回同じ乱数で大丈夫です
よろしくお願いします。

23:デフォルトの名無しさん
07/05/15 23:46:25
>整数の乱数の発生させかたは幾つか見つかった
これが分かって、何で
>1 -0.5から0.5までの間のdouble型の乱数の発生のさせかた
>2 0から1までの間のdouble型の乱数の発生のさせかた
これがわかんないんだ?
ちょっと考えれば分かりそうなもんだが…

24:デフォルトの名無しさん
07/05/15 23:54:53
応用力のないゆとり

25:デフォルトの名無しさん
07/05/16 00:39:24
>>21

ゆとり教育の弊害か?

こういう調べ方もわからない香具師はなにかに躓くたびに
同レベルの質問するんだろうなw


26:デフォルトの名無しさん
07/05/16 00:53:20
まあきっとリア消なんだろうと思って免じよう

(double)rand() / ((double)RAND_MAX + 1)
これで0以上1未満の乱数になる。1を加えなければ、範囲が0以上1以下になる。
あとは0.5を引けばいいだけ。

27:デフォルトの名無しさん
07/05/16 01:00:42
>きっとリア消
そうかな? 文章の書き方はもう少し上の年齢を感じさせるが。
だからこそ応用できないのが残念というか不思議というか…

28:18
07/05/16 01:55:47
たぶん、基本的な型変換の知識が欠如してるかと思われます

29:21
07/05/16 06:31:24
みなさんすいません。つい最近C言語を始めたばかりで何もかもがチンプンカンプンな30歳です。
整数しかなくても乱数の中の最大値で割れば小数に変換できるってことですね(RAND_MAXっていうのは乱数の
中の期待される最大値ってことですよね・・?)。
こんな風にできるのか。勉強になりました。ありがとうございます

30:デフォルトの名無しさん
07/05/16 06:43:52
1、機能設計
2、関数(クラス)設計
3、実装
4、レビュー
5、1にもどる
これを繰り返しやってるんだが効率が悪い気がする
なんかいいプログラム方法ってないの


31:デフォルトの名無しさん
07/05/16 06:49:36
>>30
1. なんとなく実装
2. バグ取り

これなら効率よく見えるかい?w

32:デフォルトの名無しさん
07/05/16 10:22:27
作業の合間の2chをなくせば効率は少なくとも5割アップする。
間違いない。

33:デフォルトの名無しさん
07/05/16 10:29:14
今は、2chの合間の作業だからなあ

34:デフォルトの名無しさん
07/05/16 10:50:43
C初心者です。
ググッていたら
int PASCAL WinMain
なんていうmain関数見つけたのですが、なんでCなのにパスカルなんですか?

35:デフォルトの名無しさん
07/05/16 10:54:07
>>34
CDECL、PASCAL、STDCALLあたりで調べてみな

36:デフォルトの名無しさん
07/05/16 22:48:12
#include <stdio.h>
int main(void)
{
int data[ ] = { 7,4,12,71,3,85,69,47,11 };
int i, j=0;
  printf("prime =");
while(j<10){
for(i=3;i<data[j];i++){
if(data[j]/i!=0)
i++;
else(data[j]/i==0)
printf("%d\n",data[j]);
}
j++;}
  return 0 ;
}

数字の中から素数を出力するプログラムを作りたいのですけど
ステートメントにセミコロンがないとエラーが出てしまいます。
セミコロンは忘れずにつけているはずなのですが・・・
どなたか教えてください。よろしくお願いします。

37:デフォルトの名無しさん
07/05/16 22:51:41
else(data[j]/i==0)

38:デフォルトの名無しさん
07/05/16 22:54:41
>>37
理解できました。
/じゃなくて%使わないとだめだったのですね
ありがとうございます。

39:デフォルトの名無しさん
07/05/16 22:58:09
それでいいんなら構わないんだけど・・・

40:デフォルトの名無しさん
07/05/17 10:29:49
>>36
一応マジレスしておくと、慣れない内はif, for, whileなどには必ず{}をつけるようにした方がいいぞ。
それと、{}の位置は対応が見つかりやすい位置に揃えておくこともね。

41:デフォルトの名無しさん
07/05/19 04:38:09
以前、Visual Studioの6.0を使っていたのですが
CDが無くなって見つからなかったせいもあり、
せっかくだから新しいのを買おうとVisual Studio 2005を買ってきたんです。

ところが、簡単なプログラムを組んで知人に渡すと
「このアプリケーションの構成が正しくないため、アプリケーションを開始できませんでした。」
と出て、実行できないとのことなのです。
調べてみると、VCの新しいランタイムを入れなければいけないとのこと。

VC++6の頃は、こんなのが出た記憶がなかったのですが、
それは、VC6が古かったのでランタイムが既に入っていただけなのでしょうか?

大半の人がランタイムを入れないと動かないというのは、好ましくないのですが
2005を使う利点というのは、どの程度あるのでしょうか?
単にフリーソフトを作って配布するだけならば、VC++6でも十分なのでしょうか?

また、持ってないのでなんともいえないのですが、VS2003についてはどうなのでしょうか?

場合によっては、2005を誰かにでも売って、2003を買ってくるなり
VC6をもう一度探してみるなどの手段を講じようと思っております。

どなたかよろしくお願いいたします。

42:デフォルトの名無しさん
07/05/19 05:28:33
>単にフリーソフトを作って配布するだけならば、VC++6でも十分なのでしょうか?
Yes

つーか俺は VS2003proとか持ってるけど、
未だにC++は VS6.0でやってる
メインの開発マシンが pen3 1GHzのノートだってのも理由だけど

43:デフォルトの名無しさん
07/05/19 10:08:05
2005はランタイムにDLLを使うのが初期設定になっただけで、
プロジェクトオプションをいじれば、
従来どおりラんタイム (CRT)を静的リンクしてEXE内に含めることも可能。

.NET 2003のデフォルトは静的リンクだが、
動的リンクした場合は、やはり2005同様ランタイムを別途入れないといけない。

6では静的リンクがデフォルトだったと思うが、
動的リンクしても、ランタイムのmsvcrt.dllが殆どのWindowsで初めから入っているため問題になりにくい。

いずれにしても、ランタイムのDLLをEXEと同梱して同じフォルダにおいても使える。
2005はマニフェスト書かないといけないから若干面倒だけど。

44:デフォルトの名無しさん
07/05/19 13:53:17
静的リンクで、サイズがあまり大きくならなければ
EXE内に含んでしまうのも手ですね…
VC6のときは、そういった問題が起こらないのもそういう理由だったのですね。

それにしても…全然VC6でも未だにいけるんですな。
何のために2005買ってきたんだろう…
2005だとこれがいい!とか、これがあるから2005にしとけ!
っていうのはあります?

45:デフォルトの名無しさん
07/05/19 14:10:32
すばらしいC++/CLIが使用できます!

46:デフォルトの名無しさん
07/05/19 15:57:41
テンプレートやそれを使うライブラリ(Boostなど)がまともに使えるようになる。
(たしか2002と2003の間に越えられない壁)
あとは最適化の能力も着実に上がっている。

47:デフォルトの名無しさん
07/05/19 17:45:35
古いMFCって色々バグなかったっけ

48:デフォルトの名無しさん
07/05/20 19:33:33
>>44
VS6の場合、WinXPから実装されたような新しいAPIはヘッダにない
有名だけど、VS6のSTLはバグあり


49:44
07/05/20 22:14:08
>>45-47
単語を元に色々見てみました。
バグや最適化のことも考えて2005のライブラリ同梱でいこうと思います。
せっかく買ったことですしね。

C++/CLIについては、今やってるものが終わったら
一旦勉強してみたいと思います。
どうも昔ながらのBASICやらCが染み付いてしまってるので
なじめるか心配ですが・・・・

ありがとうございました!

50:デフォルトの名無しさん
07/05/25 01:03:52
UTF-16LEでかかれたファイルを1行ずつ読み込んで処理したんです。
std::wstringをつかってどうにかできませんか

51:デフォルトの名無しさん
07/05/25 01:17:46
>>50
×処理したんです
○処理したいんです。
orz

52:デフォルトの名無しさん
07/05/25 18:26:16
>>50
お前の使うCPUがリトルエンディアンで、
お前の使う処理系でのwchar_tがUTF-16なら、
std::wifstreamでバイナリモードにすれば大抵上手くいくと思う。

53:デフォルトの名無しさん
07/05/25 18:54:20
こんにちは。
大量の浮動小数データをCSV形式でファイルに出力する必要があるのですが、
文字列の生成に時間がかかってしまい困っています。
出力する必要のある浮動小数データ数は5憶個くらいです。
sprintfとstrlenで時間がかかるのはわかるのですが、
何か良い方法はないものでしょうか?
---
char buf[4096];
DWORD temp;
for (int i = 0; i < 100; i ++) {
// 行番号の出力
sprintf(buf, "%.3f,", 値);
// 各列の値出力
for (int j = 0; j < 100; j ++) {
sprintf(buf+strlen(buf), ",%.14f", 値);
}
// 改行コード
strcat(buf, "\n");
// ファイル出力
WriteFile(m_hFile, (LPVOID)buf, strlen(buf), &temp, NULL);
}
---
#bufサイズの件については考えていません。


54:デフォルトの名無しさん
07/05/25 19:02:02
ループ中のstrlenを止めるだけで結構変わる悪寒

55:デフォルトの名無しさん
07/05/25 19:16:10
>>53
出力サイズ(=buf内の文字列長)を常に保持するようにすればstrlen()は全く要らなくなる。
#それでどれだけ速くなるかは知らんが。

寧ろ、もそっとこまめにWriteFile()した方が速くないかい?

56:55
07/05/25 19:16:51
あー、最後の一行無視しておいて。

57:デフォルトの名無しさん
07/05/25 19:33:20
>>53
strlenやめたコードで16MBくらいのデータを出力してみたが、
ぶっちゃけHDDの速度に依存してる感じだ。w
あんまりかわらんね。

58:デフォルトの名無しさん
07/05/25 19:44:13
>>53
散々言われているがファイルの書き込みを考えたほうがいい
メモリマップドIOにするなり別スレッドで書き込むようにするなり

59:53
07/05/28 12:02:35
皆様有難う御座います。

文字列の長さを変数に保持して、新たに追加された文字列分だけ
strlenするようにしても対して効果はありませんでした。
#皆さんの答えで一つわからなかったのですが、
#sprintfで何文字で出力されるかわからないので完全にstrlenを
#除去出来ないですよね?

プロファイルを取って調べた処、7割の時間をsprintfで
消費している事がわかりました。

数値を文字列に高速に変換する方法などあれば解決しそうですけど
なかなか考えつきませんね。。

60:デフォルトの名無しさん
07/05/28 12:17:03
>>59
少しは調べる努力もしよう。
-- from MSDN
>戻り値
>書き込まれた文字数を返します。
-- from www.linux.or.jp
>返り値
>成功時には、上記の関数は書き込まれた文字数を返す (文字列の最後を示すために使用する `\0' は数に含まれない)。

61:デフォルトの名無しさん
07/05/28 12:28:24
>>53
今ちょっと実測してみたんだけど、数値の範囲にも拠るけど
桁数が増えるとパフォーマンスにかなり影響する。
%.14fを例えば%.13fや或いは%.14gに変えられないの?

62:デフォルトの名無しさん
07/05/29 10:08:31
まあsprintfの戻り値使えばstrlenはいらないけど、たいした節約にはならんような。
自前でftoa()でも作ってしまうとか。
10^n掛けていって整数部分を取るような。

63:デフォルトの名無しさん
07/05/30 02:14:35
Cの場合は
void 関数名(void);
じゃないと警告出ますよね
C++の場合
void 関数名();
で、警告出ないんですけどvoidは入れた方が良いんですか?

64:デフォルトの名無しさん
07/05/30 02:20:12
>>63
C++の場合はvoidを書かなくても書いた場合と同じとなってますが、
Cとの互換性を考えるなら書いた方がいいかもしれません。

65:デフォルトの名無しさん
07/05/30 07:46:02
>>64
分かりました。ありがとうございます。

66:53
07/05/30 13:56:24
sprintfの戻り値が出力数とは目から鱗でした。

最終的にstrlenの除去と、出力を%.7fにする事で
文字変換のコストを10%程度削減出来ました。
ファイルへの出力も逐次出力するのをやめた所
全体で30%程度処理時間を短縮する事が出来ました。

皆さんありがとう御座いましたm(__)m


67:デフォルトの名無しさん
07/05/30 21:54:37
誰か教えてくれ。
次のようなコードをたまに見るんだけど、なんか意味はあるのだろうか。

for (int i = 0; i < 3; i++) {
 swtich (i) {
  case 0:
   printf("%d\n", 2);
   break;
  case 1:
   printf("%d\n", 3);
   break;
  case 2:
   printf("%d\n", 5);
   break;
 }
}

単純に逐次処理で
   printf("%d\n", 2);
   printf("%d\n", 3);
   printf("%d\n", 5);
としたほうが分かりやすいと思うんだけど。


68:デフォルトの名無しさん
07/05/30 23:11:35
書いた本人は、処理の数が膨大な数になり且つ、もしcase以降の処理の順番を入れ替える事態が発生した時の
保守のし易さにでも重点を置いたんだろう。
あんたの見たその時の状況を知らないからなんとも言えないが、もし枝分かれが指折り数えるくらいなら意味ないね。

69:デフォルトの名無しさん
07/05/31 03:48:55
上の質問と被ってしまうような気もするけど・・・気にしない。。

switch(CHECK)
   {
      case 1:
            break;
      case 2:
            break;
   }

これを

switch(CHECK)
   {
      case MENU:
            break;
      case END:
            break;
   }

こういう風にしたいのですけどCHECKの型を何にしたら良いのでしょうか

70:デフォルトの名無しさん
07/05/31 06:41:09
int

71:デフォルトの名無しさん
07/05/31 07:27:36
すごいくだらない質問なんですが、
CをどこまでやったらC++に移っても問題ないのでしょうか?
入門書を一通り終えたらC++に行っちゃって大丈夫なんですか?

72:デフォルトの名無しさん
07/05/31 07:40:47
>>66
ていうかさ、なんでstdioを使わないでAPIを直接使ってるの?

初心者にありがちな間違いだけど
「FILE*を使うと直呼び出しに比べてオーバーヘッドがある」という点より
「FILE*を使うと内部でバッファリングしてくれるので呼び出し回数が減り、結果的に速くなる」
というのが正しいから。

ファイルマッピング使っても、本質は同じ。
もちろん、ディスクアクセスがunmap時のみに出来る(量)なら充分だけど
そうでなければ、結果的にシステムコールを減らせるほうが速いから。
setvbufを使ってもいいし。

sprintfの戻り値の件もそうだけど、知らないで思い込む(=調べない)と損だよ。

73:デフォルトの名無しさん
07/05/31 09:48:11
>>69
enum の出番だ
まあ>>70の通りだ

74:デフォルトの名無しさん
07/05/31 10:49:13
ちょっと疑問なのですが、
char *str = "ABCDE";
のような宣言のとき、 "ABCDE"という文字列がstrに入った☆
なーんて説明されたんだが、既に納得がいかない。

・str自体は、先頭の'A'のポインタが入ってるはず。
・char型を5個連続で確保できる保障なんてあるのか?
・無かった場合、どっかのデータ壊すんじゃないのか?
・何か俺勘違いしてるのかな・・・?

教えてくださいエラい人・・・。

75:デフォルトの名無しさん
07/05/31 10:53:25
>>74
まず、リテラルの"ABCDE"を格納している領域があって、そのアドレスがstrに入るだけ。

char str[] = "ABCDE";だと6個の領域がローカルに確保されてリテラルの"ABCDE"から
内容がコピーされる。

76:デフォルトの名無しさん
07/05/31 15:36:13
ローカルのは処理系依存だな
単にcharの配列の初期化になるだけとか

77:デフォルトの名無しさん
07/05/31 17:15:53
>>76
>ローカルのは処理系依存だな
意味不明。

78:デフォルトの名無しさん
07/05/31 21:48:06
>>75 >>76
ありがとうございました。


79:デフォルトの名無しさん
07/05/31 23:19:56
質問です。
"<列番>,<行番>,<顧客名>" という形式で入力されるデータを
行列ソートされた状態で変数に格納しようとしています。

map型でキーを2つ使う事は出来るのでしょうか?
より簡潔に書ける方法があれば、そちらもご教授願いたいです。

80:デフォルトの名無しさん
07/06/01 00:42:12
処理系くらい書けや

URLリンク(www.tt.rim.or.jp)

81:デフォルトの名無しさん
07/06/01 00:54:29
>>79
うーむ、mapが一番楽ではないかな。

82:デフォルトの名無しさん
07/06/01 12:03:48
>>79
std::map<列, std::map<行, 顧客名> > ではあかんの?

83:sage
07/06/01 15:50:28
Windowsのサービスプログラムを作成しています。

Shell_NotifyIconでログインしたときにシステムトレイに
アイコンの表示とポップアップメニューでコントロール
できるようにしたいのですが、サービスではアイコンが
表示できないようでホトホト困っております。

そもそもサービスからシステムトレイへアイコンを表示する場合は
別のプロセスで行わなければならないものなのでしょうか?

ご存知の方、どうぞ教えていただけないでしょうか。

84:デフォルトの名無しさん
07/06/01 15:56:11
>>83
普通そういう構造にはしないけど、だからってできないことはないと思うが。
もしもログイン時に動かないんであれば、実行時にはまだシェルが起動してなくて
Shell_NotifyIcon自体が失敗してんじゃないの?

85:デフォルトの名無しさん
07/06/01 16:00:16
>>83
>>79
これってどーやったらみんなみたいに青くなるんですか??

86:デフォルトの名無しさん
07/06/01 16:05:42
>>85
sageはメール欄な

87:デフォルトの名無しさん
07/06/01 16:06:23
って入ってるじゃねーかw

88:83
07/06/01 16:25:42
>>84
ATLで雛形を作成していますので、
手動とサービス起動の両方で実行が可能になっています。
それで両方で試してみましたが、手動のほうは問題なく
アイコンが表示されましたが、サービスのほうはコンパネより手動で
サービスを起動してもアイコンは表示されませんでした。
そこで考えたのがサービス起動のときだけShell_NotifyIconが
失敗しているのではと思ってやってみたら、
サービスのときは「重複した I/O 処理を実行しています。」
というエラーになりました。
エラーの意味が何のことかよくわからないですが
やはり、サービスでアイコンを表示するのは無理だったみたいです。

89:デフォルトの名無しさん
07/06/01 16:34:50
>>88
へんだな。
当然、
デスクトップとの対話をサービスに許可
にはチェック入れてるんだよな?

90:83
07/06/01 16:59:40
>>89
対話を許可というものがあること自体解からなかったのですが。
チェックを入れたら表示されました。
ありがとうございました。

危うくプロセスを分けてCOMで状態を受け渡す行動に出るところでした。


91:デフォルトの名無しさん
07/06/01 17:50:58
私と同じことにつまずいた方に
サービス登録時にデフォルトでチェックを入れて
かつ自動起動にするやり方をあげておきます。

inline BOOL CServiceModule::Install()
{
  ・
  ・
  ・
  SC_HANDLE hService = ::CreateService(
    hSCM, m_szServiceName, m_szServiceName,
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
    SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
    szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);
  ・
  ・
}

VSが作成したCreateServiceの引数を変更するだけですが・・・
よかったら参考にしてください。

92:771
07/06/02 18:30:00
CからC++に移行したと思っています。

CとC++の関数が載っているオススメの書籍を教えて下さい。

93:79
07/06/02 22:30:32
>>82
上手くいきました。
良い案をありがとうございます。

94:デフォルトの名無しさん
07/06/03 19:01:38
class A : private B {
// 省略
} ;

というのは、どういう場合に使うのでしょうか。

AのメンバからしかBはアクセスできないので、
class A {
private:
B b ;
} ;
としてしまったほうが、スッキリするような気がするのですが。

95:デフォルトの名無しさん
07/06/03 20:09:03
cin, cout は何の略ですか.

96:デフォルトの名無しさん
07/06/03 20:51:04
>>94
A has BかA is Bかの違いでしょ。

97:デフォルトの名無しさん
07/06/03 20:54:12
>>94
とりあえず実際的な理由としては
virtual関数をオーバーライドしたいときとか。


98:デフォルトの名無しさん
07/06/03 21:34:02
>>95
cはconsoleの略
inとoutはそのまま

99:94
07/06/03 22:53:19
>>96
privateで継承した場合は、
A a ;
B& b=a ;
ということができないので、
A is B ではなく、A has B になると思うのですが・・・。
Aを外側から見るのではなく、Aの中からAの中を見れば、A is B なのかもしれないけど・・・。

>>97
なるほど、
Aが、Bからのコールバックを受け取りたい場合、
privateで継承してしまえば、
Bにコールバック先のポインタを教えてあげる手間が省けますね。

100:デフォルトの名無しさん
07/06/03 23:06:03
Bが純粋仮想関数を持っていれば、継承せざるを得ないわけで。
で、AがBの実装を云々したくなければprivate継承で充分だと。

101:デフォルトの名無しさん
07/06/03 23:12:51
でも実際問題private/protected継承なんて使っているところを見たことがない
そういうこともできるんだと頭の片隅に留めておけば十分だと思う

102:デフォルトの名無しさん
07/06/03 23:52:32
おまえらEffectiveC++くらい読めよ。

103:デフォルトの名無しさん
07/06/04 00:12:38
ググっても質問しか出てこなく、解答が見つからなかったのでここで質問させてもらいます。


1 名前: 名無し 投稿日: 2001/04/15(日) 21:22
下のプログラムは複素数演算のcomplex.hを使用しています。
コンパイルすると、『特化パラメータを指定しないと
テンプレート 'complex<T>' を使えない』エラーになります。

特化パラメータって何でしょうか?どうしたらコンパイル通る
ようになるのでしょうか。ソースはインタフェース(2001.5)誌の
ソースをBCC5.5でコンパイル使用よしたものです。

bcc32 sample.cpp

** sample.cpp **
#include <stdio.h>
#include <complex.h>

extern int Dka( double *c, complex *result, int n, double eps);

main()
{
}

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
3aa.cpp:
エラー E2102 3aa.cpp 5: 特化パラメータを指定しないとテンプレート 'complex<T>' を使えない
エラー E2293 3aa.cpp 5: ) が必要
*** 2 errors in Compile ***


104:デフォルトの名無しさん
07/06/04 00:15:17
>>103
当たり前だろデフォルトパラメータがないんだから。

complex<double>とか特化しろって事だよ。

105:デフォルトの名無しさん
07/06/04 00:34:12
>>104
#define Complex complex<double>

と書いてみたのですが、同じようなエラーが出ました。
”特化する”ということがよく分からないのですが、
もうすこし詳しく教えていただけないでしょうか……

106:デフォルトの名無しさん
07/06/04 00:41:42
それよりはtypedef Complex complex<double>;のほうがいい。
それはともかく、こうしてComplexを用意したものの、
Dkaの宣言がcomplexのままになっているのでは?

107:103
07/06/04 00:44:03
>Dkaの宣言がcomplexのままになっているのでは?
自分のソースを見たらその通りでした……。
まさか大文字小文字を間違える単純なミスだったなんてorz

何とか解決しました。ありがとうございました。

108:デフォルトの名無しさん
07/06/04 01:02:16
テンプレートの特化の意味がわからないなら、テンプレートの勉強を
すべきだと思う。特にSTLが出すエラーメッセージは常人では解読する
事が不可能な内容である事が多いため、ソースからコンパイルエラーの
原因を追わなければならない。

109:103
07/06/04 01:22:28
>>108
そうですね。今までもエラーメッセージを解読できなかったことが多かったので、
これを機にテンプレートの勉強をしてみようと思います。

110:デフォルトの名無しさん
07/06/04 10:03:37
>>100
Aが継承せざるを得ないわけではない。
選択肢は1つではない。
Bを継承したCをメンバに持っても構わない。

>>101
多重継承がgdgdしてくると、privateで継承する必要が出てくる。
そうなった場合、そもそものクラス設計が妥当なのか、
小一時間考えたほうがいいことは言うまでもないが。

111:デフォルトの名無しさん
07/06/04 10:07:18
>>107
人間はミスをする生き物なので、
1文字違いの識別子を使うのは、
やめたほうがいい。

文字数が多くなっても、
complex_double
などのようにしたほうが。

112:デフォルトの名無しさん
07/06/04 18:34:15
だったらcomplex<double>でいいよという結論

113:デフォルトの名無しさん
07/06/05 01:59:35
C言語でswitch文使うときに、
case 〜〜の〜〜の部分を範囲指定(例えば0 < a && a < 9みたいな)する方法ってありますか?
初めて1ヶ月も経ってなくてスキルはカスですがやらしく教えてください

114:デフォルトの名無しさん
07/06/05 02:13:39
ありません。

115:デフォルトの名無しさん
07/06/05 02:37:25
ありがとうございます。
なんか学校の課題でそういうのやったらポイント高いぜーとか教授が言い出してたんです。
ifとelse if使った関数勝手に作って強引に処理して解決?しました
それならswitch使う意味がどこにあるんだって話になるんでしょうけれど・・・

116:デフォルトの名無しさん
07/06/05 03:41:42
>>113
switch (a) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
処理;
break;
}
または、
switch (0 < a && a < 9) {
case 0:
範囲外の処理;
break;
default:
範囲内の処理;
break;
}

117:デフォルトの名無しさん
07/06/05 11:34:35
>>73
できました!ありがとうございます

118:デフォルトの名無しさん
07/06/05 15:47:31
>>112
typedefしたほうがいいと思うけどなぁ。

>>116
後者だったら、if文を使ったほうがいいと思うなぁ。


119:デフォルトの名無しさん
07/06/05 15:51:24
>>118
確かに。

>typedefしたほうがいいと思うけどなぁ。
complex<float>してもエラーメッセージが判りにくいからね。
それが嫌ならtypedefした方がいい。

>後者だったら、if文を使ったほうがいいと思うなぁ。
敢えてswitchを使う理由がなければそう思うよ。

120:デフォルトの名無しさん
07/06/05 17:23:07
switch文を使うとしたら、
何らかの分類関数を呼ぶことになるかと。

switch(_mbsbtype(pointerToSomeString, idx)) {
case _MBC_SINGLE :
// 何か
break ;
case _MBC_LEAD :
// 何か
break ;
case _MBC_TRAIL :
// 何か
break ;
case _MBC_ILLEGAL :
default :
// ひでぶ
break ;
}

if〜else ifを直に書いてしまうのと、
分類関数を作って一段噛ませるのがいいのかは、
どうなんだろう。


そもそも、教授の発言の背景は何だろう。
switchのcaseに定数しか書けないのは不便だなぁ、条件文が書ける言語もあるのに
という愚痴で、何かいい解決法を見つけ出す人がいないかな? と儚い期待をしたのか、
>>116の前者が可能なことに気がつく人はいるかな? ニヤニヤ
ということだったのか。


121:デフォルトの名無しさん
07/06/05 17:55:58
VC++6でATLのスケルトンを作ってNTサービスアプリを開発しています。

とりあえず雛形に手を加えずビルドしただけのもので勉強している
段階なのですが、サービス停止時の動作で
コンパネのサービスから停止させた場合は
CServiceModule::Handler(DWORD dwOpcode)に
SERVICE_CONTROL_STOPイベントが発生するのですが
期待したOSシャットダウン時に発生しないのです。

さらに
m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN
としてみてもSERVICE_CONTROL_SHUTDOWNも発生しません。

イベントの発生の有無はCServiceModule::LogEvent()で吐き出した
イベントログで確認しています。

シャットダウン時にSERVICE_ACCEPT_STOPイベントが発生しない原因
について推測でもいいのでご存知ないでしょうか?


122:デフォルトの名無しさん
07/06/05 19:15:39
>>121
ATLもMFCも知らないので、適当ぶっこきます。

可能性1
イベントログのサービスが先に終了していて、イベントログに記録されていないだけで、
ちゃんとSERVICE_CONTROL_SHUTDOWNが送られてきている

可能性2
SERVICE_ACCEPT_SHUTDOWNをセットしたつもりが、
ラッパークラスのメンバ変数を書き換えただけで、
OSに対してWin32APIのSetServiceStatusを呼んでいない。

可能性3
シャットダウン時に他のプロセスやサービスが重くて、
サービスのプロセスにSERVICE_CONTROL_SHUTDOWNを送る
時間的な余裕がなく、問答無用で強制終了させられている

可能性4
何らかの原因でサービスのメッセージポンプが止まっていて、
送られてきたメッセージがキューに溜まったまま、消化されてない。

123:デフォルトの名無しさん
07/06/05 19:57:31
いくつか質問です

#include<stdio.h>
#include<float.h>

int main()

{
double what;
what=3.14159265358979;

printf("もう少し詳しい値は%20.18fです\n",what);

return 0;
}

/*結果は3.141592653589790007になるんだけど、最後の「7」は何か教えて下さい*/

後はborland社のコンパイラを使っているのですが、閉じるのが早くてエラーの文など読めません。
どうしたらよいのでしょうか?
後、初心者なのでDos形式でがんばってるのですが、これまた閉じるのが早くて自分で打った文字列などが読めません。
exeにしても一瞬で閉じてしまいます。制御するコード(HSPだとstop)みたいなのはないのでしょうか?
回答できる方よろしくお願いします。

124:デフォルトの名無しさん
07/06/05 20:06:13
"丸め誤差"でググれ

125:デフォルトの名無しさん
07/06/05 20:08:28
switch構文じゃなくて
strategyパターンを使った方が良い場合ってどういうときがありますか?

126:デフォルトの名無しさん
07/06/05 20:10:19
>>123
> borland社のコンパイラを使っているのですが、閉じるのが早くてエラーの文など読めません。

原因も対処方法も見当がついているけど、
自己解決するスキルを身につけて欲しいので、
あえて、詳しい話を聞かせてね。

「何が」閉じるのが早いの?
どうやって実行しているの?


127:デフォルトの名無しさん
07/06/05 20:10:41
丼じゃなくて、
酢飯を使った方が良い場合ってどういうときがありますか?

128:デフォルトの名無しさん
07/06/05 20:11:17
携帯ですみません
ifの条件文の中に&&や||は使えますか?
学校じゃないから確かめられない

129:デフォルトの名無しさん
07/06/05 20:18:22
家にPCはないのか?

130:デフォルトの名無しさん
07/06/05 20:22:12
ないです

131:デフォルトの名無しさん
07/06/05 20:24:29
だったらノートPCでもなんでもいいから買えよ
それともかく使えないようにする理由がないから使える

132:122
07/06/05 20:36:52
>>121
ちょっと試してみた。

CServiceModule::Init()で、
m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
に書き換えただけで、
CServiceModule::Handler()の、
case SERVICE_CONTROL_SHUTDOWN:
に来たよ。

ただ、イベントログに書き込むのは、最初から試さずに、
CloseHandle(CreateFile("適当なパス\\ServiceControlShutdownに到達したよ.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) ;
とやって、ファイルが作られたかどうかチェックした。

だから、可能性1っぽいよ。


可能性2については、ゴメン。
VC6が生成したコードが、SetServiceStatusを呼んでた。

今回の件には影響ないと思うけど、Handlerが呼ばれた場合には、
ステータスが変化しなくても、必ずSetServiceStatusを呼ぶことになってる。
ところが、VC6が生成したコードは、
case SERVICE_CONTROL_STOP:
でしか呼んでいない。

ついでに、もう一つ。CServiceModule::ServiceMain()の
SetServiceStatus(SERVICE_STOPPED);
LogEvent(_T("Service stopped"));
これは、逆の順序のほうがいいと思う。
というのも、SERVICE_STOPPEDにセットした時点でスレッドが終了して、次の行が実行されないことがあるから。

133:122
07/06/05 20:41:24
ちなみに・・・

Win32サービスの作り方を勉強するなら、
そのままの状態で適切に動作するか怪しいVC6のウィザードが生成した雛形よりも、
PlatformSDKとかのサンプルを見たほうが、いいと思う。

さらに、ちなみに・・・
自分も長々と書き込んでおいて言うのもなんだけど、
Win32APIの話は、C/C++の言語自体の話とは違うから、スレ違いだと思う。

134:デフォルトの名無しさん
07/06/05 20:47:20
>>128
> 学校じゃないから確かめられない

学校に通っていて、
いまは学校以外の場所にいるので確かめることができない
ということだと解釈する。

解決案1
次に学校に行ったときに確かめる

解決案2
学校の友人に電話して聞く

解決案3
自宅でも確かめられるようにする



だいたいさぁ、
> 学校じゃないから確かめられない
こんな下らない理由で、見ず知らずの他人を頼るなよ。

何が
> 携帯ですみません
だよ。

んな余計な文を打ち込む暇があったら、携帯で調べろよ。

135:デフォルトの名無しさん
07/06/05 20:50:22
スレを立てるまでもないレベルの低い質問のスレではあるが、

ちょっと書いてコンパイルしてみるだけで、
自分でわかるようなことは

レベルが低い質問ですらないから。


ネットの第三者の善意に頼って質問していいのは、
できるだけ努力はしたけど自分にはサッパリわからない
というような場合だ。


136:デフォルトの名無しさん
07/06/05 21:23:32
あんまり萎縮するようなことを書くのは、どうかと。

もっと気軽に行こうよ。
小言を言って雰囲気を悪くしたりせず、
だまってスルーすればいいんだよ。

137:デフォルトの名無しさん
07/06/05 22:13:42
ある数の逆数を求めるプログラムで循環小数部を除いて表示させたいのですが
どのような方法があるでしょうか?

138:デフォルトの名無しさん
07/06/05 22:39:47
C/C++言語の質問ではないような。

Cには分数を扱う組込み型がないので、
ちまちまと筆算をシミュレートするとして、
割り算の余りに既出のものが出たら、
その既出のものが最初に出たところが、
循環部のはじまり。

ということでどう?

139:デフォルトの名無しさん
07/06/05 22:49:01
配列などは使わないでできますか?

140:デフォルトの名無しさん
07/06/05 23:06:30
ランダムアクセスする必要ないから、リストでできるよ。
配列のほうが簡単だと思うけどなぁ。

141:デフォルトの名無しさん
07/06/05 23:13:53
わかりました
ありがとうございました

142:デフォルトの名無しさん
07/06/05 23:17:05
何桁で循環するかは計算で出せるはずだが。

143:デフォルトの名無しさん
07/06/05 23:47:49
10のN乗を分母で割った余りが1になる場合のNの最小値だったかな。

ちょっとググれば答えが見つかりそうじゃないか?

144:デフォルトの名無しさん
07/06/05 23:55:28
10のn乗とかオーバーフローが怖いな
MPFRとか使えってか

145:デフォルトの名無しさん
07/06/06 00:05:27
数学屋さんは、
1÷3×3が1になる
という前提で話をするからねぇ。

logとか使われちゃうと、
お手軽なdouble型では、
丸め誤差がアレだし。

だからさ、
ちまちまと筆算をシミュレート
したほうが手っ取り早いと。

146:デフォルトの名無しさん
07/06/06 00:38:39
>>142
どんな計算法ですか?

147:デフォルトの名無しさん
07/06/06 03:10:04
VC++ 2005 Expressを使っているのですが、

#include <stdio.h>

int main(void)
{
char input;

do
{
printf( "input A\n" );
scanf( "%c", &input );
}while( input != 'A' );

return 0;
}

をビルドして実行すると、出力が

Aを入力して下さい
(A以外を入力)
Aを入力して下さい
Aを入力して下さい



と以下のループで”Aを入力して下さい”が二回表示されるのですが、
色々試してみても何故なのか良く解りません。
どうかご教授賜りたく…。

148:デフォルトの名無しさん
07/06/06 03:47:37
例えばaを入力してエンターを押すと
バッファに’a'と改行コードが入力される
でscanfはinputに'a'を入力する、このときまだ標準入力バッファに改行コードは残っている
そして次のループではscanfはこのLFを拾ってinputに代入してしまうわけ

解決策としてはscanfの前でflush(stdin);でも使ってバッファをクリアするのが手っ取り早い

149:デフォルトの名無しさん
07/06/06 03:50:11
誤:flush
正:fflush

150:デフォルトの名無しさん
07/06/06 05:04:57
だから標準入力はフラッシュしちゃダメだってば。

151:デフォルトの名無しさん
07/06/06 05:20:19
>>148
なるほど!良く解ってスッキリしました。
ありがとうございます。


152:デフォルトの名無しさん
07/06/06 06:10:46
>>150
そうか、じゃあこういうの用意して
void flush(FILE* in) {
if (in->_cnt == 0)
return;
in->_ptr = in->_base;
*(in->_base) = '\0';
in->_cnt = 0;
}
入力ストリームを使う関数の前でflush(stdin);ってのはどう?
これでも環境依存でやばいかな?

153:デフォルトの名無しさん
07/06/06 06:54:35
>>147
思い通りの動きにならない場合は、
デバッガ上でステップ実行して、
何が起きているのか確認するのがいい。

VCのIDEに統合されたデバッガなら、
inputの中身を確認するのも簡単だしさ。


ただし、覚えておいてほしいことがある。
問題の原因を理解せずに、思い通りの動きになるまで、コードを弄り倒す
というのは、やってはいけない。
コード的には間違っているのに、偶然で思い通りの動きになってしまっている
というので良しとしてはいけないから。

たとえば、今回の場合、
あえて酷い例を挙げると、
do
{
char dummy ;
printf( "input A\n" );
scanf( "%c", &input );
scanf( "%c", &dummy );
}while( input != 'A' );
としても、一見、思い通りに動いているように見える。
でも、これは間違っている。

154:デフォルトの名無しさん
07/06/06 08:06:54
>>148
> 解決策としてはscanfの前でflush(stdin);でも使ってバッファをクリアするのが手っ取り早い

かならずユーザの入力があるまでブロックしたいのなら、それもいいかもしれないが、
先行入力を許したい場合や、ファイルからのリダイレクトを許したい場合に困るよ。

人間がAを押下した後にエンターを押させる
というのが意図した仕様であれば、
人間の入力の単位は1文字ではなく行である
ということなわけだよね。
ということは、それを受け取るプログラム側でも、
1文字ずつ読み取るのではなく、1行ずつ読み取る
ようにするのが自然だと思う。

自分なら、
char input_buf[10] ; /* この長さが適切なのか・・・ */
do {
printf( "input A\n" );
} while((fgets(input_buf, sizeof(input_buf), stdin) != NULL)&&(input_buf[0] != 'A')) ;
という感じにする。

エラーの場合も直進するのが、ちょっとアレだが。

155:デフォルトの名無しさん
07/06/06 08:40:15
>>143
たとえば142で割ったとして、各桁の余りは0~141だろ?(24か2.4か0.00024かの違いはあるが。)
ということは最長でも141桁目にはループが現れているはずだ。
よくわからなかったら筆算してみることをお勧めする。

156:デフォルトの名無しさん
07/06/06 09:07:49
>>154
ちゅーことは、結局こういう面倒くさい事しないと駄目なのかYp
char* buf = (char*)malloc(sizeof(char) * stdin->_bufsiz);
if (buf == NULL) {
fputs("メモリが確保できなかった", stderr);
exit(1);
}
do {
printf("'A'を入力 : ");
if (fgets(buf, stdin->_bufsiz, stdin) == NULL) {
fputs("終端か、エラー", stderr);
exit(1);
}
} while (buf[0] != 'A');
free(buf);

たかが文字を1文字読むだけなのに…

157:デフォルトの名無しさん
07/06/06 09:26:37
関数にしとけばおk

158:121
07/06/06 09:29:24
>>122

>>132の方法でSERVICE_CONTROL_SHUTDOWNイベント確認できました。
それとSTOPイベントはシャットダウン時には発生しないのですね。

HandlerでのSetServiceStatusの件は勉強になりました。

このスレを見渡したところ今回の件は確かにスレ違いでした。
NTサービススレで探して無かったのでNTサービススレを立てようかと
思ったのですが、スレ立てるまでもないかと思いここに来ました。
ご容赦してください。

ありがとうございました。


159:122
07/06/06 09:46:57
>>158
たぶんWin32APIスレあたりが、良かったと思う。


160:デフォルトの名無しさん
07/06/06 09:53:24
>>156
本来やりたい処理だけを書いているうちは明瞭でも、
エラー処理を入れると、途端に、ぐちゃぐちゃになるのは、
しかたないよ。


161:デフォルトの名無しさん
07/06/06 21:23:09
FILE *fpとfpb = NULL;
chars,[256]とn[26]
int aとbとc
for(a=0;a<26;a++);{
n[a] = 0 ;
}
if( (fp = fopen("CRed.txt","r")) == NULL );{
exit;}
fp = fopen("Count.txt","w");
while(fgets(s, 256, fp) != NULL);{
fgets(s,256,fp);
for( a=0 ; a<256 ; a++ ){
while( s[a] != '\0' ) {
for(b=0;b<26;b++) {
if( s[a] == b+65 )
{
n[b]++;
break;
}
}
}
}
}
fclose(fp);
fprintf(fpb,"+---+------+");
for(c=0;c<26;c++);
{
fprintf(fpb,"| %c | %4d |","c+65","n[c]");
fprintf(fpb,"+---+------+");
}
テキストの中の文字をカウントするものを組もうと思ったのですがうまくいきません。
素人のソースなのですが、どうかどこが悪いのかお教えください。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4289日前に更新/282 KB
担当:undef