スレを勃てるまでもないC/C++の質問はここで 11

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。

過去ログ
スレを勃てるまでもないC/C++の質問はここで
http://pc11.2ch.net/test/read.cgi/tech/1167476845/
スレを勃てるまでもないC/C++の質問はここで 2
http://pc11.2ch.net/test/read.cgi/tech/1178503366/
スレを勃てるまでもないC/C++の質問はここで 3
http://pc11.2ch.net/test/read.cgi/tech/1187521676/
スレを勃てるまでもないC/C++の質問はここで 4
http://pc11.2ch.net/test/read.cgi/tech/1221633708/
スレを勃てるまでもないC/C++の質問はここで 5
http://pc11.2ch.net/test/read.cgi/tech/1230516307/
スレを勃てるまでもないC/C++の質問はここで 6
http://pc11.2ch.net/test/read.cgi/tech/1231564903/
スレを勃てるまでもないC/C++の質問はここで 7
http://pc11.2ch.net/test/read.cgi/tech/1232983248/
スレを勃てるまでもないC/C++の質問はここで 8
http://pc12.2ch.net/test/read.cgi/tech/1235921779/
スレを勃てるまでもないC/C++の質問はここで 9
http://pc12.2ch.net/test/read.cgi/tech/1240022781/
スレを勃てるまでもないC/C++の質問はここで 10
http://pc12.2ch.net/test/read.cgi/tech/1242300936/
2デフォルトの名無しさん:2009/06/15(月) 19:03:02
いつだったかお前のポニーテールは反則的なまでに似合ってたぞ
3デフォルトの名無しさん:2009/06/15(月) 20:48:32
                          刀、           , ヘ
                  /´ ̄`ヽ /: : : \_____/: : : : ヽ、
              ,. -‐┴─‐- <^ヽ、: : : : : : : : : : : : : : : : : : : : : : }
               /: : : : : : : : : : : : : :`.ヽl____: : : : : : : : : : : : : : : : : : /
     ,. -──「`: : : : : : : : : :ヽ: : : : : : : : :\ `ヽ ̄ ̄ ̄ フ: : : : :/
    /: :.,.-ァ: : : |: : : : : : : : :    :\: : : : :: : : :ヽ  \   /: : : :/
    ̄ ̄/: : : : ヽ: : : . . . . . . . . . . .、 \=--: : : :.i  / /: : : : :/
     /: :     ∧: \: : : : : : : : : : ヽ: :\: : : 〃}/  /: : : : :/         、
.    /: : /  . : : :! ヽ: : l\_\/: : : : :\: ヽ彡: : |  /: : : : :/            |\
   /: : ィ: : : : :.i: : |   \!___/ ヽ:: : : : : : :\|:.:.:.:/:!  ,': : : : /              |: : \
   / / !: : : : :.ト‐|-    ヽ    \: : : : : l::::__:' :/  i: : : : :{              |: : : :.ヽ
   l/   |: : :!: : .l: :|            \: : : l´r. Y   {: : : : :丶_______.ノ: : : : : :}
      l: : :l: : :ト、|         、___,ィ ヽ: :| ゝ ノ    '.: : : : : : : : : : : : : : : : : : : : : : /
      |: : :ト、: |: :ヽ ___,彡     ´ ̄´   ヽl-‐'     \: : : : : : : : : : : : : : : : : : イ
        !: :从ヽ!ヽ.ハ=≠' , ///// ///u /           ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
      V  ヽ|    }///  r‐'⌒ヽ  イ〉、
              ヽ、______ー‐‐' ィ´ /:/:7rt‐---、       こ、これは>>1乙じゃなくて
                  ィ幵ノ ./:/:./:.! !: : : : :!`ヽ     ポニーテールなんだから
              r‐'T¨「 |: | !:.∨:/:./: :| |: : : : .l: : : :\   変な勘違いしないでよね!
               /: : .|: :| !:.!ィ¨¨ヾ、:.:/ !: : : : l: : : : : :.\
4デフォルトの名無しさん:2009/06/15(月) 21:02:38
会社出勤日数が減って
給料がアップするプログラムってないでしょうか?
5デフォルトの名無しさん:2009/06/15(月) 22:35:41
>>4
俺も欲しいよそんなもん。

・・・あれだな、最高に便利なライブラリを作って
クローズドソースにして販売すること。

働かなくても金が入る。
6デフォルトの名無しさん:2009/06/15(月) 23:15:09
平均と標準偏差を求める関数を作りました。
平均のほうは確実にあってるんですが、標準偏差のほうが手計算と違うような気がします。
どうでしょうか?

http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9463.c

それと、プログラムのなかで、ある整数を割ったり、数学関数sqrtをつかっているんですが、
手計算で計算した場合との誤差はどうなんでしょうか?
よろしくお願いします。
76:2009/06/15(月) 23:19:42
すみません。こっちでお願いします。

http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9464.c
8デフォルトの名無しさん:2009/06/15(月) 23:25:20
9デフォルトの名無しさん:2009/06/16(火) 08:59:33
>>3
そのポニーテール、壊滅的なまでに似合ってないな。
10デフォルトの名無しさん:2009/06/16(火) 09:12:45
>>7
母集団数をnとするかn-1とするかの違いじゃない?
どっちがどっちだか忘れたが、標準偏差は分散の平方根である場合と不偏分散の平方根である場合があるのよ。
表計算ソフトの標準偏差はn-1の方だけど、>7の式はnだね。
詳しくはこちら。
ttp://foxes-nest.up.seesaa.net/attic/covariance.pdf
11デフォルトの名無しさん:2009/06/16(火) 16:13:57
アフィなら仕事しなくても儲かるのに
12デフォルトの名無しさん:2009/06/17(水) 02:56:57
C++って、フィールド名とメソッド名同じにできないの?

private:
bool isComplete;
public:
bool isComplete();

ってやるとエラー吐かれるんだけど・・・
13デフォルトの名無しさん:2009/06/17(水) 03:04:06
できないよ
14デフォルトの名無しさん:2009/06/17(水) 07:42:29
「'」文字列にこの文字があるときだけ特別な操作をしたいのですが
for(i=0;i<20;i++){
if(mozi[i]==''')
}


とやる訳にはいきませんよね?この場合どのような書き方をすればいいんでしょうか?
15デフォルトの名無しさん:2009/06/17(水) 07:49:29
'\''
エスケープしろ
16デフォルトの名無しさん:2009/06/17(水) 08:10:19
>>15
解決しました。
ありがとうございました。
17デフォルトの名無しさん:2009/06/17(水) 08:28:15
フィールドとかメソッドとか、そんな呼び名はC++にはないっすよ。
どれもこれもメンバです。
18デフォルトの名無しさん:2009/06/17(水) 18:19:39
BMPファイルを読み込むため
char*ではなく char buf[100][100][3];みたいな配列に
ifstreamを使ってバイナリ読み込みたい場合
どうするのが普通なのでしょうか

とりあえずchar*に読み込んでコピーだとコストがかかってしまいますし
ifs.read(buf,3)などとやると、型エラーが出てしまいます
19デフォルトの名無しさん:2009/06/17(水) 18:22:20
ifs.read(reinterpret_cast<char*>(buf), sizeof(buf));
20デフォルトの名無しさん:2009/06/17(水) 18:40:34
ありがとうございます。うまく行きました
reinterpret_castってこう使うんですね
21デフォルトの名無しさん:2009/06/17(水) 21:29:59
エンディアンの関係でRGBのうちBとRが逆転していたようなので
修正してみたのですが、書法的には問題ないですよね?
一応動作はしています
for(int i=0;i<TEXHEIGHT;++i){
for(int j=0;j<TEXWIDTH;++j){
ifs.read(reinterpret_cast<char*>(texture[i][j])+2,1);
ifs.read(reinterpret_cast<char*>(texture[i][j])+1,1);
ifs.read(reinterpret_cast<char*>(texture[i][j]),1);
}
}
22デフォルトの名無しさん:2009/06/17(水) 21:33:05
tr1::shared_ptrで配列を確保って無理ぽ?
2312:2009/06/17(水) 21:33:31
>>13, 17
なるほど、どっちもメンバだから同じ名前にできないのかな?
ありがとう。
24デフォルトの名無しさん:2009/06/17(水) 21:35:53
ifs.read(reinterpret_cast<char*>(texture[i][j])+2,1);
これってキャストなしで動かない?
25デフォルトの名無しさん:2009/06/17(水) 21:36:55
>>22
tr1::shared_arrayってあるっしょ?
26デフォルトの名無しさん:2009/06/17(水) 21:40:16
ぐお・・・tr1::shared_arrayはないな

boost::shared_arrayを使うしかない
27デフォルトの名無しさん:2009/06/17(水) 21:45:06
>>24 ifs.read(texture[i][j],1);の時点でコンパイル通らないです
28デフォルトの名無しさん:2009/06/17(水) 22:01:27
>>27
なんてエラー出るの?
> char buf[100][100][3];みたいな配列
これは texture ではないということ?
29デフォルトの名無しさん:2009/06/17(水) 22:12:05
>>28
おっと、失礼しました
charにするとコンパイル通るし普通に動作もしますね

エラーメッセージ
 GLubyte [3]' から 'char *' に変換できません。

「みたいな」、と書いてるのは
結局の所
 typedef GLubyte char
となっているからです(openglのコードです)

typedef mychar char;として
mycharを使ったコードに書き直してもやはり同様のエラーがでます

これはちょっと勉強になりましたが、
しかし、どういうことなのだろう?
30デフォルトの名無しさん:2009/06/17(水) 22:14:32
私の認識では、Cのtypedefは新しい型は導入しなくて
MC++とかでは新しい型を導入するために
struct{}でくくったものをtypedefで使っていたように思うのですが
認識違いだったのかなぁ・・
31デフォルトの名無しさん:2009/06/17(水) 22:29:13
すみません、私の勘違い
typedef unsigned char GLubyte;
とtypedefされていてエラーになっていたみたいです
32デフォルトの名無しさん:2009/06/17(水) 22:31:41
ああ、なら納得です。
unsigned char から char へのキャストは強制的に行うしかないですね。
33デフォルトの名無しさん:2009/06/17(水) 22:38:31
C++初心者です。
ドット演算子とアロー演算子って、何で区別されてるんでしょうか?
変数とポインタで用いる場所が違うのは分かるんですが、どっちかに統一されてた方が簡便なような・・・
可読性向上のためでしょうか? 何か他に理由があるなら教えてください。
34デフォルトの名無しさん:2009/06/17(水) 22:44:16
>>33
可読性向上のためでしょ。
hoge->piyo->fuga->m_func()
なんて式があったとして、これを.演算子で書き換えてごらん?
35デフォルトの名無しさん:2009/06/17(水) 22:47:17
hoge->piyo->fuga->m_func()

hoge.piyo.fuga.m_func()
が等価であればよかったのにという話じゃないの?
そうじゃないからこう書かざるを得ないだけで。
(*(*(*hoge).piyo).fuga).m_func()
36デフォルトの名無しさん:2009/06/17(水) 22:49:07
両方.にしたらポインタそのものに演算してるのかポインタの示す先に演算してるのかどっちなのって気分になるから
37デフォルトの名無しさん:2009/06/17(水) 22:49:39
hoge->piyo.fuga->m_func()
と書かれていて、ああ、fugaはポインタなんだな、piyoは非ポインタなんだな、ということがわかることの
メリットが見出せなければ、実質的に可読性が高まったとは言いにくい。
俺も同じならよかったのに、ということで参照渡しはよいよね。
C#のrefはさらによいよね。
38デフォルトの名無しさん:2009/06/17(水) 23:16:48
オーバーヘッド削減だけならいいけど、値返し目的の参照渡しは好きになれないなぁ
39デフォルトの名無しさん:2009/06/17(水) 23:26:56
>>37
横やりだが、C++Builderでプログラム書いてるとそういう->の
連続なんてしょっちゅう出てくる

あまりに長くてウザいので、with文を持たないC++なので途中までを
ポインタに保存しておき、そこから->を伸ばしてる
40デフォルトの名無しさん:2009/06/17(水) 23:28:59
>>38
それも含めて、また、呼び出し側から変更されるかどうかが明確であるという点でC#はよいよね、に
つなげてたけどはしょりすぎたね。ごめん。
41デフォルトの名無しさん:2009/06/17(水) 23:29:20
標準C++で質問させてください。

アルファベットの文字は必ずしも'a'-'z'まで連続してならんでいないと聞きました。
すなわちchに文字が入っているとして
if('a'<ch && ch<'z'){******}
では必ずしも全ての小文字を捉えられる訳ではなく、環境依存であると聞きました。
ですが数字は並んでいることは保証されていますか?
すなわちchに文字が入っているとして
if('0'<ch && ch<'9'){******}
では必ず全ての数字を捉えられますか?

「捉えられない環境なんて見たことない」かどうかではなく、
標準C++で厳密に保証されているかどうかという視点で、
どうかよろしくお願いします。
42デフォルトの名無しさん:2009/06/17(水) 23:30:45
>>41
そういう意味なら'0'〜'9'まで連続で並んでいるコードだという
保証は規格票には一切ない

isdigit()を使え
43デフォルトの名無しさん:2009/06/17(水) 23:30:44
>>33
昔のCで区別されていたから。
なんでCで区別されていたかというと、昔はコンパイラがそんなに頭がよくなかったから。
p->mは、(*p).m と同じものに機械的に変換されていた。
それだけ。
44デフォルトの名無しさん:2009/06/17(水) 23:36:07
>>41
'0'〜'9'は保証されてるよ
45デフォルトの名無しさん:2009/06/17(水) 23:37:39
>>42
数字はされているだろ。
何が一切無いだよw
46デフォルトの名無しさん:2009/06/17(水) 23:37:59
>>41
is系の関数は並びがどうであれうまく動作することが保障されている
4741:2009/06/17(水) 23:39:13
みなさんありがとうございます。
isdigit()という便利な代物があることをご指摘いただきましたが
仕様上気になっていましたもので。

48デフォルトの名無しさん:2009/06/17(水) 23:41:18
従来型の iostream ライブラリ
ttp://docs.sun.com/source/806-4840/Iostream.html

ここに
>入力データの先読み
>メンバー関数 peek を使用するとストリームから次の文字を抽出することなく、
>その文字を知ることができます。
>使用例を次に示します。
>if (cin.peek() != c) return 0;
とありますが、それでは次の次の文字や次の次の次の文字や次の次の次の次の文字が
知りたい時はどうにかして知ることはできますか?
49デフォルトの名無しさん:2009/06/17(水) 23:42:21
>>45
規格票にはないだろ
50デフォルトの名無しさん:2009/06/17(水) 23:45:39
別人ですが横から失礼する。

[迷信] 'A'〜'Z' の値は連続している | 株式会社きじねこ
ttp://www.kijineko.co.jp/tech/superstitions/A-to-Z-is-sequence.html
えーと、とりあえずここに保証されていると書いてあるから
きっと探せばどっかに出て来るんじゃない?
51デフォルトの名無しさん:2009/06/17(水) 23:46:41
>>50
つ[EBCDIC]
52デフォルトの名無しさん:2009/06/17(水) 23:46:46
>>42を擁護するつもりはないが、>>45,45は規格のどのセクションか示してから発言した方がいいよ。
ここが規格準拠スレでなくてよかったね。C++の規格書を読むのは嫌だけど。

>>41
可読性向上も考えて、is*()使え。
53デフォルトの名無しさん:2009/06/17(水) 23:46:48
規格票のどこに書いてあるか素直に尋ねればいいのにね。
5450:2009/06/17(水) 23:47:23
・・・数字の話ね、もちろん。
55デフォルトの名無しさん:2009/06/17(水) 23:56:19
X3014:2003
2.2 文字集合
3 …… 上で掲げた表の0以降のそれぞれの数字に対応する文字の値は,
それの直前にある文字の値より1だけ大きくなければならない。……

>>48
tellg/seekgで読み取り位置を元に戻しておけばいい。
5648:2009/06/17(水) 23:58:12
>>55
ありがとうございます。そうします。
57デフォルトの名無しさん:2009/06/18(木) 00:00:18
>>52自己レス
ISO/IEC 14882:2003(E) 2.2.3 3 In both the source and execution basic character sets,
the value of each character after 0 in theabove list of decimal digits shall be
one greater than the value of the previous.

58デフォルトの名無しさん:2009/06/18(木) 00:01:56
ほらね
59デフォルトの名無しさん:2009/06/18(木) 03:17:02
んー?
C++の規格で「0-9は並んでなきゃダメ!」といっているのは、
そういう文字コードでしか正しく動きませんよって言っているだけなのでは?
60デフォルトの名無しさん:2009/06/18(木) 04:07:46
は?当然だろ。何言ってるんだ
61デフォルトの名無しさん:2009/06/18(木) 14:19:41
コピー代入演算子の返り値がtype&なのはなんで?
(a = b) = cみたいな変なことができないconst type&のほうがいいと思うんですが
62デフォルトの名無しさん:2009/06/18(木) 14:22:04
いいところに気づきました!

そんなときのためにも C++ Coding Standards を読みましょう。
端的にいうと、STLコンテナに入らなくなります。
63デフォルトの名無しさん:2009/06/18(木) 14:36:44
>>60
当然だったのか。
じゃあisdigitを使うべきかどうかなんて議論する余地もないね
64デフォルトの名無しさん:2009/06/18(木) 16:00:39
小数点以下の桁が多いdouble型をToStringすると指数表記の文字列になっちゃうんだけど
ToString(#とか0)で桁数制限せずに普通の表記にする方法はない?
65デフォルトの名無しさん:2009/06/18(木) 16:06:47
>アルファベットが並んでる

実際のところ、普通のパソコン向けの開発なら
歩調されてないということさえ覚えておけば、あんまり気にしなくてOKなのかしら?
66デフォルトの名無しさん:2009/06/18(木) 16:13:33
Your left! Your left! Left, right, left!

>>64
ToString…だと?
67デフォルトの名無しさん:2009/06/18(木) 16:29:13
C#だろうねぇ
68デフォルトの名無しさん:2009/06/18(木) 16:34:24
C#は+が4つもついてるんだから、C++よりも高級だろ。
69デフォルトの名無しさん:2009/06/18(木) 16:44:31
何を唐突に?
70デフォルトの名無しさん:2009/06/18(木) 16:45:14
恋は突然に
71デフォルトの名無しさん:2009/06/18(木) 17:19:49
>>65
つか、アルファベットが隙間なく並んでいないと困るような状況ってあんまりないしな。
72デフォルトの名無しさん:2009/06/18(木) 17:57:33
>>71
ゲーム系だと結構あるかも。
専用のグラフィックを用意して描画しなきゃならないことも多いし。
73デフォルトの名無しさん:2009/06/18(木) 18:08:00
それはアルファベットのグラフィックがアルファベット順に並んでるかどうかの話でしょ
74デフォルトの名無しさん:2009/06/18(木) 19:48:34
ん? 何か引っかかる?
75デフォルトの名無しさん:2009/06/18(木) 19:53:36
vc++のGUI使ってるんだけどビルドオプションの設定とかがよくわからない
makefileとやらも使い方を覚えてそっちを使ったほうがいいのかな?
76デフォルトの名無しさん:2009/06/18(木) 19:56:03
デフォのままにしとけば?
77デフォルトの名無しさん:2009/06/18(木) 21:29:57
関数の中で同じようなコードが連発するときって
#defineを書いてまとめてもいいんだよね?
#defineはグローバルスコープ以外にも書いてもいいんだよね?
78デフォルトの名無しさん:2009/06/18(木) 21:31:50
#defineってスコープ認識したっけ?
79デフォルトの名無しさん:2009/06/18(木) 21:38:13
そういやスコープ認識しなかったな。

ということは

スコープに閉じ込めることはできない
=>グローバルスコープ以外にも書いてもいい

ってことか。
サンクス。
80デフォルトの名無しさん:2009/06/18(木) 21:39:05
知りません。スコープはコンパイラの仕事なので、
プリプロセッサを担当するリンカは知ったこっちゃないからです。

逆に言えば、ソースのどこに書いてもOK
81デフォルトの名無しさん:2009/06/18(木) 21:39:53
リロードしたらもう書いてあった・_・マムコ
82デフォルトの名無しさん:2009/06/18(木) 21:42:20
コンパイル時に決まる文字列リテラル(const char*)の文字数を取得するマクロってない?

つまり
"hoge"
"hogepiyo"
"jder208o1ulk34paa16u9ky7gj7nfezb2yjshhpo6v28o90q8hyq67d3m42eq814gp6"
の3つがあったとして、
これらの文字数をエディタで数えるとかじゃなく
取得する方法はない?
8379:2009/06/18(木) 21:43:08
>>80
ありがとう。
84デフォルトの名無しさん:2009/06/18(木) 21:45:29
sizeof("hoge")とかだめだったかな。
85デフォルトの名無しさん:2009/06/18(木) 21:48:31
いまやったら、'\000'が入るから'\000'文字分を引かないといけない。
けど、ワイド文字とか多バイトのとき即死フラグが立っている。
86デフォルトの名無しさん:2009/06/18(木) 21:48:33
文字列の最後は必ず'\0'で終わるから、メモリを調べれば長さがわかるよ。
変数の中に入っているならstrlenとか使えるし。

そういう意味ではなく?
87デフォルトの名無しさん:2009/06/18(木) 21:49:29
あぁ、マクロか。よく読んでなかったよ、おっかさん。
8882:2009/06/18(木) 21:53:57
みんなありがとう。

コンパイル時に定数として文字数を取得したいんだよね。
それを用いて配列を定義したりするつもりだから。
sizeof("hoge")だと惜しいんだけど、
sizeof("hoge")==sizeof(char)*4
にならない?そしてcharが1バイトとは限らないから。。。


言い忘れたけど
・標準C++準拠
・文字列はASCII文字しか入りません。
を想定しています。
ただしstrlenでもまあどうにかならないことはない。(配列を動的確保にすれば。)
89デフォルトの名無しさん:2009/06/18(木) 22:11:28
>>88
$ cat -n foo.c
1
2 #include <stdio.h>
3
4 #define static_strlent(static_str, type) (sizeof(static_str)/sizeof(type) -1)
5 #define static_strlen(static_str) (static_strlent(static_str, char))
6 #define static_wcstrlen(static_str) (static_strlent(static_str, wchar_t))
7 #define static_mbstrlen(static_str) (static_strlent(static_str, char))
8
9 int main(void)
10 {
11 printf("char %d\n", static_strlen("sakuratan"));
12 printf("wchar %d\n", static_wcstrlen(L"さくらたん"));
13 printf("mb %d\n", static_mbstrlen("さくらたん"));
14
15 return 0;
16 }
$ ./foooo
char 9
wchar 5
mb 15

マルチバイトはもう知らん。
わざわざC++の規格読むの面倒だから後は適当に誰かやってくれるだろう。
9088:2009/06/18(木) 22:23:35
>>89
おお!
ありがとう。
91デフォルトの名無しさん:2009/06/18(木) 22:27:47
>>89
(sizeof(static_str)/sizeof(static_str) - 1)とすればchar/wchar_tの場合分けが不要になる。
92デフォルトの名無しさん:2009/06/18(木) 22:38:00
(sizeof(static_str)/sizeof(static_str[0]) -1)
ってことかな。
確かにそうだね。配列の要素数を得るマクロのちょっとした応用だった。
93デフォルトの名無しさん:2009/06/18(木) 22:39:52
しかしそれは果たしてコンパイル時定数になれるのだろうか?
94デフォルトの名無しさん:2009/06/18(木) 22:55:52
余裕でなれるんじゃないの?
95デフォルトの名無しさん:2009/06/18(木) 23:08:09
ISO/IEC 14882:2003(E) 5.19 Constant expressions
1 ... An integral constant-expression can involve only literals (2.13), enumerators, const variables or static
data members of integral or enumeration types initialized with constant expressions (8.5), non-type tem-
plate parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can
appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumera-
tion types can be used. ... (前後は省いた)
全く忙しいのにC++の規格を読むことになるとは、ちゃんと書いてあるね、sizeof expressionsって。
sizeof expressionsがわからない場合は、自分で規格書内を調べてね。
9688:2009/06/18(木) 23:14:43
いやはやすまない。

みんなマジでサンクス!
97デフォルトの名無しさん:2009/06/19(金) 17:04:15
Win32(VC++2005) で作ってます。
思いつきでずぼらなクラスを書いてみました。

class CLocalTime
{
private:
  char buf[32];
  SYSTEMTIME SysTime;
public:
  CLocalTime()
  {
  }
  operator char *();
};

CLocalTime::operator char *()
{
  GetLocalTime(&SysTime);
  sprintf_s(buf, 31, "%04d/%02d/%02d %02d:%02d:%02d",
            SysTime.wYear, SysTime.wMonth, SysTime.wDay,
            SysTime.wHour, SysTime.wMinute, SysTime.wSecond);
  buf[31] = '\0';
  return buf;
}

これで、例えば printf なんかで使うときに、
printf("通過![%s]\n", (char *)CLocalTime());
ときちんとキャストすればちゃんと表示されるんですが、
printf("通過![%s]\n", CLocalTime());
だけで表示させるには、たぶん operator だと思うんですが、何を追加すればいいんでしょうか。
CAtlStringA なんかは後者できちんと表示されていてくやしいです。
98デフォルトの名無しさん:2009/06/19(金) 17:16:20
Cに関する初歩的なポインタの質問です。

問. 1を入力すると「Jan」、2を入力すると「Feb」というように、その月の名前を返すプログラムを文字列の配列を利用して作れ

答.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
char *mon(int n);    ←←←←←←←←←
int main()
{
int n;
while (1) {
printf("数値:__");
scanf("%d",&n);
if(n == 0)
break;
printf("%s\n",mon(n-1));
}
return 0;
}
char *mon(int n)   ←←←←←←←
{
→→→→ char *month[] = {"Jan", ・・・略"};
return month[n];
}
ここでポインタが出てくる理由がわかりません。
ここではmonthのアドレスをmonに集約させて表示させてるっていう認識でOKですか?

また、配列を利用する以外に、もっと簡単に解答を返す方法ってあるんでしょうか?
99デフォルトの名無しさん:2009/06/19(金) 17:19:27
>>98
あー。文字「列」について勉強しなおしましょう。
端的にいうと、C言語には文字「列」という型はないのです。
BASICでは文字列型というのがありました。A$とかB$とか。
でもC言語にはないんです。
ないから、文字列をやり取りするには非常に特殊な方法が必要なのです。

それがchar*なのです。
10098:2009/06/19(金) 17:26:20
>>99
素早いお返事ありがとうございます。
検索してみたところ、"プログラム中に「"ABC"」が出てくると、これ全体がアドレスの値になります" これがそもそも理解できてませんでした。
文字列について調べてきます。ありがとうございました。 100get
101デフォルトの名無しさん:2009/06/19(金) 18:39:08
class A {
protected:
  size_t global_a;
}

こんなかんじで protected な field を global 変数のように
扱いたいのです。いちど継承をしないと、その include 先の
メソッドから操作するのは難しいでしょうか? > protected な field

class DealWithA
  : public A { ... }
class ConvertWithA
  : public A { ... }
class TalkWithA
  : public A { ... }
102デフォルトの名無しさん:2009/06/19(金) 18:51:24
あと class A << DealWithA << ActionDeal のように

二段階下の階層から、class A 大もとの 『protected な field』 に
アクセスすることはできるでしょうか? どうぞ宜しくお願いします。
103デフォルトの名無しさん:2009/06/19(金) 19:01:47
フィールドとかメソッドとか意味不明な単語がw
・・・メソッドはVCでは使うか。

「インクルード先のメソッド」の意味が不明ですが、
protectedメンバは派生クラスでないクラスからはprivateメンバとして扱われるので見えません。

派生クラスは基底クラスのメンバを継承するので
(ただし、コンストラクタ、仮想でない代入演算子、仮想でないデストラクタを除く)
派生クラスの派生クラスでも奥底のクラスのメンバにアクセスできます。
多重継承の場合にいくつかの注意事項があるくらいでしょう。

104デフォルトの名無しさん:2009/06/19(金) 19:38:40
>>104
dくすです

メンバ、派生クラス << C++ での呼び方 ですね
派生クラスから操作されたくない、メンバは private にと。

>「インクルード先のメソッド」の意味が不明ですが
#include "A2Z.h"
class DealWithA : A {...}
class DealWithZ : Z {...}

「インクルードして、継承した派生クラスから」
メソッドを呼び出して操作する…ことばが足りずスマソですorz

private メンバアクセス 〜解答
http://blog.goo.ne.jp/akatoza/e/4e550d5481e47a1d43697eedcdc806e3

C++奥深し…テンプレート謎すぐるd
105デフォルトの名無しさん:2009/06/19(金) 20:12:05
>>104
当該サイトで紹介されている Exceptional C++ Style は
C++ の落とし穴を紹介する本の中でもことさらに難しいレベルで、
さすがはサッター先生と驚嘆すべき本です。
(同氏の著書 Exceptional C++ でメイヤーズすらもそう書いている)
初心者は読んでもちんぷんかんぷんでしょう。
言語仕様の微細に分け入れるので、むしろ混乱するだけかもしれません。

あと、当該サイト、コード間違ってます。
すぐにわかるレベルのtypoですが…。
106デフォルトの名無しさん:2009/06/19(金) 23:56:27
質問させてもらいます。

error LNK2028: 未解決のトークン (0A00001D) "extern "C"〜
っていうエラーが出るんですが、問題の関数にはextern "C"がつけられてます。

この場合他にどういう原因が考えられるでしょうか?
107デフォルトの名無しさん:2009/06/20(土) 00:14:30
>>106
関数の、宣言と定義の両方に extern "C" ついてる?
あとは普通のリンク間違いしか思いつかないな。
108デフォルトの名無しさん:2009/06/20(土) 00:32:06
Visual Studio2008を使っているのですが、
sprintfを使うと
'sprintf' の宣言を確認してください。 というエラーが出て、
ネットで検索したところ、sprintf_sの書式に書き換えると良いと書いてあったので書き換えたところ
warning C4024: 'sprintf_s' : の型が 2 の仮引数および実引数と異なります。 というエラーが。

どうしたらsprintfが使えるようになるんですか?
109デフォルトの名無しさん:2009/06/20(土) 00:34:11
sprintf sprintf_s は書式が違う、パラメータをsprintf_sにあわせて増やす
110デフォルトの名無しさん:2009/06/20(土) 00:34:39
>>108
多分書式間違えてる。すごい勢いで間違えている。ソースを全部貼れといいたいほどに間違っている。
ご存知のとおり、varargを利用するこの手の関数はいかなる文法上のミスも許されない。
111デフォルトの名無しさん:2009/06/20(土) 00:37:33
>>109-110
すいません、きっと凄い勢いで間違えてます。
ただ本の通りにはしてるんです。できれば修正お願いします。
#include <stdio.h>

struct Data {
char name[32];
int age;
double bl;
double bw;
double bmi;
};

int struct_input(struct Data *);

int main()
{
struct Data Mydata;
char format[] = "%sさん(%d歳)のプロフィール\n"
"身長 = %5.1fcm, 体重 = %5.1fkg, BMI = %4.1f\n";
char buffer[256];

struct_input(&Mydata);
sprintf(buffer, format, Mydata.name, Mydata.age,
Mydata.bl, Mydata.bw, Mydata.bmi);
printf(buffer);
printf("%s", Mydata.name);
return 0;
}
112デフォルトの名無しさん:2009/06/20(土) 00:38:33
続き

int struct_input(struct Data *p);
{
printf("氏名__");
gets(p->name);
printf("年齢___");
scanf("%d", &p->age);
printf("身長(cm)___");
scanf("%lf", &p->bl);
printf("体重(kg)___");
scanf("%lf", &p->bw);
p->bmi = p->bw * 10000.0 / (p->bl * p->bl);

return 0;
}
お願いします。。
113デフォルトの名無しさん:2009/06/20(土) 00:38:44
sprintf(buffer, sizeof(buffer), format, Mydata.name, Mydata.age,
Mydata.bl, Mydata.bw, Mydata.bmi);
114デフォルトの名無しさん:2009/06/20(土) 00:39:43
>>107
回答ありがとうございます。
サンプルプログラムなので
そのへんはちゃんとなっているようです。
115デフォルトの名無しさん:2009/06/20(土) 00:39:45
sprintf_s(buffer, sizeof(buffer), format, Mydata.name, Mydata.age,
Mydata.bl, Mydata.bw, Mydata.bmi);

_s忘れた
116デフォルトの名無しさん:2009/06/20(土) 00:42:26
aprintf使っても警告になるだけでエラーにはならないと思うんだけど
設定によるのかしら?
117デフォルトの名無しさん:2009/06/20(土) 00:44:13
>>108
#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
と書けば、sprintfがそのまま使える。
これはsprintfの呼出をできるかぎりsprintf_sに変換するようになる効果がある。
万能ではないが。
118デフォルトの名無しさん:2009/06/20(土) 00:50:22
>>115-117
ありがとうございます。実行できるようになりました!
実行できなかったのはint struct_input(struct Data *p); セミコロンが原因でした。。
まだ、
'gets' の宣言を確認してください。
'scanf' の宣言を確認してください。 *3の合計4つの警告が残っているのですが、
警告は残ったままでもいいのでしょうか?

>>116
すいません警告でした。エラーは別の原因でした。。
119デフォルトの名無しさん:2009/06/20(土) 01:00:09
>>118
エラーメッセージを略さないでちゃんと『全部』貼ってくれ。
_CRT_うんちゃらかんちゃらとか書いてあるだろ?

無視して問題ない。
120デフォルトの名無しさん:2009/06/20(土) 01:07:07
>>119
すいません、今さらですが張らせて頂きます。

>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(34) : warning C4996: 'gets': This function or variable may be unsafe.
Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(279) : 'gets' の宣言を確認してください。
1>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(36) : warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。
1>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(38) : warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。
1>c:\users\owner\documents\visual studio 2008\projects\struct03.c\struct03.c\struct03.c(40) : warning C4996: 'scanf': This function or variable may be unsafe.
Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(306) : 'scanf' の宣言を確認してください。

CRTうんちゃら書いてました。
問題無いんですね、ありがとうございました!
121デフォルトの名無しさん:2009/06/21(日) 01:18:16
gets この関数(もしくは変数)は安全でない可能性があります
gets_s を使うことで安全になります。
こまけえことはいいんだうるせえだまれ、と思うなら _CRT_SECURE_NO_WARNINGS を使ってください。

と、書いてます。
122デフォルトの名無しさん:2009/06/21(日) 01:19:12
あ、それと、gets関数というやつは「常に悪」である関数だよ。
123デフォルトの名無しさん:2009/06/21(日) 07:33:13
質問です。
m個のデータの中からn個のデータを無作為に抽出したい場合、どうすればいいですか?
124デフォルトの名無しさん:2009/06/21(日) 08:21:36
乱数を用いて、m個のデータテーブルからn個のデータを取り出す。
一度取り出されたとこは、なしフラグを立てて再度読まないようにする。
無い所が引かれたら再度乱数を取る。n個そろうまで繰り返す。
125デフォルトの名無しさん:2009/06/21(日) 08:38:57
>124
まあ、楽だよな
126123:2009/06/21(日) 09:04:45
どうもです。
127デフォルトの名無しさん:2009/06/21(日) 09:49:12
data a[m], b[n];
//input(a);
for(i = 0; i < n; ++i) {
  swap<data>(a[i], a[rand()%(m - i) + i]);
  b[i] = a[i];
}
128デフォルトの名無しさん:2009/06/21(日) 11:38:51
質問です。 VC++2008にて

#pragma once
class test
{
private:
 static int a; //テスト変数
public:
 test(void);
 ~test(void);
 static void tekitou(int b){  //テスト関数
  a = b;//☆☆
 }
};
このクラスを別のファイルから

test::tekitou(5);//☆☆

みたいな感じで呼ぶと
main.obj : error LNK2001: 外部シンボル ""private: static int test::a" (?a@test@@0HA)" は未解決です。
C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\Project1\Game\Debug\Game.exe : fatal error LNK1120: 外部参照 1 が未解決です。

というエラーがリンク時にでるのですが、原因は何でしょうか?
//☆☆と入れたどちらかの行を削除するとリンクも通ります。ヘッダファイル等はきちんと渡しているはずなのですが…
129デフォルトの名無しさん:2009/06/21(日) 11:51:52
int test::a;
をソースに書くとよい
130デフォルトの名無しさん:2009/06/21(日) 11:56:14
ありがとうございます。通りました。
クラス読み込んだ際に、aも認識してくれてるはずと思い込んでいたのですが、してなかったんですね…
131デフォルトの名無しさん:2009/06/21(日) 15:15:54
まず「宣言」と「定義」の違いを学ぶんじゃ
おまえのソースには宣言しかなかったのじゃ
132デフォルトの名無しさん:2009/06/21(日) 16:10:01
すみません。

Cを現在習得中なんですが、自作サンプルにて困ったことがあります。

構造体に電話番号と氏名のデータを入れているんですが、それをファイルに記憶しています。
で、好きな番号の後に新規データを入れれるようにしたんですが(fseek関数を使って)、
好きな番号のデータを削除することができません。ファイル処理はランダムアクセスで
データを消去することはできないんでしょうか?
133デフォルトの名無しさん:2009/06/21(日) 16:13:10
Cの扱うファイルは、バイト列。
ランダムアクセスしても、中を抜くことはできない。
134デフォルトの名無しさん:2009/06/21(日) 16:16:33
>>133
どうもありがとうございます。できないんですか(´・ω・`)
ここまで来たんで、意地でもやりたいんですが、制御文字の
BSとか使ってもできないですかね・・もしできるなら、自分で工夫します。
135デフォルトの名無しさん:2009/06/21(日) 16:19:40
>>134
memmoveを使え
136134:2009/06/21(日) 16:26:03
>>135
ありがとうございます。ぜひ、それを使い作ってみようと思います。教えてくださり、ありがとうございました。
できると聞いて、とてもうれしい・・
137デフォルトの名無しさん:2009/06/21(日) 16:28:58
memmoveを使うというのは、いったんメモリに読み込んで、ずらして書き直すってことだよ。
138134:2009/06/21(日) 16:40:27
それでもいいお。
139デフォルトの名無しさん:2009/06/21(日) 17:25:21
C++ の動作の質問です。以下のようなクラスがあったとして、ifブロックのスコープ内で文字配列のポインタをセットした時、
スコープを外れてもそれは有効な内容として保持されてるんでしょうか。

Class ClsA {
private: char* p;
public:
 void setStr(char* pt) {
  p = pt;
 }
};
int main() {
 ClsA ca;
 if(TRUE) {
  ca.setStr("ABC");
 }
 // この時点でインスタンス内の"ABC"は保持されているのか
}

もし、ブロックのスコープから外れても、インスタンス ca が保持するポインタの指す先は消えないとしたら、
この文字配列は delete しなければなりませんか?
140デフォルトの名無しさん:2009/06/21(日) 17:27:34
スコープを外れていないので、保持されている。
141デフォルトの名無しさん:2009/06/21(日) 17:29:02

定数文字列”ABC”がプログラムが終了するまで存在する
142デフォルトの名無しさん:2009/06/21(日) 17:29:46
>>139
保持されているが、deleteすべきものがない
143デフォルトの名無しさん:2009/06/21(日) 17:32:28
>>140-141
ありがとうございます。つまりこれは、
グローバルスコープにある char型配列(自動変数)と同じ、って考えていいんでしょうか
144デフォルトの名無しさん:2009/06/21(日) 17:33:22
変数ではなく定数
145デフォルトの名無しさん:2009/06/21(日) 17:34:18
グローバルなのに自動変数とはこれいかに?
自動変数の自動とは、レジスタやスタックで確保されているということじゃないのか?
146デフォルトの名無しさん:2009/06/21(日) 17:40:11
ごめんなさい。自動変数じゃなくて定数。 ちなみに、何を不安に思っているかと言うと、

{
 char a[3];
 a[0] = 'A'; a[1] = 'B'; a[2] = 'C';
 ca.setStr(a);
}
// スコープを外れた時、ca の中のポインタは有効な物として使えるか

のようにした時と、動作的にどう違うのかがわからないのです。ちなみにこの例だときっとアウト。
しかし定数ならOKって、どうして?
147デフォルトの名無しさん:2009/06/21(日) 17:46:30
それが、自動変数と定数の仕様だから
148デフォルトの名無しさん:2009/06/21(日) 17:48:40
素直にstringあたり適当につかっちゃいなYO
149デフォルトの名無しさん:2009/06/21(日) 17:52:37
>>147
>>146 のソースでも、大本の文字は定数として書かれていて、char型配列はそのメモリ領域のアドレスを指している
そのアドレス値をコピーしたポインタを使っているって事は

→ 定数領域を指すポインタになっているので、プログラムが終了するまで保持される。

スコープを外れた時、char配列 a そのものは自動変数なのでスタックから削除されるが、
定数領域そのものはプログラム終了まで解放されない

→ その解放されない領域をポインタは指しているから、結果的に有効である

って解釈でいいんでしょうか
150デフォルトの名無しさん:2009/06/21(日) 17:53:36
>>148 いや、動作の理屈が知りたいんです
151デフォルトの名無しさん:2009/06/21(日) 17:55:04
あ、ちょっとまて、配列は自動変でそのポインタは壊れる
152デフォルトの名無しさん:2009/06/21(日) 17:58:35
壊れるっていう表現は正しくないな、そのポインターの先は保障されない。
が正しいか
153デフォルトの名無しさん:2009/06/21(日) 17:59:49
>>151 壊れるんですか・・・ もし壊れるとするとますます

ca.setStr("ABC"); と、

char* a = "ABC";
ca.setStr(a); の、

違いがわからなくなってくる・・・ 一旦スコープ上に自動変数の形で置いたらアウト、って事なんでしょうか
直で"ABC"を渡した時は、その受け手はメソッド内の変数だから、って言う
154デフォルトの名無しさん:2009/06/21(日) 18:04:30
定数は壊れない、
定数を参照する自動変数はスコープを外れたら保障されない。
定数の値を入れた自動変数はスコープを外れたら保障されない。

簡単だって、自動変数はスコープを外れたら保障されない。
だけ
155デフォルトの名無しさん:2009/06/21(日) 18:19:42
>>154 そうすると、

ca.setStr("ABC");

と、置いた時、動作の順は 「定数 → 引数 → メンバの変数」 って移り変わりますが、
それでも大丈夫なんでしょうか。 あるいは

class ClsA {
public: char* p;
};

ClsA ca;
ca.p = "ABC"; //これなら確実

みたいにした方がいいんでしょうか。何度もすみません
156デフォルトの名無しさん:2009/06/21(日) 18:25:22
上は、定数のアドレスデータが渡されているだけなので、自動変数を
中継に使っただけだから問題ない。
もちろん下は、定数のアドレスを入れているから問題ない。
この場合はどちらも問題ない。 
上の自動変数は単なる中継、中継後壊れても問題は無い。
157デフォルトの名無しさん:2009/06/21(日) 18:26:32
この場合の中継する自動変数は 引数のことな。間違えないように
158デフォルトの名無しさん:2009/06/21(日) 18:31:15
あああそうか! 上の例の中継(引数)は自動変数でもあるけど、
自分が消える前にアドレスをメンバにコピー(アドレスの値渡し)して死ぬから、それはそれで問題ないって事ですか

あれ?でもそうすると >>153 の下の例(char* に一旦アドレスを取り、そのアドレス値をメソッド引数に値渡しする)も、
同じ状態になる気がするんですが、あっちも大丈夫って事でしょうか
159デフォルトの名無しさん:2009/06/21(日) 18:33:57
定数文字列の先頭アドレスが入るだけだよ
160デフォルトの名無しさん:2009/06/21(日) 18:35:00
>>153が駄目だと言っていないと思うけど。
161デフォルトの名無しさん:2009/06/21(日) 18:35:15
>>158
下の例も問題ないよ
162デフォルトの名無しさん:2009/06/21(日) 18:35:59
 char a[3];
 a[0] = 'A'; a[1] = 'B'; a[2] = 'C';

 char* a = "ABC";
は違うよ
163デフォルトの名無しさん:2009/06/21(日) 18:38:32
なんかわかってきました。

1) char a[3]; a[0] = 'A'; a[1] = 'B'; a[2] = 'C'; // スコープ外れたらポインタの先は保証されない
 ca.setStr(a);

2) char* a = "ABC"; // インスタンス消えるまでポインタは有効
 ca.setStr(a);

3) ca.setStr("ABC"); // 2と同じ

この中で 1だけがアウトな理由は、1だけは直で定数のアドレスを指していないから。って事ですね! なんか納得できました。
スレ汚し失礼しました。 ありがとうございました。
164デフォルトの名無しさん:2009/06/21(日) 18:39:54
>1だけは直で定数のアドレスを指していないから
そ、これが大正解
165デフォルトの名無しさん:2009/06/21(日) 18:45:45
ちなみに自分の理解のまとめ:
>>163 の2と3のケースは、即値の書かれたメモリ上のある1点を直接指していて、その領域(この場合は定数の)はプログラム終了まで解放されない。

1のケースは、「定数1文字の書かれた領域を示すアドレスの、そのアドレステーブルの先頭の、」 アドレスをポインタにコピーしているので、
配列(自動変数)に寿命が来たとき、コピーされたポインタの指す先は保証されなくなる。

似たような事で悩んでいる人がいるとあれなので、メモしておきます。 ありがとうございました。
166デフォルトの名無しさん:2009/06/21(日) 18:48:55
なんか1のケースの解釈がへんじゃね?
定数1文字の書かれた領域を示すアドレスなんてものは使ってないよ。
167デフォルトの名無しさん:2009/06/21(日) 19:00:35
>>166
char a[3];
a[0] = 'A';

この時、a[0] って言う変数は、定数領域にある 'A' を指していて、
a は自動変数領域にある、a[0]〜a[2] のアドレステーブルを指している。これは、

Foo f[3]; であっても同じで、配列名 f は、アドレステーブルを示す物(値はそのアドレステーブルの先頭アドレス)
って、解釈じゃ間違いでしょうか。 なんか長引いて申し訳ないです
168123:2009/06/21(日) 19:01:25
>>127 ありがとうございます。
169デフォルトの名無しさん:2009/06/21(日) 19:06:41
>この時、a[0] って言う変数は、定数領域にある 'A' を指していて、
指してない
170デフォルトの名無しさん:2009/06/21(日) 19:11:07
文字を画面の真ん中あたりに表示させたいのですが、
座標を指定する方法がわかりません。
どうすればいいのですか?
171デフォルトの名無しさん:2009/06/21(日) 19:13:12
>>168
ちなみにbは必要ない

>>170
API使うか
コンソールサイズを固定とみなして計算
172デフォルトの名無しさん:2009/06/21(日) 19:15:37
>>169 こういうイメージを持っていました。

メモリマップイメージのモデル:

自動変数領域 ※スコープの終了と共に解放される
    +0 +1 +2 +3 +4 +5 +6 +7
8000 10 80 11 80 12 80 00 80 a[0] a[1] a[2] a
8008 00 00 00 00 00 00 00 00

定数領域 ※プログラムの終了と共に解放される
8010 41 42 43 00 00 00 00 00 ABC
8018 00 00 00 00 00 00 00 00
173デフォルトの名無しさん:2009/06/21(日) 19:16:38
1は単に値のコピーだね。だからcharが破壊されると値も破壊される。
174デフォルトの名無しさん:2009/06/21(日) 19:20:13
ああ・・・ int i = 10; と同じような値のこぴー・・・

なんか深く考えすぎたかもしれない
175デフォルトの名無しさん:2009/06/21(日) 22:16:47
ためせボケ
うぜぇんだよ
176デフォルトの名無しさん:2009/06/21(日) 22:37:41
で、試すとどんな状況でもたいがいちゃんと表示されちゃうんだよな。
メモリの中身がゴミになったかどうかは単純な実験では確認できない。

C言語知らない人間にはこのことが理解できない
177デフォルトの名無しさん:2009/06/21(日) 22:44:26
アドレス理解してるじゃねぇか
なんでメモリがわかんねーんだよ
新手の嫌がらせか
178172:2009/06/21(日) 23:04:01
>>176 それ!表示されちゃうんです。 使う分にはそれでいいんだけど、動作を知りたい。
で、知らずに少しづつリークしてくような作りを書きたくなかった。 だから知りたかった。

>>177 嫌がらせじゃないです。 じゃあ >>172 のイメージで合ってるんですか?
あのメモリマップは、あくまで自分の想像です。 動きを観察したらああなのかなぁって思った。
元々、Z80A でずっとアセンブラを書いてた事があるので、自分ならああいうイメージにするって思った。

でも、>>169 さんに 「指していない」 と指摘を受けたので、そのイメージじゃないのかなって確認の為に書きました。
>>172 のモデルでは、変数はアドレスを指しています。 もし違うとしたら、 8000H から 41 00 42 00 ・・・ って収まる事になる。

でも結局、即値が入ってるにしても何にしても、実際には自動変数領域にサイズ情報くらいは格納してると思うので、
不定バイト長であっても処理系がうまいことしてくれるのかなと考える事にしました。 長々とすみません。
179デフォルトの名無しさん:2009/06/21(日) 23:12:45
やはりアセンブラからCへの昇格だったか

int a = 10;
int *p = NULL;
p = &a;

printf( "%d\n", *p );

これを理解しろ クラスやらポインタが指してるとかはそれ以後の問題だ
180デフォルトの名無しさん:2009/06/21(日) 23:14:39
ほとんど読んでないけどデバッガ使えばいいんじゃないの
181デフォルトの名無しさん:2009/06/21(日) 23:17:40
不定バイト長でよろしくやってくれると思ってるのか?

printf( "int:%d\n", sizeof(int) );
printf( "double:%d\n", sizeof(double) );
printf( "char:%d\n", sizeof(char) );
printf( "char[4]:%d\n", sizeof(char[4]) );

で、自分の環境を調べろ
処理系がうまいことやるわけない
182デフォルトの名無しさん:2009/06/21(日) 23:20:41
>>178
'A'と単純に書いたとき、それは'A'の文字コードとして扱われる。
それを配列の要素に代入したとき、配列のメモリ領域にその数値が格納される。

"A"と書いたとき、Aと\0が静的な(場合によってはReadOnlyな)連続領域に配置され、
その先頭アドレスを表す。
183デフォルトの名無しさん:2009/06/21(日) 23:22:32
>>179 その内容だと、多分 >>172 のモデルになると思います。
変数領域のアドレスの即値を、ディープコピーでポインタ変数の値としてコピーしている
184デフォルトの名無しさん:2009/06/21(日) 23:25:54
>>182 ああああああ ありがとうございました!
それが聞きたかった。 定数 'A' と 定数 "A" の、明確な違い。 すっきりしました、ありがとう!
185デフォルトの名無しさん:2009/06/21(日) 23:39:19
>>184
よかったw
たぶんあなたはポインタで詰まることはなさそうなので、今後は楽かもw
186デフォルトの名無しさん:2009/06/22(月) 06:34:28
char buf[256];
string st;

st = buf;

のようにしたいのですが当然コンパイルエラーです
どうやってstring型にchar配列を代入できるのでしょうか?
187デフォルトの名無しさん:2009/06/22(月) 06:41:16
st = (string)buf;
188デフォルトの名無しさん:2009/06/22(月) 07:06:52
>>186
本当にコンパイルエラー出た?

>>187
でたらめ書くな
189186:2009/06/22(月) 07:33:36
>>187
ありがとうございました
190デフォルトの名無しさん:2009/06/22(月) 08:15:58
えええ!?
187がコンパイルできるなら186も問題ないはずなんだけど。
191デフォルトの名無しさん:2009/06/22(月) 08:30:37
これ以上は通報するぞ?
192デフォルトの名無しさん:2009/06/22(月) 08:34:34
それまじでいったん
193デフォルトの名無しさん:2009/06/22(月) 08:42:00
st = (string)buf;   // >>186の期待とは違う動作

st = buf;  // 問題ない動作
俳味がぜんぜん違います。
コンパイルエラーは、#include が正しくない
194デフォルトの名無しさん:2009/06/22(月) 09:04:59
char buf[256];
string st(buf);

これがベスト
195デフォルトの名無しさん:2009/06/22(月) 09:14:32
だから

st = buf;

はコンパイルエラー出ずに通るっしょ?
コンパイルエラーが出るとか嘘を書くなっつーの
196デフォルトの名無しさん:2009/06/22(月) 10:00:08
質問者逃亡
197デフォルトの名無しさん:2009/06/22(月) 11:13:19
assert()に失敗した時に値を表示するようにできないでしょうか? 例えば
  assert (x >= 0 && x < WIDTH);
の行でアサートで落ちたときにxの値を表示してほしいのです。
198デフォルトの名無しさん:2009/06/22(月) 11:19:00
授業で提示されたサンプルでは、
srand(time(NULL));
secret_number=rand() % 9 + 1;
で1〜9の乱数を生成しているのですが、このようなやり方で命令を使わずに
4桁の乱数(1000〜9999)を生成するにはどうすればいいのでしょうか?
199デフォルトの名無しさん:2009/06/22(月) 11:22:31
rand() % 9000 + 1000
200デフォルトの名無しさん:2009/06/22(月) 11:23:29
#ifdef NDEBUG
#define assert_or_show(a,b) ((void)0)
#else
#define assert_or_show(a,b) ((a) ? (void)0 : \
wsprintf(g_sz, "file %s, line %d: (%s), %d", __FILE__, __LINE__, #a, b), \
MessageBox(NULL, g_sz, NULL, 0))
#endif

char g_sz[1024];
assert_or_show(x >= 0 && x < WIDTH, x)
201デフォルトの名無しさん:2009/06/22(月) 11:24:15
>>198
命令って何?
202デフォルトの名無しさん:2009/06/22(月) 11:29:49
>>199
それだと、 1000~6766の出現確率が6767~9999の出現確率の1.33倍になるぞ。
(RAND_MAXが32767の場合)
203197:2009/06/22(月) 11:33:17
>>200
完璧です。欲しかったのはそういうASSERTです。
恐れ入りました。
これからもっともっと精進します。
204デフォルトの名無しさん:2009/06/22(月) 11:35:52
srand(time(NULL));
secret_number = (int)((rand()/((double)RAND_MAX+1.0f))*(10000-1000))+1000;
205デフォルトの名無しさん:2009/06/22(月) 11:41:18
>>199
>>204
上ので出来るみたいですね。数学に疎いものでよくわかりませんが・・・
命令というより関数?ですか。どうもありがとうございました
206デフォルトの名無しさん:2009/06/22(月) 11:54:59
>>205
>>199>>202の欠点があるので実用に使うなら>>204がオススメ。いや>>199書いたの俺なんだけどw
RAND_MAXが未定義でエラーになるなら、stdlib.hをインクルードしてちょ
207デフォルトの名無しさん:2009/06/22(月) 12:09:40
BCCでDirectX9は使えるの?
ライブラリは7までしかないって聞いたけど
208デフォルトの名無しさん:2009/06/22(月) 12:39:41
http://www.geocities.co.jp/Milano/8000/bcc/index.html#dx8sdk
あとは implib.exe を使い DLL からライブラリを作れば、ある程度なら DirectX 8 も DirectX 9 も利用できます。
209デフォルトの名無しさん:2009/06/22(月) 12:58:04
>>201
OPコード
210デフォルトの名無しさん:2009/06/22(月) 16:56:08
>>206
ありがとうございます。無事修正して提出できました。
211デフォルトの名無しさん:2009/06/22(月) 18:06:06
enum ID {
 ID_ABC,
 ID_DEF,
 ID_GHI,
 ...
};
struct IDITEM {
 enum ID id;
 const char *name;
};
という定義があったとして、

struct IDITEM table[] = {
 {ID_ABC, "ID_ABC"},
 {ID_DEF, "ID_DEF"},
 {ID_GHI, "ID_GHI"},
 ...
};
という宣言を簡単にマクロでつくれないでしょうか。
イメージとしては

#define DECL(id) {id, "id"}

struct IDITEM table[] = {
 DECL(ID_ABC),
 DECL(ID_DEF),
 DECL(ID_GHI),
 ...
};
みたいな。でも id を " で囲む方法がわかりません。"##id##" じゃないし...
どうすればいいでしょう?
212デフォルトの名無しさん:2009/06/22(月) 18:14:47
#define DECL(id) {id, #id}
の、どこがダメなんですか?
213デフォルトの名無しさん:2009/06/22(月) 18:26:53
>>212
どういうエラーが出るの
214デフォルトの名無しさん:2009/06/22(月) 18:56:52
>>213
ちがうちがう、>>212!=>>211だぞ
215デフォルトの名無しさん:2009/06/22(月) 21:28:02
クラス定義の中でusingを使いたいんですが、どうやれば使えるようになるんでしょうか?
とりあえず試したのはしたの2パターンですがだめでした

class Class {
  using std::string; // 失敗!
  std::string str; //<- string だけにしたい
};

namespace name {
  using std::string;
  class Class {
    string str;
  };
}
// name内のほかの場所でもusingが有効になってしまう。失敗!    
216デフォルトの名無しさん:2009/06/22(月) 22:28:29
>>215
不可能。

擬似的に実現したいなら
class Class {
  typedef std::string string; // 成功
  string str; //<- string だけ
};

これで満足?
217デフォルトの名無しさん:2009/06/22(月) 22:37:24
満足です。ありがとうございました
メンバの引数に長い名前空間が沢山出てきたときのタイプ量を減らしたかっただけなのです
218デフォルトの名無しさん:2009/06/22(月) 23:20:25
仮想関数にテンプレートを適用したいのですが、どうやれば使えるようになるんでしょうか?

template<typename T,unsigned U>struct A{virtual int operator()(T&)const{return U;}
template<typename T>struct BASE: A<T,0>,A<T,1>A<T,2>{}
template<typename T>struct B:BASE<T>{template<unsigned U>int A<T,U>::operator()(T&);}

としてもだめでした。
219デフォルトの名無しさん:2009/06/23(火) 00:18:39
>216
そのtypedefは面白いな
220デフォルトの名無しさん:2009/06/23(火) 01:51:54
バネとダンパーにぶら下がった重りの変位を求めるプログラムなのですが

#include<stdio.h>
#include <math.h>
void euler(double *,double *,double *,double *);
double acceleration(double,double,double);

main(){
double x,v,t,dt,tt;
dt=0.1;
x=0.05;
v=0.0;
t=0.0;
tt=300.0;//出力を開始する時刻

while(t<tt+10.1){
if(t>=tt){
printf("%lf\t%lf\n",t,x);
}
euler(&x,&v,&t,&dt);
t+=dt;
}
return(0);
}
221220:2009/06/23(火) 01:53:14
/*Function euler()*/
void euler(double *x,double *v,double *dt,double *t){
*x+=*v**dt;
*v+=acceleration(*x,*v,*t)**dt;
}

/*Function acceleration()*/
double acceleration(double X,double V,double T){
double a;
a=-(0.5*V)-X+sin(2.0*T);
return(a);
}

出力結果に1.#QNANOという数字が出てきてしまうのですが、これはなぜですか?


222デフォルトの名無しさん:2009/06/23(火) 02:06:22
> *x+=*v**dt;
キモっ

>*v+=acceleration(*x,*v,*t)**dt;
キモっ
キモっ
223デフォルトの名無しさん:2009/06/23(火) 02:09:03
>>222
きもいだけか
224デフォルトの名無しさん:2009/06/23(火) 02:34:37
>>220
オーバフローだね> 1.#QNANO
ためしにtt=300.0じゃなくてtt=60.0ぐらいから表示してみると、
65秒あたりからX座標がめちゃくちゃ発散しちゃってますぜ
225デフォルトの名無しさん:2009/06/23(火) 12:39:37
tとdtはポインタで渡す必要ないじゃん
226デフォルトの名無しさん:2009/06/23(火) 13:26:05
別にアドレス渡しでもいいじゃん
227デフォルトの名無しさん:2009/06/23(火) 17:08:17
int StrToIntDef(const char *s, int def) {
 char *err;
 int val = strtol(s, &err, 0);
 return (ア);
}
のとき、(ア)の部分は

1: err ? def : val
2: *err ? def : val
3: (err && *err) ? def : val

どれがいいの?
228デフォルトの名無しさん:2009/06/23(火) 17:25:59
>>227
2じゃね。errにNULLが返ることはない
229デフォルトの名無しさん:2009/06/23(火) 18:18:38
この仕様だと
strtol("", &err, 0)
とした場合に
err[0] = '\0' になるんだよな.......
230デフォルトの名無しさん:2009/06/23(火) 18:36:42
名前空間を消すためのtypedefに、templateのtypedefを使いたいんだけど
こんなごまかし方以外になんかないかな?

template <typename type> class smart_ptr {
public:
 typedef std::tr1::shared_ptr<type> shared;
 typedef std::tr1::weak_ptr<type> weak;
};

class CHoge {
public:
 ...;
private:
 smart_ptr<int>::shared p;
};
231デフォルトの名無しさん:2009/06/23(火) 21:33:05
>>230
C++_名前空間
ttp://www.geocities.jp/cbc_vbnet/vc/namespace.html#namespace
ここの
名前空間の別名定義
がなんか役立たないかな?

あと、そもそも名前空間を回避するようにコードするのは余り良くないことだよ?
せっかく名前空間という仕様があるのだから、ねぇ。

232デフォルトの名無しさん:2009/06/23(火) 22:31:11
thxです
しかし、求めてるものとはちょっと違いました

なんで名前空間を隠蔽したいかというと
今vc++で使ってるstd::tr1::が将来std::になるらしい(?)ということを聞いたので
今後std::tr1をできるだけ手間無くstdに変えられるように書きたいなと思ったからです
namespace std = std::tr1みたいなことができれば、1行消すだけでstd::tr1→stdになって楽なんですけどできませんでした
マクロしかないんでしょうかねぇ
233デフォルトの名無しさん:2009/06/23(火) 22:36:16
namespace std { using namespace std::tr1; }
234デフォルトの名無しさん:2009/06/23(火) 22:36:21
>>232書いた直後にためしたので解決?できた。できてんのかな?

namespace std {
 using namespace std::tr1;
}

std::shared_ptr<hoge> hoge;
235デフォルトの名無しさん:2009/06/23(火) 22:37:36
>>233
書き込む前にレス気がつきませんでしたがthx
236231:2009/06/23(火) 23:05:47
>>232
具体的にそう言ってくれないとさぁ・・・。
エスパーじゃな…(ry


std::tr1::はそのままの方がいいと思うのだが。
むりにstd::名前空間に引っ張ってこない方が。
だって将来std::になるだろうという予定なだけだし、
どうしても直したかったらgrepで適当に置換すればいいだけじゃないか。
237231:2009/06/23(火) 23:07:30
>>236
×どうしても直したかったら
○実際にstd名前空間に入れもらえて、
○さらにC++0xが一般的にサポートされるようになった時
○一斉に直したかったら

の意味ね。
238デフォルトの名無しさん:2009/06/23(火) 23:22:21
grep使ったこと無いです><
こんど使ってみます
239デフォルトの名無しさん:2009/06/23(火) 23:23:24
>>238
ああ、知らないなら俺のレスを
単に「検索して置換」って読み替えてくれてもいいよ。
240デフォルトの名無しさん:2009/06/23(火) 23:24:01
gotoなんか一生使うな。って、スレ違ってないか?
241デフォルトの名無しさん:2009/06/23(火) 23:28:23
>>240
?誰にレスってるの?
242デフォルトの名無しさん:2009/06/24(水) 01:59:35
grepがgotoにみえるほどつかれていたんだろうよ
243241:2009/06/24(水) 14:19:59
理解。
244デフォルトの名無しさん:2009/06/24(水) 14:45:37
virtualついてないメンバ関数はなるべくオーバーライドしないほうがいい、でおk?
245デフォルトの名無しさん:2009/06/24(水) 15:13:52
ポリモルフィズムと名前の隠蔽がどういうものか理解していれば
別に非仮想関数をばんばんオーバーライドしてもいいぞ。

でもしないほうがいいのは確かだね。
厄介ごとにわざわざ首を突っ込む必要はないから。
246デフォルトの名無しさん:2009/06/24(水) 15:32:09
>>244
とりあえずEffective C++を読むといいよ。
道しるべになってくれる。
247デフォルトの名無しさん:2009/06/24(水) 16:06:47
Effective C++はまさに今読んでます
隠蔽の仕組みも大体わかってるつもりなんですが
ベースのポインタから呼んだときとサブの変数から呼んだときで
呼ばれる関数が違うのがじゃっかん気持悪くて・・・
後のメンテナンスがめんどくさそうな気がするからオーバーライドしないほうがいいのかなー、と
248デフォルトの名無しさん:2009/06/24(水) 16:21:44
>>247
>>247
> ベースのポインタから呼んだときとサブの変数から呼んだときで
> 呼ばれる関数が違うのがじゃっかん気持悪くて・・・
若干どころじゃない!
そういうのは代表的なクソ設計の一つ。

君の感覚が正しい。
すなわち
 基底クラスのポインタに、派生クラスの変数のアドレスや
 基底クラスの変数のアドレスを入れて同じインターフェースで操作する
というのを
 ポリモーフィズムpolymorphism的な使い方
という。
 例:
   BaseWindowClass{virtual void visualize(){}};
   Derived_1_WC : BaseWindowClass{void visualize(){}};
   Derived_2_WC : BaseWindowClass{void visualize(){}};
  にて
   BaseWindowClass * p = new BaseWindowClass();
   BaseWindowClass * q = new Derived_1_WC();
   BaseWindowClass * r = new Derived_2_WC();
  のような状況の時、
   Func(const BaseWindowClass * arg){arg->visualize()}
  にp,q,rを全部区別無く渡せる。

そしてポリモーフィズム的な使い方をされることが前提の場合、
そのメンバ関数はvirtualにすべき。

逆にポリモーフィズム的な使い方をされないなら
virtualでないメンバ関数をオーバーライドすることもありえるだろう。
249248:2009/06/24(水) 16:23:54
逆に

他人の作った基底クラスが
ポリモーフィズム的な使い方をするハズのクラスなのに
virtual宣言されていないメンバ関数がある場合、
「そのメンバ関数はオーバーライドしないでくれ」
という基底クラス設計者のメッセージと受け取るべき。
250デフォルトの名無しさん:2009/06/24(水) 16:43:25
インターフェースの継承では仮想以外いじらない
ベースの一部の機能が欲しいだけのときとかは臨機応変に可
ということですね。参考になりました。thxです
251デフォルトの名無しさん:2009/06/24(水) 16:45:38
基底クラスの一部分しか機能を使わないなら継承しちゃダメよ。
継承は「is a」の関係でないといけない。

まぁ、そんなことは気にせず、例えばvectorとかstringとかを継承して
おもしろいことにしちゃうのもおもしろいけどね(初心者のうちは…)。
252デフォルトの名無しさん:2009/06/24(水) 17:00:09
インターフェースの継承では仮想以外いじらない
その他の場合はいじらないでいいならいじらないが臨機応変に可
こ、これでおk・・・かな
253248:2009/06/24(水) 17:18:36
俺は>>251とは別人だが。

>>252
> インターフェースの継承では仮想以外いじらない
『Effective C++』用語でいうところのインターフェースの継承とは
純粋仮想関数のオーバーライドのことだったと記憶している。

polymorphicな使い方をされる想定の基底クラスについて
 純粋仮想関数(定義無し)=>インターフェースのみの継承。実装は各自で0から作れ。
 純粋仮想関数(定義あり)=>インターフェースの継承。実装は各自で作れ、ただし基本コードは提供してあげるよ。
 仮想関数=>インターフェースの継承。ただしデフォルトの実装も提供するので必ずしも各自で作る必要はない。
 非仮想関数=>インターフェースと実装の継承。オーバーライドするなってことだ。

ここまでは分かってますかい?
なお、
polymorphicな使い方をされない想定の基底クラスのメンバは
デストラクタ含め全て非仮想関数になっている。STLなど。
逆に言えば
仮想関数を持つクラスはpolymorphicな使い方をされることを想定
しているわけであり、デストラクタも仮想になっている。

以上、全てpublic継承の話ね。
254デフォルトの名無しさん:2009/06/24(水) 17:49:52
仮想化の種類と特徴はわかってます

public継承でベースにvirtualがひとつでもあるなら
それはポリモーフィックな使い方をすることが前提→virtual以外はオーバーライドしない
ほかの場合は適宜、ということでしょうか?若干混乱してきた
もうちょっとEC++読み進めたほうがよさそうですね
255デフォルトの名無しさん:2009/06/24(水) 18:03:27
>>254
> public継承でベースにvirtualがひとつでもあるなら
> それはポリモーフィックな使い方をすることが前提→virtual以外はオーバーライドしない
> ほかの場合は適宜、ということでしょうか?

あってるよ。
まあ、それだけ理解出来ていればすぐ慣れるさ。
がんがれ
256デフォルトの名無しさん:2009/06/24(水) 18:18:21
>>254
意味は理解できてても、どういった場合に使うのが妥当かが理解できてい
ないと思われ。単に経験だな
257デフォルトの名無しさん:2009/06/24(水) 18:50:10
深さ優先探索とスタックの関係
幅優先探索とキューの関係がまったく分かりません。

用は何がしたいんですか?

教科書の説明だとそれぞれのノードに
番号つけるだけみたいな説明なんですけど
番号つけるのとスタック、キューがどうリンクしているのかまったく分かりません。

それと教科書に
”グラフの点は、深さ優先探索ではスタックで管理され
幅優先順ではキューで管理される”
とありますが、結局は番号とその番号に収納されてるデータを
配列で対応させるのが目的なんでしょうか?

よろしくお願いします。
258デフォルトの名無しさん:2009/06/24(水) 18:58:17
探索がしたい

エスパーすると
CPU時間が異なる
259デフォルトの名無しさん:2009/06/24(水) 19:33:57
エスパーすると
>配列で対応させるのが目的なんでしょうか?
違う
260デフォルトの名無しさん:2009/06/24(水) 19:42:36
マジなエスパー要請キタ!
261デフォルトの名無しさん:2009/06/24(水) 20:11:59
>>258
データが同じなら、CPU時間にそれほど違いは無いかな
まあキューの方が遅そうだが。
エスパーに対してエスパーしてみた。メタエスパー?
262デフォルトの名無しさん:2009/06/25(木) 00:42:20
構造体に関連してtypedefを勉強していて分からない箇所がありました。
---------------------------
typedef struct _tagData {
int age;
double bl;
double bw;
} MYDATA, LPMYDATA;
とすると、_tagData型の構造体変数を宣言するとき
MYDATA mydata; と書くことができます。

また、この構造体へのポインタを宣言するときも
LPMYDATA lpmydata; と書くことができます
---------------------------
変数を宣言するまでは理解できるんですが、
MYDATA mydataと書くことができるってくだりが分からないんです。
そもそも意味が・・。
分かりやすく解説していただけませんか?
263デフォルトの名無しさん:2009/06/25(木) 01:36:12
>>262
typedefしておくと、その型を使うときstructキーワードがいらないってこと

-----------------
struct _a {int foo; double bar;}; /*「struct _a」型を普通に定義 */

int main()
{
 struct _a mydata; /* 使うときにもstructキーワードが必要 */
}

-----------------
struct _a {int foo; double bar;}; /* 上と同じ「struct _a」型を… */
typedef struct _a A; /* このようにtypedefすると */

int main()
{
 A mydata; /* structキーワード不要、型名Aだけでよい *//
}
264デフォルトの名無しさん:2009/06/25(木) 01:57:11
図解
 typedef ○○○ 定義名

 ※○○○は改行して記述してもよい。定義名はカンマ区切りで複数書いてもよい

   ↓

 typedef ○○○
  ○○
  ○○
 ○ 定義名

 ※○の所に、struct の宣言を埋め込んでみよう。 何故そうしたいのか、は >>263 参照
265デフォルトの名無しさん:2009/06/25(木) 02:46:50
>>263-264
なるほど、ありがとうございます。
構造体で使う場合としては単にstructなどを省略するための関数と捉えていいんですよね?
大規模なプログラムを書くときにはこれが活きてくるのでしょうか?
本に書いてあるレベルではメリットがあまり感じられないので。。
266デフォルトの名無しさん:2009/06/25(木) 04:18:15
>265
そんな感じ。

もし仮に、その構造体をtypedef無しで5個とか10個とか使うことになった……と想像してみればいいと思うよ。
たぶんイヤな気持ちになれるから(笑)


他にも、1つのプログラムを複数の人で分けて書いている時や、
既存のライブラリ&フレームワークを使って開発するっていう時にも役に立つ。

単なるデータの受け渡しに使うだけなど、その構造体の中身を直接弄らない限り、
MYDATAの中が具体的にどうなってるか知る必要が無くなる。
つまり、使うだけならintとかdoubleとかと同列に並べることが出来るってわけだ。

もし今後、Cでファイル処理をやる機会があったら、よく見てみるといいよ。
「FILE」って名前の型が出てくるはずだから。
僕らはFILEの構造がどうなってるか知らなくてもいいし、そもそも構造体とは限らないかもしれない。


それと、蛇足かもしれないけど、最後に1つだけ。
typedefは「関数」ではないからね。
凄く細かいところかもしれないけど、もし勘違いしたままだと大変だから。
267デフォルトの名無しさん:2009/06/25(木) 04:57:22
>>266
ほんと助かりました、ありがとうございます。
今の自分にはあまり必要がないですが将来的に必要になるものですね。
FILEはもうすぐファイル入出力の項に入るのでそのとき見てみます。
関数じゃなくてデータ型でしたね、いまいち関数との違いも分かってないような
レベルでした。。ありがとうございました!
268デフォルトの名無しさん:2009/06/25(木) 06:18:30
>>266
> 凄く細かいところかもしれないけど、もし勘違いしたままだと大変だから。
お前やさしいやつだな。
俺だったらもっと厳しく言うと思う。

>>267
>関数じゃなくてデータ型でしたね、
>いまいち関数との違いも分かってないような
>レベルでした。。
typedef自身は関数でもなければデータ型でもありません。

typedefはキーワードです。(宣言指定子)
269デフォルトの名無しさん:2009/06/25(木) 06:18:37
どういたしまして。
270デフォルトの名無しさん:2009/06/25(木) 07:21:34
>>255
そうか?
常にvirtual以外はオーバーライド禁止だと思うけど
271デフォルトの名無しさん:2009/06/25(木) 08:23:09
宣言指定子って型指定子も含むんだけど
272デフォルトの名無しさん:2009/06/25(木) 08:31:31
データ型がキーワードじゃないとも読める
273デフォルトの名無しさん:2009/06/25(木) 09:34:46
>>272
それは残念な読解力ですね。
274デフォルトの名無しさん:2009/06/25(木) 13:46:22
スレ違いかとも思うのですが、他に質問できる場所を見つけられなかったので、書かせていただきます。
vc2003にてメールの送信を行おうとしています。

メール送信の最初のheloの送信時について質問なのですが、
sendを行う中身を

@"HELO name\r\n"
A"HELO name \r\n"
 (Aは\r\nの前にブランク有り)
とすると、Aでは [501 5.0.0 Invalid domain name]を返却されることがあります。

Aでもheloが通るマシンは合ったのですが、
SMTPサーバによっては、"name "を名称と取ってエラーを返却するということなのでしょうか?

Aではエラーが発生しましたので、@の形に修正するのですが、
@では私が接していないサーバでもエラーなく動かせるのでしょうか?

このような細かい部分を載せてあるHPが見つけられなかったため質問させていただきました。
他にもメール送信時の決まりごとの参考となるようなHPを教えていただけると助かります。
275デフォルトの名無しさん:2009/06/25(木) 13:56:43
ライツアウトで。勝敗判定。ゲームログ。新しいゲームデータの作成。
http://www.ee.t-kougei.ac.jp/~kondo/kiso_pro/lightsout2009e.pdf
言語問わずで・・・Unixで動けばなんでも・・・。
276デフォルトの名無しさん:2009/06/25(木) 14:30:43
>275
知ってるか?
そのURLは、大学内からじゃないとアクセスできないんだぜ?

つーかその、なんだ。俺の母校じゃねーか(笑)
277デフォルトの名無しさん:2009/06/25(木) 14:31:30
>>274
>他に質問できる場所を見つけられなかったので
なんだろう…ネットワーク?ちょと違うか。

>SMTPサーバによっては、"name "を名称と取ってエラーを返却するということなのでしょうか?
RFC では、<CRLF> の前の空白を許容せよと書いてある。が、
許容しないサーバがあるというなら、あるんだろう。

>@では私が接していないサーバでもエラーなく動かせるのでしょうか?
互換性の為にHELOは通せ、と書いてあるし、そこは多分大丈夫かと。

>他にもメール送信時の決まりごとの参考となるようなHPを教えていただけると助かります。
↓こことか。
ttp://www.puni.net/~mimori/smtp/
278デフォルトの名無しさん:2009/06/25(木) 16:48:17
>>276
やっぱみれないか(;Ц;)
母校なら・・・なお、頼む!
279デフォルトの名無しさん:2009/06/25(木) 16:53:52
>278
だから外部からの接続じゃ見れねーから、どうしようも無いんだってば。
あと、人に質問するときは、質問の仕方と態度を覚えような?
280デフォルトの名無しさん:2009/06/25(木) 17:05:26
ロダに転載しろよ
著作権とか言われたら責任取れないけど
281デフォルトの名無しさん:2009/06/25(木) 17:17:52
確かライツアウトって、どのボタンを押すかという組み合わせの問題なんだよな。
押す順番は関係ないし、2回以上同じ場所を押す必要はない(それは押さないのと同じ)、っていう。

>280
問題を読んだところで「for文で1個ずつチェックしろ」の一言で終わりそうだけどな。
もう何年も昔だけど、Cの基礎しかやらないような講義内容だったし。

問題作成のところは、何もライトが点いていない状態から
ランダム(または任意)の箇所のボタンを押した状態にする……くらいかね?

282デフォルトの名無しさん:2009/06/25(木) 19:37:31
大学教授からのメッセージ

【うpってもいいのよ】
http://www.youtube.com/watch?v=_XKhPYjotgE
283255:2009/06/25(木) 20:28:45
>>270
それは安全だが「常に」ではないと思う。

例えば非仮想デストラクタを持つ基底クラスでオーバーライドなんて
よく・・・はないけど、たまにはあり得てもおかしくない。
さらにいえばshared_ptrで子クラスのインスタンスのアドレスを親クラスの
スマートポインタにいれてもおkなんだから。
284デフォルトの名無しさん:2009/06/25(木) 21:48:54
どうして「常に」ではないのか、理由もEffective C++に書いてあるね。
Effective C++は本当に偉大な本だ。
285デフォルトの名無しさん:2009/06/25(木) 21:59:08
private継承の時とか?
286デフォルトの名無しさん:2009/06/25(木) 22:01:53
public継承で非仮想関数をオーバーライドするのがベターって状況、具体的にどんなのがあるの?
287デフォルトの名無しさん:2009/06/25(木) 22:06:05
俺は後半の手口のメリットも知りたい
288デフォルトの名無しさん:2009/06/25(木) 22:13:29
例えば、vtblがそのクラスを他の言語に渡す邪魔になるとき。

メモリコスト、演算コスト、他のコードとの互換性などの理由で
どうしても汚い実装が必要になる現実があり
その現実に対処するために「プログラマはすべてを知っている」という原則に立っているのは
C++がCから受け継いだ実用性のひとつ、というのがメイヤーズの回答の要約かな。
289デフォルトの名無しさん:2009/06/25(木) 22:18:32
ふむ。
>>283はその「泥臭いこと」を指して「常に」ではないといったのかな。
290283:2009/06/25(木) 22:20:31
>>288さんありがとう。

>>287
> 後半の手口のメリット
俺も知りたいわ。

「非仮想デストラクタを持つ基底クラスを継承した派生クラスの
インスタンスをnewで生成してRAIIにもとづきshared_ptrに渡す」

こんな状況が起こるのはレアケースな気もするが、
知識として知っていればこんな時にも大丈夫
ってなだけかね。

291デフォルトの名無しさん:2009/06/25(木) 22:29:56
>>290
基底クラスのデストラクタを仮想に変更できない、のっぴきならない事情における最終手段の話だよね?
292デフォルトの名無しさん:2009/06/25(木) 23:00:20
>>291
他人が書いたクラスとかね。
STLではあまりやりたくないけどそういう最終手段もありってことだろうと思う。
pimplで役立ちそうだ。
293デフォルトの名無しさん:2009/06/25(木) 23:04:47
他人が書いたクラス程度の話なら仮想デストラクタに変更すればいいのに
294デフォルトの名無しさん:2009/06/25(木) 23:05:44
RAIIにもとづきとかなんかおかしい。おかしいよな?
295デフォルトの名無しさん:2009/06/25(木) 23:06:55
>>294
RAIIの概念に基づき

これでいい?
296デフォルトの名無しさん:2009/06/25(木) 23:11:54
多態性を利用したコードでメモリリークが発生するのを避けたいかつ、
RAIIな動作にしたい場合にしぶしぶそうするってことだよね?
なんかRAIIが絶対であるかのように読めたから。誤解ならごめんね。
297295:2009/06/25(木) 23:18:57
>>296
基底クラスbaseが仮想でないデストラクタをもつ場合、
その派生クラスderivedをnewしてbase* pに渡して
delete pするとメモリーリークどころか未定義動作になるはずだが。

要は
polymorphismを利用したコードに使われることを想定されていないクラス
を基底クラスにしてpolymorphicに使いたい以下略
298デフォルトの名無しさん:2009/06/25(木) 23:21:54
ん?
基底クラスが非仮想デストラクタで、

基底クラス *p = new 派生クラス
delete p

派生クラスのデストラクタが呼ばれないだけだと思ってた。
未定義なんだったらますますだめじゃね?
299297:2009/06/25(木) 23:32:25
>>298
>派生クラスのデストラクタが呼ばれないだけだと思ってた。
いや、厳密には未定義なんだわ。
 5.3.5
 if the static type of the operand is different from its dynamic type,
 the static type shall be a base class of the operand’s dynamic type
 and the static type shall have a virtual destructor
 or the behavior is undefined.
これを俺なりに訳すと
 もしオペランド(演算対象)の静的な型と動的な型が異なる場合、
 静的な型は「オペランドの動的な型の基底クラス」になる。
 そしてその静的な型は仮想デストラクタを持つべきであり、
 さもなければ挙動は未定義である。
ところが
 boost::shared_ptr<基底クラス> sh_p(new 派生クラス());
これだとsh_pが破棄される時に自動的にdeleteされるわけだが
基底クラスが非仮想デストラクタでも未定義にならないというすげー代物。
300299:2009/06/25(木) 23:34:08
そろそろ寝ないと次の日がやばいから寝るわ。
明日早いんで。

おやすみ。
301デフォルトの名無しさん:2009/06/25(木) 23:38:57
>>299
わざわざありがとう。
勉強になりました。

shared_ptrは派生クラスのポインタに変換してdeleteしてんのかなぁ。
302デフォルトの名無しさん:2009/06/25(木) 23:41:12
shared_ptr側から見れば型は明確なんだから、別にすごいわけでもないような??と横レス
303デフォルトの名無しさん:2009/06/26(金) 01:16:47
基底→派生 だけなら型は明確だけど

基底→派生1→派生2 の時、shared_ptr は派生1のデストラクタも呼んでくれるのかな
304デフォルトの名無しさん:2009/06/26(金) 01:31:15
派生2であることさえわかっているならふつうに呼ばれそうに思う。
 基底 *p = new 派生2
 派生2 *p2 = (派生2 *)p
 delete p2
と同じことというか。
shared_ptrどころかC++の知識が怪しいので、おかしい点があるかもしれないです。
305デフォルトの名無しさん:2009/06/26(金) 06:21:15
まあそうなんだけど、
コロンブスの卵的な気がするが。
306デフォルトの名無しさん:2009/06/27(土) 08:03:52
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9561.txt

ランダムアクセスについて学習していたんですが、矢印のところの効果が分かりません。
実際にプログラムを走らせてみましたがあっても無くても支障はないようなのですが・・
なければならないものなのでしょうか?
307デフォルトの名無しさん:2009/06/27(土) 08:21:54
>>306
え? 電話番号を読みこんでいるんじゃないんですか?
308デフォルトの名無しさん:2009/06/27(土) 08:32:28
>>307
非常に寝ぼけてました、すみません
無くても電話欄も表示されてたから良いかとおもったら名前欄と同じものが反映されてただけでした・・・
309デフォルトの名無しさん:2009/06/27(土) 09:40:01
某社から供給されたとあるライブラリに
コンストラクタがprivateに設定されていてfriendも無いクラスあるんですが、
こういうのってどうやって使えばいいんですか?
310デフォルトの名無しさん:2009/06/27(土) 09:44:41
GUIだけJavaでその他はC++にして
機種に依存しないソフトを作りたいんですけど
作り方の参考になるものを教えてください。
311デフォルトの名無しさん:2009/06/27(土) 09:57:15
>>309
staticなファクトリメソッドがあるとか。
312デフォルトの名無しさん:2009/06/27(土) 10:18:34
>>309
シングルトンじゃないの?
313デフォルトの名無しさん:2009/06/27(土) 10:43:03
>>309
使うなってことじゃね?
314デフォルトの名無しさん:2009/06/27(土) 12:02:05
>>310 その場合、勿論依存しない、ってのはソースコードレベルの話しだよね?
JNI で組め。 そんで環境ごとにライブラリ部分(dll、so)をコンパイル汁
315デフォルトの名無しさん:2009/06/27(土) 12:02:55
「template 付きの namespace」 的クラスじゃねーの?
316デフォルトの名無しさん:2009/06/27(土) 12:31:04
template <typename T> class Container {
public:
  typedef std::list<T> list;
  typedef std::vector<T> vector;
  // 〜
};

このtypedefつかったテクニックって一般的な名前はあるの?
317デフォルトの名無しさん:2009/06/27(土) 12:48:15
概念もクソも無い記述上の工夫、設計技量だから名前なんて必要ねえ
318デフォルトの名無しさん:2009/06/27(土) 14:45:57
staticなメンバ変数にvectorを使った場合、
うまくコンパイルできないのですが、
コンストラクタで初期化が必要とか、何かおまじないが必要なのでしょうか?


class Node [
public:
static std::vector<int> m_idlist;
int addIdList(int id);
};

int Node::addIdList(int id)
{
m_idlist.push_back(id);

return 0;
}
319デフォルトの名無しさん:2009/06/27(土) 14:52:40
>>318
vectorとか関係なく、static変数の定義も別に必要なのはOK?

vector<int> Node::m_idlist;
320デフォルトの名無しさん:2009/06/27(土) 15:18:08
おなじない、って言う考え方は害悪
321デフォルトの名無しさん:2009/06/27(土) 15:36:52
>>319
変数の再定義になっていまうので、うまくできません。

>>320
そんな深い意味があって書いたわけじゃないんですが、
もちろん、その理由も明確にしたいと思ってます。
322デフォルトの名無しさん:2009/06/27(土) 15:45:04
>>318
コンパイルはできるけどリンクができないって話なら
cppにstd::vector<int> Node::m_idlist;を追加したらどうだろうか
323デフォルトの名無しさん:2009/06/27(土) 15:49:21
>>322
できました。

そうか、クラスがいつ作られるかわからないから、
実体を外で作ってあげないといけないんですね。
ありがとうございました。
324デフォルトの名無しさん:2009/06/27(土) 15:49:52
今読み返したら>>319に書いてある orz
コンパイルできないならclass Node "["が原因だと思う
325デフォルトの名無しさん:2009/06/27(土) 16:27:00
namespace って作ったクラスとかにはもれなく付けるほうがいいの?
クライアント側のコードが::だらけですごい不快なんだけど
326デフォルトの名無しさん:2009/06/27(土) 16:58:31
スコープ解決演算子が可読性を損なうようなほどなら、適切に using namespace すればいいし。
不快とか言う事と、名前の衝突の問題を同列にするのか

あと、付けた方がいいかなんて話を疑問に思ってしまうって事は、
多分OO的な集合のイメージを持ってないって事か
327デフォルトの名無しさん:2009/06/27(土) 17:33:08
class hoge {
public:
  hoge(std::size_t n);

private:
  std::vector v;
};

hoge::hoge(std::size_t n) : v(n) {〜;}
v(n)は中でメモリの動的確保をしてるはずなのでtryしたいです
この初期化方法ではどうやって例外を使うんでしょうか?
328デフォルトの名無しさん:2009/06/27(土) 17:45:50
FileException::FileException(const char* error)
try :
m_error(error)
{
} catch (const bad_alloc& e) {
...
}

だってさ。普通は外に投げて、つまり、hogeの構築の失敗とみなして
hogeを構築しようとしているクライアントがこれを処理するようにする。
329デフォルトの名無しさん:2009/06/27(土) 17:58:32
ありがとうございます

vectorが配列を再確保したときに例外を投げた場合の流れは

vector<T>の中でnew[] bad_alloc (Tのデフォルトコンストラクタは呼ばれない)

vector<T>の中で元の配列をdelete[]

throw;

という感じでいいんでしょうか?
STLと例外の扱いって難しいですね
330デフォルトの名無しさん:2009/06/27(土) 18:22:56
>>328
知らなかった。こんな構文あるのかー
331デフォルトの名無しさん:2009/06/27(土) 23:18:22
どうやったら美しいコードが書ける様になれるんだろう
332デフォルトの名無しさん:2009/06/27(土) 23:22:11
ぐちゃぐちゃな性格のおれには無理だな
333デフォルトの名無しさん:2009/06/28(日) 09:49:39
インスタンス化禁止にするにはこれで十分でしょうか?

class non_instance {
private:
  non_instance();
};

class hoge : private non_instance {
public:
  static void fuga();
};
334デフォルトの名無しさん:2009/06/28(日) 09:52:35
C++の上級者の人はどんなプログラムの本を買いましたか?
335デフォルトの名無しさん:2009/06/28(日) 09:55:58
336デフォルトの名無しさん:2009/06/28(日) 10:00:17
>>335
みたところ初心者向けでした。
337デフォルトの名無しさん:2009/06/28(日) 10:15:24
上級者は本を書くんだよ
338デフォルトの名無しさん:2009/06/28(日) 10:53:55
C/C++ リファレンス
http://www.cppll.jp/cppreference/

HTMLHelpバージョン ※DL前に上のサイトを確認すること
ttp://www.cppll.jp/cppreference/cpp_winhelp.zip
339デフォルトの名無しさん:2009/06/28(日) 10:55:18
英語でおk な人は本家のこちら
http://www.cppreference.com/wiki/
340デフォルトの名無しさん:2009/06/28(日) 12:07:46
初心者を中級者に出来る本は?
341デフォルトの名無しさん:2009/06/28(日) 12:14:13
EffectiveC++
342デフォルトの名無しさん:2009/06/28(日) 12:15:36
中級者ってどのへんだよ
おれ的には、EffectiveC++を読んで楽しめたら中級だと思う
343デフォルトの名無しさん:2009/06/28(日) 13:35:51
俺的には
入門者,初心者,中級者,上級者
として
・『Effective C++』の内容を読むことはできる。
・『Effective C++』の内容をまだ理解していない
程度なら
初心者かなぁ。

中級者を名乗るヤツが『Effective C++』の内容すら知ってなかったら
もぐり。
344デフォルトの名無しさん:2009/06/28(日) 14:39:47
質問です。
下のプログラムでポインタを通してconst intの値を変更しようとしたが
変更は無視されました。そういう物なのですか?

#include <iostream>
int main()
{
const int I = 123;
int* ip = const_cast<int*>(&I);

std::cout << I << std::endl;
*ip = 234;
std::cout << I << std::endl;
}
345デフォルトの名無しさん:2009/06/28(日) 14:41:26
>>344
未定義の動作です。

解説したいのだが、予備知識として問いたい。
「未定義の動作」って意味知ってる?
346デフォルトの名無しさん:2009/06/28(日) 14:42:51
>>345
わかります
「鼻から悪魔」ですね?
347デフォルトの名無しさん:2009/06/28(日) 14:47:25
>>346
そう。それ。

ということは
const int I = 123;
int* ip = const_cast<int*>(&I);
*ip = 234;
が未定義動作なのだから、
「コンパイラーはいかなる動作をするバイナリを吐いても良い。」
ってことになるのは分かる?
値が変わらないどころか
君の鼻から悪魔が出てきてもおかしくないじゃない。
348デフォルトの名無しさん:2009/06/28(日) 14:49:35
ちなみに現実にはコンパイラは
const int I = 123;
これによりIが定数であるとして
以下の様なバイナリを吐いたと思われる。

 std::cout << I << std::endl;
 の部分が
 std::cout << 123 << std::endl;
 そして*ip = 234;の部分は謎のところの値を書き換え。

だから変わらないのだろう。
349デフォルトの名無しさん:2009/06/28(日) 14:53:05
c++でパイプってどうやって使うの?
350デフォルトの名無しさん:2009/06/28(日) 14:53:43
>>347>>348
ありがとうございました
これから気を付けます
351デフォルトの名無しさん:2009/06/28(日) 14:56:45
>>349
OSによる
UNIXならソケット
Windowsなら名前付きパイプ
352デフォルトの名無しさん:2009/06/28(日) 14:59:16
>>347
使用者の鼻から悪魔を出すコード書いてくださいな
353デフォルトの名無しさん:2009/06/28(日) 15:15:12
>>352
以前書いたのを実行したヤツが死亡したという話を聞いた。
だから俺はもう過ちを犯さない。
354デフォルトの名無しさん:2009/06/28(日) 15:26:42
hana = CreateHana();
hana.CreateAkuma();
hana.Call( "ジャイアン" );
355デフォルトの名無しさん:2009/06/28(日) 16:55:24
ジャイアンは耳から出て来る方が恐いお
356デフォルトの名無しさん:2009/06/28(日) 16:59:24
なんの話してんだよww
357デフォルトの名無しさん:2009/06/28(日) 17:07:09
Battle( char *a, char *b, char *c );

int main()
{
Battle( "ジャイアン", "vs", "スネ汚" );

return -032;
}
358デフォルトの名無しさん:2009/06/28(日) 17:09:21
悪魔はミギー
359デフォルトの名無しさん:2009/06/28(日) 17:29:21
>>358
>>1乙であったな。
  /|            
 //||             
    ||         /( (・゚))
  . |:|       //
 . | |       | |                  |
  | |        |. |                 .||
  | |      / |     , _____    .||
  | |      /  |     / ____  /   .||
  | |      /.   |   / /    / /     |:|
  | ||     | -‐-|   / /    / /      | | 
  | ||\   /   /   / /    | |____/ .|
  | :| \ \/    |   / /     \.______/
  | |  \      ゝノ /
  | |  /)       /
 . .|| / /       |
   | (_/       \
     /   /⌒\  \
    (___/    \__)
360デフォルトの名無しさん:2009/06/28(日) 18:08:01
未定義の動作と、環境(コンパイラ?)によって異なる動作というのが
わりとごっちゃになる
361デフォルトの名無しさん:2009/06/28(日) 20:15:44
>>360
未定義の動作と処理系定義のことかな?

未定義の動作ってのは
「動いても何が起こるかも起こらないかも分からない、鼻から悪魔が出て来るかもよ」
 例:>>344
処理系定義の動作ってのは
「コンパイラによって好き放題な結果にしてよいが、動くことは保証されている」
 例:
   const char const *p="hoge", *q="hoge";
   if(p==q){}
362361:2009/06/28(日) 20:17:24
誤操作した。
if(p==q){}
は次のように書きたかった。


 if(p==q){foo();}
 else{bar();}
これでfoo()が呼ばれるかbar()が呼ばれるかは分からないが、
どちらかは呼ばれる。
363デフォルトの名無しさん:2009/06/28(日) 20:49:54
つまり使う側からすると、

・未定義の動作
 = やめたほうがいい。最悪壊れる事もある。(少なくともメモリ上は既に壊している)

・処理系によって定義の異なる動作
 = その処理系ではどういう結果になるかを知った上で、かつ他の処理系に持っていく事が無い
    (理解と自覚あり)ならば、使っても構わない = 問題は起こらない。(それを使う事自体の是非は置いといて)

って感じか
364361:2009/06/28(日) 20:57:23
>>363
そう。
・未定義の動作
 = そもそも動かない。動かないならまだしも悪さをしうる。
・処理系によって定義の異なる動作
 = ちゃんと動く。どう動くかは処理系のマニュアル(C/C++のではなく。)を読んでください。
とも書ける。
365デフォルトの名無しさん:2009/06/28(日) 22:22:05
これはもしかするとdirectX関係の質問なのかもしれませんがよくわからないんでここで・・・

if(FAILED(○○○)){
・・・条件文・・・}

よく↑のようにif文で見かけるFAILEDとはいったいどういったものなんですか?
関数なんですかね?またどういう役割をしているんですか?
366デフォルトの名無しさん:2009/06/28(日) 22:23:25
エラー検出マクロだろ
367デフォルトの名無しさん:2009/06/28(日) 22:27:57
>>365
それだけじゃ全然分からないな。

C/C++に無いものは知りません。

DirectXスレいけ。
368デフォルトの名無しさん:2009/06/28(日) 22:42:03
ポインタ関係で悩んでいます。
int f(int **m)
な関数に
int n[10][10]
を渡すとgccでは以下のようなエラーになります。

test.c: In function ‘main’:
test.c:9: 警告: passing argument 1 of ‘f’ from incompatible pointer type

逆に、
int g(int m[10][10])
な関数に
int **n = new int*[10]; for (int i = 0; i < 10; i++) n= new int[10];
としたnを渡すと以下のようなエラーになります。

test.c: In function ‘main’:
test.c:9: 警告: passing argument 1 of ‘g’ from incompatible pointer type

上のn[10][10]と**nは似たようなものだと思うのですが関数に渡すときは別扱い
されているように見えます。2つはどうちがうのでしょうか。
何らかの方法で渡す事はできるでしょうか。
369デフォルトの名無しさん:2009/06/28(日) 22:45:44
質問です。
派生クラスのインスタンスのサイズの知りたい
のですが計測する方法を教えてください。
370デフォルトの名無しさん:2009/06/28(日) 22:50:08
>>368
int g(int m[10][10]) この関数の引数は ** 型じゃなくて、 int[10][10] 型
だから型が違うと言われて当たり前な気がする
371デフォルトの名無しさん:2009/06/28(日) 22:57:40
真偽値を返す関数foo()とbar()があるとき、
if( !(foo()) && !(bar())){〜}

if( !( foo() || bar() ) ){〜}
とではどちらが望ましいですか?
可読性やスピードなどで。
372デフォルトの名無しさん:2009/06/28(日) 22:59:13
>>370
int [10][10]型って、なんだよ。
int g(int (*m)[10])だと思うのは私だけだろうか。

int foo[n][m]が関数の引数として渡されるとポインタに成り下がるから
int (*)[m]になるはずだけど。
373デフォルトの名無しさん:2009/06/28(日) 23:02:54
>>371
関数の中身によっては、その挙動が異なるわけだが、
その部分は考慮しなくていいの?
374デフォルトの名無しさん:2009/06/28(日) 23:03:20
>>372
そこが良く混同される所。配列はポインタにならないし、ポインタじゃない。
アドレス値を持ってるだけ。 代入や比較ではアドレス値を代入したり比較したりするけど、
型は違う。 キャストすればいける。 あくまで型は int[10][10]型
375373:2009/06/28(日) 23:04:28
ごめん、勘違いしてたかもしれん。
>373は無視してくれ。
376デフォルトの名無しさん:2009/06/28(日) 23:04:35
>>373
foo()とbar()は副作用を持たない関数だと想定しています。
言葉足らずでした。

それ以外では挙動は同じになりますよね。
377デフォルトの名無しさん:2009/06/28(日) 23:17:39
char型の変数chがあり、chには
'0','1','2','3','4','5','6','7','8','9'
のいずれかの値が入っていることが分かっている。(つまりch.isdigit()がtrue)
このとき、chの中に入っている文字をint型の変数の数字として取得するには
どうするのが一番動作速度が速い?

>>41などなどで、
数字が連続している事が保証されている
という結論になってるけど、それを踏まえるなら
単純に
static_cast<int>(ch)-static_cast<int>('0')
だろうけど、これ以外に早い方法ないし標準C++ライブラリの関数はある?
378デフォルトの名無しさん:2009/06/28(日) 23:20:28
>>372
ヒント:
> int g(int (*m)[10])だと思うのは私だけだろうか。

そもそも配列サイズは固定だろ?sizeofで返る結果も違うだろ?
int[10][10] を期待してまっている関数の引数として、例えば int[2][2] の ** を渡して一致すると思うかい?
・・・ってのは逆説的な言い方だけど。

int g(int (*m)[10]) … もしも第一階層が不定サイズの内容を扱いたいなら、
vectorに突っ込んでvectorの参照でも渡しとくといい。

Javaとかだと int g(int[][] m) みたいなインタフェースが成立するけど、C++には無い。 考え方が違う
379デフォルトの名無しさん:2009/06/28(日) 23:26:08
>>377
なぜキャストするのじゃ。^^
ポインタ同士の引き算の結果はptrdiff_t(ぷんたりでぃっふんてぃー)型であり
それは一般に long int であり、仮に一般的じゃなくても
明治キャストしなくても整数型に変換されるのです。
そしてポインタの演算ほど高速な世界はありません。
380デフォルトの名無しさん:2009/06/28(日) 23:29:25
>>379
最後の一行は無関係でどうでもいい話だけど、じゃあ何故コンパイラが型違いと言ってエラーにしたと思う?
381デフォルトの名無しさん:2009/06/28(日) 23:30:23
>>380 見間違い。スルーで。スマソ
382デフォルトの名無しさん:2009/06/28(日) 23:34:21
>>374
そうなんですか。確かにキャストすると実行できました
ふーむ。キャストしないといけないのか。
仮に違うものだとしても暗黙のキャストがされるだろうと考えていたので驚きです。

ありがとうございました。
383デフォルトの名無しさん:2009/06/28(日) 23:36:12
>>379
何でポインタの減算の話してんの?
384デフォルトの名無しさん:2009/06/28(日) 23:39:28
>>382
俺も昔間違えてたからさ。 暗黙キャストは出来ないんだよ。 添え字違うとサイズも違うから。
int[10][10] が待ってる所に 他の大きさの配列をキャストしたポインタとか来られても困るでしょ
そういうこと。
385デフォルトの名無しさん:2009/06/28(日) 23:40:28
それはまあいいとしても、なんでキャストしてんの?とは思うね。
386デフォルトの名無しさん:2009/06/28(日) 23:40:50
きゃすとwwwww
型安全にしような
387デフォルトの名無しさん:2009/06/28(日) 23:44:02
似たような話が平行すると誰が誰にレスしてんのかわからんww
388デフォルトの名無しさん:2009/06/28(日) 23:44:45
>>383
おお、よく読んでなかった。すまんすまん^^;;;;;;;

いずれにしてもcastは不要なのじゃ。
ch - '0' で char 型の値が返り、
char は整数型に暗黙に変換できるので
明治キャストは不要なのじゃ^^
すまんこ。

そしてこれはとても速い。atoiとかやってることいっしょ。
(atoiは'-'とか'+'も判定しているみたいだけど)
389デフォルトの名無しさん:2009/06/28(日) 23:45:26
>>384
なんか、その論調だと
void func(int m[10][10])
void func(int (*m)[10])
では、sizeof(m)の結果が違うかのように読めるんだが
390デフォルトの名無しさん:2009/06/28(日) 23:46:49
'0'ってintじゃないっけ?
だったらch - '0'はintに釣られてintになるんじゃないっけ?ちがった?
391377:2009/06/28(日) 23:51:21
C++じゃないけどCの型拡張に関しては
QAC - ANSI C型拡張
ttp://www.toyo.co.jp/ss/qac/technical_whitepaper_sstp0015j.html
にあるね。

それはともかく、とにかくこれで十分速いと言うことね。
サンクス。
392377:2009/06/28(日) 23:53:13
ちなみに
static_castを付けたのは、型がどうとかレスが付く気がしたから
あらかじめその可能性を排除するつもりだった。
その結果逆にstatic_castへのレスが付いてしまったな。
やっぱ付けるべきじゃなかったか。
惑わしてごめんなさい。
393デフォルトの名無しさん:2009/06/28(日) 23:54:18
>>389
違う違う。 m が来るかどうかわからない、って事
m のサイズが違うじゃなくて、そのポインタが果たして [10][10]の配列のアドレス(例の場合 m)が
コピーされた物なのかどうか、ポインタになっちまったらわからないって事。
だから安全の為にそういう記述はコンパイルの段階で防がれるって事
394デフォルトの名無しさん:2009/06/29(月) 01:23:09
[5][10]やら[2][10]なんかは防げないってことを言いたいんじゃねーの?
395デフォルトの名無しさん:2009/06/29(月) 01:33:51
>371
見やすい方にしておけと言っておく。
どうせコンパイラが最適化してしまい結果同じになるから。

396デフォルトの名無しさん:2009/06/29(月) 01:58:10
void func(int m[10][10])
void func(int (*m)[10])
で sizeof(m)が同じだからって何なんだろ
等価じゃないのに
397デフォルトの名無しさん:2009/06/29(月) 02:02:38
お前は何を言ってるんだw
398デフォルトの名無しさん:2009/06/29(月) 02:07:16
夜更かしするから。。。
399デフォルトの名無しさん:2009/06/29(月) 02:23:46
>>396
等価だぞw
400デフォルトの名無しさん:2009/06/29(月) 02:39:30
>396
どちらも同じシグナルの関数
401デフォルトの名無しさん:2009/06/29(月) 02:41:06
シグナル……
402デフォルトの名無しさん:2009/06/29(月) 02:46:52
>>400
おい・・・・寝ぼけすぎw
403デフォルトの名無しさん:2009/06/29(月) 02:47:01
等価じゃないよ。前者にはポインタが渡せない。
404デフォルトの名無しさん:2009/06/29(月) 02:55:24
**pはどっちにも渡せないが、(*p)[10]ならどっちにも渡せる。
405デフォルトの名無しさん:2009/06/29(月) 02:56:49
#include <stdio.h>

void foo( int m[10][10] ) { printf( "foo!\n" ); }
void bar( int (*m)[10] ) { printf( "bar!\n" ); }

int main() {
int n[10][10];
int (*p)[10] = n;

foo( n );
foo( p );
bar( n );
bar( p );
}

わたせるじょ。
406デフォルトの名無しさん:2009/06/29(月) 02:59:56
void foo( int m[static 10][10] )
407デフォルトの名無しさん:2009/06/29(月) 03:06:54
またまたオナニーしちゃって
そんなことやると移植性が
408デフォルトの名無しさん:2009/06/29(月) 17:22:41
VC2003で、
メインスレッドから渡された情報を
メール送信するスレッドを作ったんですが、
メール送信にてメモリリークを起こしていたんですよ。

#define _CRTDBG_MAP_ALLOC
とかを使っても原因がわからなくて先にやれること全てやるべきだと、
warningを出していた、strcat,sprintfをCString型を使って
編集することによってwarningを消したところ、
大幅なメモリリークがなくなりました。

多いときでメインスレッドから
1秒間に数回メール送信のスレッドへ情報が渡される状態でしたが、
(メール送信処理は多少時間がかかるので順番待ちしてます)
strcatやsprintfがメモリリークの原因になることってあるんですか?

ネットで調べてもnewやmallocがメモリリークの原因になるという記述はあっても、
strcatやsprintfがメモリリークの原因になるような記述が見つかりませんでした。
409デフォルトの名無しさん:2009/06/29(月) 17:26:09
どっか破壊してて、それがリークって判定されたんじゃね?
410デフォルトの名無しさん:2009/06/29(月) 17:43:38
おまえには無理
411デフォルトの名無しさん:2009/06/29(月) 22:33:01
http://www.sasaraan.net/program/cpp/cpp_class3.html
このサイトの下のほうにある
クラステンプレートのサンプルをVisual Stuio 2008で動かそうとすると
未解決の外部参照があります…とエラーがでます
なぜなのでしょうか?
412デフォルトの名無しさん:2009/06/29(月) 22:44:48
>>411
とりあえずエラーメッセージを
codepad
ttp://codepad.org/
に貼れ。
個人情報が含まれないように気をつけてね。
413411:2009/06/29(月) 22:55:17
>>412
そのサイトでコンパイルすると大丈夫でした

VisualC++固有の問題かと思って検索して見ますと、下のようなページを見つけました
http://d.hatena.ne.jp/kasei_san/20070517/p1

どうやらテンプレートクラスの定義をcppに分離するとだめなようです
とりえあず全部ヘッダファイルに書くことにします
414411:2009/06/29(月) 22:58:30
というかテンプレートクラスの定義ってヘッダファイルに書くのが常識なようですね…
なにか勘違いしていたようです
415デフォルトの名無しさん:2009/06/29(月) 22:59:24
makefileの改行コードって\nですか?
416デフォルトの名無しさん:2009/06/29(月) 23:02:24
>>414
ああ、そうじゃないと
undefined referenceになるだろうね。
説明は・・・
誰か頼む、俺は寝なきゃならない。
417デフォルトの名無しさん:2009/06/30(火) 02:51:26
テンプレートクラスの扱いはコンパイラによってめちゃくちゃなんだよね。
特殊化するとヘッダファイルにかけなくなったりするし。
418デフォルトの名無しさん:2009/06/30(火) 06:52:29
>>417
そんなことあるの?
explicit instantiation明示的インスタンス生成
ttp://d.hatena.ne.jp/aki-yam/20081129/1227982516
の事じゃなくて?
419デフォルトの名無しさん:2009/06/30(火) 09:36:02
>>415
お使いのmakeプログラムの仕様をご覧ください。
420デフォルトの名無しさん:2009/06/30(火) 14:46:36
#include <stdio.h>

class A
{
public:
static void PrintA();
void PrintB();
};

class B
{
public:
void PrintB();
};

void A::PrintA() {
printf( "A\n" );
}
void A::PrintB() {
printf( "A-B\n" );
}
void B::PrintB() {
printf( "B\n" );
}
421デフォルトの名無しさん:2009/06/30(火) 14:47:20

int main()
{
A a;
B b;

A::PrintA();
a.PrintB();
b.PrintB();

return 0;
}

のように メンバ関数を static にするメリットは何でしょうか?
422デフォルトの名無しさん:2009/06/30(火) 14:54:50
>>421
・インスタンス毎に作られるわけではないので極端な話インスタンスが
一個もなくても呼び出せる

・インスタンスがいくつあっても一個しか無いように見えるのでそれを
利用してSingletonなどのデザパタを実現できる
423デフォルトの名無しさん:2009/06/30(火) 14:56:04
・名前空間の圧迫を避ける
・テンプレートクラスと組み合わせで本領発揮
424デフォルトの名無しさん:2009/06/30(火) 14:56:11
欠点は利点の裏返しで

・non-staticなメンバ関数はインスタンス毎に作られるように
見えるので他のインスタンスには干渉しないがstaticメンバ関数は
すべてのインスタンスから干渉を受ける
425デフォルトの名無しさん:2009/06/30(火) 14:56:42
メンバ関数なら、そのクラスのprivateメンバにアクセスできる
ふつうのグローバルな関数は、クラスのprivateメンバにはアクセスできない
426デフォルトの名無しさん:2009/06/30(火) 15:05:52
Windows visual studio2005 で作ったC++の.exeからソースファイルを見たいんだが・・・・・そういった類のソフトやツールはないかなぁ
427デフォルトの名無しさん:2009/06/30(火) 15:07:40
>>422-425
なるほど、利点を理解しました
428デフォルトの名無しさん:2009/06/30(火) 15:08:52
>>426
Outlook
429デフォルトの名無しさん:2009/06/30(火) 15:33:48
>>428
くっkwsk!
430デフォルトの名無しさん:2009/06/30(火) 16:12:59
>>429
想像してごらん
スパムのこない毎日
431デフォルトの名無しさん:2009/06/30(火) 16:24:55
>>430
!?



ありがとう
432デフォルトの名無しさん:2009/06/30(火) 17:16:33
きもいです
433デフォルトの名無しさん:2009/06/30(火) 17:42:56
きもすいです。
434デフォルトの名無しさん:2009/06/30(火) 19:03:28
想像してごらん
輪切りのピーマンにウィンナーを通してるところを

pi-man = Create( "ピーマン" );
winner = Create( "ウィンナー" );
Wagiri( &pi-man );
pi-man.Insert( winner );
435デフォルトの名無しさん:2009/06/30(火) 19:11:35
なんだよ、パイマンってw
436デフォルトの名無しさん:2009/06/30(火) 19:56:20
C++でC言語は扱えますか?
437デフォルトの名無しさん:2009/06/30(火) 20:03:13
無論じゃ
438デフォルトの名無しさん:2009/06/30(火) 20:03:16
YESでありNOでもある。

>436が使う程度ならYES。
テストで出てきたらNOかもしれない。
439デフォルトの名無しさん:2009/06/30(火) 21:47:39
>>426 C++のexe ってなんだよ。コンパイルしたらマシンネイティブだボケ
ツールもへったくれも、中間言語形式でもない限り、ソースの姿になんか戻せる訳無いだろ
※機械語ニモニック除く
440デフォルトの名無しさん:2009/06/30(火) 21:57:06
C/C++の最適化をOFF(デバッグモード)にしてコンパイルすると
結構な所まで戻るよ

リリースモード(最適化最大)にすると元のソースの姿はまずほとんど
残らないと思っていい
441デフォルトの名無しさん:2009/06/30(火) 22:20:08
vc2003で作成したexeを起動して、ある程度の時間起動していると、下記のエラーが発生して止まってしまいます。
中断をしても混合モードで表示されるのでソース上の位置が特定できません。

test.exe の 0x0746398c で初回の例外が発生しました : 0xC0000005: 場所 0x00000256 を読み込み中にアクセス違反が発生しました。 。
test.exe の 0x0746398c でハンドルされていない例外が発生しました : 0xC0000005: 場所 0x00000256 を読み込み中にアクセス違反が発生しました。 。

場所は 0x00000256,0x0000023a, 0x00000266などと特定されてないんですが、
0x0746398c が固定なんですよね。
メモリのアクセス違反なんでしょうが、0x0746398cを実行している箇所を特定する方法を教えてください。
もしくは、混合モードで表示されない設定方法を書いてあるサイトへ誘導していただけないでしょうか。
442デフォルトの名無しさん:2009/06/30(火) 22:28:52
link時にmapファイルを出力してみれば?
443デフォルトの名無しさん:2009/06/30(火) 22:52:11
動的配列の要素数を、中身を保持したまま増やすにはどうすればよいでしょうか
VBAでいうとReDim Preserveに当ります

444デフォルトの名無しさん:2009/06/30(火) 23:03:48
>>443
(1) 最初から領域をいっぱい確保して、その中におさまるよう期待する
(2) それより増えたら、しょうがないので新しく領域を確保して古いのをコピー
445デフォルトの名無しさん:2009/06/30(火) 23:07:06
vectorなどに任せる
446デフォルトの名無しさん:2009/06/30(火) 23:15:30
「動的配列」、「中身を保持したまま領域を増やす」 みたいな
高級な概念(人間の都合による動作)はC/C++には無いので、用意した領域を使い、それで足りないなら
サイズの大きな新しい領域を用意してそこにコピーして処理を継続する、ってやる他無い。

vectorなどのライブラリを使えば、その辺の実装を隠して実現してくれるので
面倒ならそれらを使うといい。
447デフォルトの名無しさん:2009/06/30(火) 23:15:56
>>444
ありがとうございます!
>>445
すごい!
448デフォルトの名無しさん:2009/06/30(火) 23:30:45
reallocで代用は邪道かな
WindowsならHeapRealloc等で再割り当ても出来るけどやっぱり邪道かな
449デフォルトの名無しさん:2009/07/01(水) 03:48:22
>>441
それは、メモリにロードされたtest.exeのマシン語のまさに実行しようとした番地だろ
デバッガで実行すれば、特定してくれるよ
"場所 0x00000256"辺りは、OSにもよるが、どう考えてもOS管轄の触れるな危険領域

内容的には、初期化していないポインタの間接参照だな
450デフォルトの名無しさん:2009/07/01(水) 08:01:59
>>448
Cならrealloc。
ここらへんは、質問にCかC++か書いてくれないと。
451デフォルトの名無しさん:2009/07/01(水) 08:05:43
アドレスを渡すべき関数に値を渡してるのかなー
452デフォルトの名無しさん:2009/07/01(水) 09:05:28
未初期化のポインタを渡していると見た。
453デフォルトの名無しさん:2009/07/01(水) 09:55:49
while(b) とはどういう意味でしょうか?
ifの場合は if(a!=0)=if(a) なので、while(b!=0)と同じ意味ととらえていいでしょうか?
454デフォルトの名無しさん:2009/07/01(水) 09:59:11
仕様とかよくわからんけどwhile((bool)b)じゃないかな
455デフォルトの名無しさん:2009/07/01(水) 10:16:12
いいえ、b != 0です。
456デフォルトの名無しさん:2009/07/01(水) 11:46:11
>>453
いい。
457デフォルトの名無しさん:2009/07/01(水) 13:07:09
UTF-8環境で、
 何かの型 str = "山a川";
 cout << str[0] << endl; // 山
 cout << str[1] << endl; // a
 cout << str[2] << endl; // 川
となるような方法って無いでしょうか?
458デフォルトの名無しさん:2009/07/01(水) 13:11:01
>>457
Unicodeに変換して
wcout << wstr[0] << endl; //山
wcout << wstr[1] << endl; //a
wcout << wstr[2] << endl; //川
459デフォルトの名無しさん:2009/07/01(水) 13:16:53
>>454
なんで得意げに想像で答えるんだろう…
460デフォルトの名無しさん:2009/07/01(水) 18:03:55
operator[] を用意して ビット列 10xxxxxx を除いてカウントアップすればいい。
461デフォルトの名無しさん:2009/07/01(水) 19:36:01
いまどきSJISべったりはやめようぜ
462461:2009/07/01(水) 19:36:52
ああ、すまん、思いっきり誤読していた
463デフォルトの名無しさん:2009/07/01(水) 22:24:40
out_of_rangeとrange_errorってどう使い分けるんだ?
464デフォルトの名無しさん:2009/07/02(木) 01:05:33
プログラミングのスタイルについて質問させていただきます

まず、以下の二つのAとBのコードをごらんください。

■ パターンA
int hoge(int data) {
  if (data == 0) {
    return 0;
  }

  data = data + 1;
  return data;
}

■ パターンB
int hoge(int data) {
  int ret;
  if (data == 0) {
    ret = 0;
  } else {
    ret = data + 1;
  }
  return ret;
}
465>>464:2009/07/02(木) 01:06:43
(続き)

私の会社のコードレビューで意見が衝突しているのですが、
パターンAの場合、コードが見やすくて良い意見と、
returnが何回も書いてあるのは見づらいという意見があります。

パターンBの場合、最後だけreturnがあるのでコードが追いやすいと意見はあります。

一般的にはどちらが良いのでしょうか?
理由も合わせてご教示お願いします。
466デフォルトの名無しさん:2009/07/02(木) 01:09:55
>>464
昔、10年前に目立ちにいたものだが、パターンAでプログラミングしたものを上司にだしたら、
わかりにくいからパターンBで修正しろと怒られた。
でも、最近の若い人は圧倒的にパターンAで書く人が多いね。
俺は、パターンBで書くことが多い。
467デフォルトの名無しさん:2009/07/02(木) 01:46:43
>>465
宗教の問題。 関数の途中にreturnを入れないという宗派が存在することは確か。
個人的には、そのコードぐらいreturnするしないの条件が単純ならやってもいいと思う。

論点になるのは、処理の追いやすさとか、
関数途中でエラーが出たときのリソース解放のしやすさとか。
誰かに強制されている状況でない限り、自分の好きにすればいいと思うよ。
468デフォルトの名無しさん:2009/07/02(木) 02:06:55
俺なら

int hoge(int data) {
if(data) data++;
return data; }

int hoge(int data) { return data ? data + 1 : 0; }

のどっちかだな。
469デフォルトの名無しさん:2009/07/02(木) 02:09:13
戻り値が必要な関数には少なくともひとつのreturn文が必要なわけだけど
古いC++コンパイラには、if文の中のreturn文を調べないスカポンタンな代物があったんですよ。
それで、できる限りreturn文は関数の末尾にまとめようよみたいな習慣があったです。

しかし、いまどきそんなあふぉーなコンパイラはありませんので、
今はパターンAを使います。

理由は簡単。464のコードは単純だからいいですが、
もし仮に関数hogeの引数が10億ペタバイトを必要とする巨大オブジェクトをコピーするようなものであったとき、
あるいは、関数hogeが1日に1000兆回も呼び出されたりするようなとても重要な関数だった場合、
パターンBはオブジェクトが1つ多い分だけ、コストが膨大になるからです。
何かの拍子にこの関数が参照渡しに書き換えられたときのコストも考えてみましょう。

っていうか、そんな細かい話でぶつかってるクソプロジェクトは
間違いなく火の海です。
470デフォルトの名無しさん:2009/07/02(木) 02:36:25
関数の内容によって2つのパターン併用するのが自然なのでは。
どちらかに決めるともう一方のパターンで書けば
もっとシンプルにできるケースまで強制されるハメになる。
471デフォルトの名無しさん:2009/07/02(木) 03:34:36
まぁ、普通に可読性なら>>468でFA。
472デフォルトの名無しさん:2009/07/02(木) 03:39:20
前者はアルゴリズムの枝狩りの感覚に似てるよね。
この場合はとっとと終わるっていうのが明確でいい。
インデントも深くならないし。

後者のメリットは関数を抜ける場所が一つになることで、free忘れが
減ったりするんだろうけど、実際そのスタイルにすることで、そういう
恩恵を得られたという実感はないね。
戻り値用の変数をずーっと持っておかないといけないのもイマイチ。

というのが、個人的な意見です。
473デフォルトの名無しさん:2009/07/02(木) 03:40:24
>>468
コーディングスタイルのハナシっすから。
474デフォルトの名無しさん:2009/07/02(木) 03:48:15
C++ Coding Standardsにはずばり、
関数にはひとつの入り口とひとつの出口という発想は
デストラクタや例外といった機構を持つ言語では
時代遅れとしかいいようがないと書かれている。
475デフォルトの名無しさん:2009/07/02(木) 04:56:33
例外機能でまかなえるからこそ有効値内の処理はフローを整えるべき
476デフォルトの名無しさん:2009/07/02(木) 07:23:48
基本的な質問で恐縮なのですが・・・
C++で、staticなメンバを含まないクラスを記述する時、そのクラスのコードは
ヘッダファイルに記述するべきなのか、ソースファイルに記述するべきなのか、どちらなんでしょうか。

class A {
 public: int get();
477476:2009/07/02(木) 07:25:35
途中で書き込んでしまいました、すみません。

// *.h
class A {
 public: int get();
};

// *.cpp
Aint A::get() { return 1; }

か、

// *.h のみ
class A {
 public: int get() { return 1; }
};

478477:2009/07/02(木) 07:26:43
Aint はtypo。 度々すみません
479デフォルトの名無しさん:2009/07/02(木) 07:30:58
>>464
その例のようにフラグ変数を追加してまで固執するのは
賛否あるけど、一般的にはBの方がいい
出口を複数作るのはよくない。
480デフォルトの名無しさん:2009/07/02(木) 08:12:16
効率ならA
老害対策にはB
可読性は個人の感覚しだいで甲乙つかず
といったところか
481デフォルトの名無しさん:2009/07/02(木) 08:25:16
>>464-465
パターンBは、初心者に教えるときに向いている。
ifとelseが対等だから、それぞれの場合を考えやすい。

パターンAは、ifでやろうとしていることが例外的なことならスマート。
無駄な一時変数も要らない。
しかし、こうなるとちょっとキモイ。

■ パターンA’
int hoge(int data)
{
  if (data != 0) {
    return data + 1;
  }
  return 0
}

それに対して、こっちはいたって自然。

■ パターンB’
int hoge(int data) {
  int ret;
  if (data != 0) {
    ret = data + 1;
  } else {
    ret = 0;
  }
  return ret;
} 
482デフォルトの名無しさん:2009/07/02(木) 09:07:42
■ パターンC
int hoge(int data) {
  if (data == 0) {
    return 0;
  } else {
    return data + 1;
  }
}

483デフォルトの名無しさん:2009/07/02(木) 09:14:11
僕は、
int hoge(int data) {return data + !!data;}
484デフォルトの名無しさん:2009/07/02(木) 11:19:59
>>476 の質問はこのまま埋もれて消えるんでしょうか・・
485デフォルトの名無しさん:2009/07/02(木) 11:27:07
>>476
インライン展開を望むならヘッダ中。
そうでなけりゃ、基本ソース中。
486デフォルトの名無しさん:2009/07/02(木) 11:37:50
>>485
ありがとうございます、すみません。
その場合、何か動作上の違いというのはあるんでしょうか
487デフォルトの名無しさん:2009/07/02(木) 12:00:01
淫乱展開すると関数呼び出しのオーバーヘッドがないから超高速。
一方で、関数としてまとめられることがないのでコードの増大を招く。

そしてもうひとつの問題が。
inline キーワードを使おうと、クラス定義に直接コードを書こうと、
本当に淫乱展開するかはコンパイラしだい。
488デフォルトの名無しさん:2009/07/02(木) 12:07:56
>>487
なるほど・・・ つまり、

// どちらも *.h で定義
class A { public: int get() { return 1; } };
// ソース側で定義。Aと同内容
class B { public: int get(); };

とした場合、Bのインスタンスに対して
B b;
b.get(); ← このタイミングで暗黙の内に関数名と実際のアドレスの解決が行われて、ジャンプしてそこで処理される

って事なんですね。オーバヘッドと仰ったのはそのジャンプ(関数呼び出し)の部分
具体的に機械語レベルでどう落とされるかは、コンパイラの実装次第
489デフォルトの名無しさん:2009/07/02(木) 15:16:21
>>487
> 淫乱展開

  (  ) ジブンヲ・・・・・・
  (  )
  | |


 ヽ('A`)ノ トキハナテ!
  (  )
  ノω|


 __[警]
  (  ) ('A`)
  (  )Vノ )
   | |  | |
490デフォルトの名無しさん:2009/07/02(木) 16:35:08
■パターン4

int hoge(int data)
{
return (data != 0)? data + 1: data; /* あえて ++data と書かない */
}
491デフォルトの名無しさん:2009/07/02(木) 17:01:46
子供が多いな
まだ夏休みには早いだろ?
宿題でもやってろよ
492デフォルトの名無しさん:2009/07/02(木) 17:03:15
>>481
初心者に教えやすい、というのは納得
493デフォルトの名無しさん:2009/07/02(木) 18:05:02
質問させてください。C言語です。
ボックスミュラー変換で正規分布のdouble型の乱数Aを作成するプログラムを作ったんですが、
それを(正規分布の特性を失わずに)整数値としてあつかいたい場合(何かの得点として扱いたい場合)は、
int型でキャストすべきなのか小数点以下を四捨五入するべきなのか教えてください。
r1=rand()/RAND_MAX
r2=rand()/RAND_MAX
A=sigma*sqrt(-2*log(r1))*cos(2*PI*r2)+m;
sigmaは標準偏差でmは平均です。
494デフォルトの名無しさん:2009/07/02(木) 18:22:35
>>493
これ、C言語の質問じゃなくてアルゴリズム(と言うか、考え方)の質問じゃね?
話こんがらがったか

言語の質問って範疇で言うと、元々doubleで持ってる値をintに丸めたら、
どうしたって精度的は下がる訳だから決め打ちでいいと思う。

考え方の質問って事ならスレチかもしれないが、偏りに応じてオフセット付けて、n捨m入にして
丸めればいいと思う。
495デフォルトの名無しさん:2009/07/02(木) 19:23:19
以下のように使用しているifstreamに
#をコメントアウトとしてスキップ機能を追加したtmpifstreamクラスを作って
  ifstream file_input;
  int n;
  file_input >> n;
tmpifstream file_input; のように(コードの大きな修正なく)代替したいのですが、
下のクラスのoperator >> ()のところのメンバ関数をどのように書けば良いか
教えていただけないでしょうか?すみません。よろしくお願いします。

class tmpifstream{
public:
  newfstream(){}
  ~newfstream(){}
  operator >> (){ /* ← ここです */
    file_input >> buffer;
    /* bufferの先頭に#を含むかの判定 */
    /* その後の処理も分かりません。。 */
}
  void open(){/* file_inputを開く */}
  void close(){/* file_inputを閉じる */}
private:
  std::ifstream file_input;
  std::string buffer;
}
496デフォルトの名無しさん:2009/07/02(木) 19:23:38
>>481
パターンBは理解しやすいかもしれないが
初心者に教えたらデカいクラスでも同じことやりそうで怖い
497デフォルトの名無しさん:2009/07/02(木) 19:35:56
どゆこと?
演算子のオーバーロードをどう記述していいかわからないってこと?
498デフォルトの名無しさん:2009/07/02(木) 19:38:52
>>495
ifstreamではなくstreambufをカスタマイズするべきだと思う
499デフォルトの名無しさん:2009/07/02(木) 20:41:39
GPLライセンスとはなんでしょうか?
GPLに関する記事を他のサイトで見たのですが、その事もよく理解できません。
GPLと、GPLライセンスについて教えてください。
500デフォルトの名無しさん:2009/07/02(木) 20:46:13
>>499
GNU General Public License - Wikipedia
ttp://ja.wikipedia.org/wiki/GNU_General_Public_License
501495:2009/07/02(木) 20:52:59
>>497
そうです。
どう書いたら、目的が果たせるのかちょっと分からなかったので。

>>498
ありがとうございます。できましたら、簡単なサンプルをお願いできないでしょうか・・
502デフォルトの名無しさん:2009/07/02(木) 22:01:45
>501
この辺から辿っていけば?
ttp://www.radiumsoftware.com/0306.html#030609
503デフォルトの名無しさん:2009/07/02(木) 23:36:23
>>494
ありがとうございます。
504デフォルトの名無しさん:2009/07/03(金) 13:22:13
>>502
ありがとうございます。
しかし、かなり難しい話になるんですね。
505デフォルトの名無しさん:2009/07/03(金) 22:47:06
class Base{
public:
void hoge(int i);
};

class Sub : public Base{
public:
void hoge(double d);
};

のようにBaseのメソッドをオーバーロードした場合、SubのインスタンスからBaseのhogeって呼べないんですか?
コンパイルエラー出るみたいで。
後、解決方法は

class Sub : public Base{
public:
void hoge(double d);
void hoge(int i){
Base::hoge(i);
}
};

以外に何かありますか?
506デフォルトの名無しさん:2009/07/03(金) 22:56:38
CHoge::CHoge(){m_pCFuga = new CFuga;}
try{CHoge *p = new CHoge [n];}catch(...){/*〜〜*/;}
とすると

@sizeof(CHoge)*xのrawMemoryを確保
A0〜n-1番目の要素にデフォルトコンストラクタを呼ぶ
Bpにアドレスを代入

という流れになると思うんですけど@あるいはAの段階でbad_allocが投げられた場合
それぞれどういった挙動を示すんでしょうか?
@でbad_allocが出た場合は巻き戻されてメモリ確保がなかったことに
Aでbad_allocが出た場合は呼ばれた分だけデストラクタ→rawMemoryも解放
と、ここまで自動でやってくれるんでしょうか?
507デフォルトの名無しさん:2009/07/03(金) 23:19:01
>>505
呼べないよ。解決方法はそれか、using使うぐらいかな。

class Sub : public Base{
public:
void hoge(double d);
using Base::hoge;
};
508デフォルトの名無しさん:2009/07/03(金) 23:27:59
>>505
Sub s;
int x;
s.Base::hoge( x );

のような呼び出し方はできる。
でも、s.hoge(x)で呼びたいなら、
あなたの示した解決法しかない。

基底クラスと派生クラスで同名の関数があるとき
(それらの戻り値や引数がことなり、本来別の関数として認識されるものであっても)
派生クラスのオブジェクトでは
基底クラスの関数は派生クラスの同名関数によって「すべて」隠蔽される。
関数がvirtualであるかどうかも問題にならない。
509デフォルトの名無しさん:2009/07/03(金) 23:36:32
510505:2009/07/03(金) 23:58:02
>>507, 508, 509
同一クラス内でのオーバーロードは予想した通り(変数の型で呼び出すメンバを変更する)に動いたので、継承でも同じように動作すると期待していたのですが・・・
継承ではそういう動作をしないのですね。分かりました。
解決方法は、usingの使用がスマートな感じがするので、これでいきたいと思います。

返答ありがとうございました。
511デフォルトの名無しさん:2009/07/04(土) 00:55:45
Baseいじれて多少ダルイ事になってもいいならダミーのデフォルト引数付けるようにすればいいんじゃないかな
512デフォルトの名無しさん:2009/07/04(土) 01:38:55
class Base{
protected:
int A;
Base(){
//Aを使った動作
}
}

Class Sub : public Base{
public:
Sub(){
A = 10;
}
}

こんな感じで、派生したオブジェクト作成と同時に、Aに派生先固有の値をいれ、使おうとしたら
Baseのコンストラクタ → Subのコンストラクタ
の順で呼び出されてしまい、Aの値が不定になり意図した動作ができませんでした。

Baseの動作をSubにそのまま組み込むことも一応できるのですが、それだとわりと長くなってしまうため…
何かスマートな解決法はないでしょうか
513デフォルトの名無しさん:2009/07/04(土) 01:48:40
class Base{
protected:
int A;
Base(){}
Func(){
//Aを使った動作
}
}

Class Sub : public Base{
public:
Sub(){
A = 10;
Func()
}
}

じゃだめなの?
514デフォルトの名無しさん:2009/07/04(土) 01:52:47
もちろんそれで動くし、それで進めることも可能なのですが
かなり派生する数が膨大で、1個1個のコンストラクタに記述するのも大変なので…。
ほかにいい方法がないかな、と思い相談させていただきました。
515デフォルトの名無しさん:2009/07/04(土) 01:57:26
>>512を読んで>>514がくることを想像できる人はいるのかね。
516デフォルトの名無しさん:2009/07/04(土) 02:02:03
すみません、たしかに質問の内容が足りていませんでした…。
517デフォルトの名無しさん:2009/07/04(土) 02:02:25
513は自演だと思う。
幼稚園スレといえどもイキナリ二匹も現れんでしょ
518デフォルトの名無しさん:2009/07/04(土) 02:02:38
Aをstaticにして、Aの定義をSub側で行うのはどう?
519518:2009/07/04(土) 02:04:00
わ、わすれてくださいorz
520デフォルトの名無しさん:2009/07/04(土) 02:16:05
>>512
こんなのは?

class B {
protected:
int A;
B(int n) : A(n) { /* Aを使った動作 */ }
};

class D : public B {
public:
D(): B(10) {}
};

と思ったけど、なんか難しく考えすぎた。>>513でいいじゃん。
521513:2009/07/04(土) 02:17:05
class Base{
protected:
int A;
Base(){}
Func(int a){
A = a;
//Aを使った動作
}
}

Class Sub : public Base{
public:
Sub(){
Func(10);
}
}

あんまり詳しくなくてこんなんしか思いつかないや。ごめん。

>>517
自演?
522512:2009/07/04(土) 02:40:46
うーん、やっぱり、Baseコンストラクタ内での処理はあきらめたほうがいいのでしょうか。
複数回呼び出すとまずい処理だったので、できればコンストラクタ内で収めたかったのですが…

とりあえず、Baseコンストラクタ内の処理を移して改めて呼び出す方向でいってみたいと思います。
ありがとうございました。
523デフォルトの名無しさん:2009/07/04(土) 03:11:19
>>522
なるほど、それだと初期化関数Func()を派生クラスから呼べるようにはしたくないな
だったら>>520みたいのは?
524デフォルトの名無しさん:2009/07/04(土) 03:16:07
>>520みたいなことできるの初めて知った
結構びっくりしてる
525512:2009/07/04(土) 03:24:01
>>520
知らない記述方法だったので、最初見たとき理解できてませんでしたが
改めて見直すと… ちょっと、いろいろと試してみます。

ええと、この場合、10の値を外部からもってくるとか、計算で求めることもできるんでしょうか?
526512:2009/07/04(土) 03:47:26
なるほど… 自己解決しました。

D(): B(10) {}

の部分を

D(int nan): B(nan) {}

とかに変えると、引数を持ってきたりも可能ですし、B(nan)の中で計算も可能みたいですね。
これで解決しそうです。 本当にありがとうございました。 
527デフォルトの名無しさん:2009/07/04(土) 04:11:04
毎レス情報を増やすというのを最後まで一貫してやり遂げたのはすごいな
528デフォルトの名無しさん:2009/07/04(土) 04:13:21
nanはナンバーのつもりならnumにしたほうがいい
nanは誤解される
529デフォルトの名無しさん:2009/07/04(土) 04:14:19
全然関係無いけど、変数名 nan だと、NotANumberに見えてしまう罠

さて、明日の昼はナンでも食べるか
530デフォルトの名無しさん:2009/07/04(土) 04:18:55
ナ、ナンダtt
531512:2009/07/04(土) 04:45:35
>>527
読み返してみると、確かに酷い質問の仕方でした…
次から注意します。

>>528-529
最近、学生時代英語サボっていたことをものすごく後悔しています…
532デフォルトの名無しさん:2009/07/04(土) 07:09:27
それにしてもnanはないだろww
533デフォルトの名無しさん:2009/07/04(土) 11:08:19
class Base {
int A;
Base( int a ) : A(a) { /* Aを使った処理 */ }
};

class Derived : public Base {
static int a = 10;
Derived() : Base( a ) { }
};

まぁ、質問の意図がよくわからんから、いいや。
534デフォルトの名無しさん:2009/07/04(土) 12:07:13
UTF8で書かれたテキストファイルをstringに読み込むにはどうすればいいんでしょうか?
535デフォルトの名無しさん:2009/07/04(土) 15:00:37
a->b これってどういう意味でしょうか?
536デフォルトの名無しさん:2009/07/04(土) 15:01:30
aの先のb
537デフォルトの名無しさん:2009/07/04(土) 16:06:07
Hoge h;

std::cout << h << std::endl;

こうやってhの情報(例えばメンバ変数など)を表示させたいのですが
どうやればいいのでしょうか?
<<演算子を定義するのでしょうか??
キーワードだけでもお願いします。
538デフォルトの名無しさん:2009/07/04(土) 16:08:47
operator<<(fstream&, const Hoge&)
539デフォルトの名無しさん:2009/07/04(土) 16:10:05
ostream& operator << ( ostream& os, const Hoge& h ) {
os << h.member_;
return os;
}
540537:2009/07/04(土) 16:11:22
ありがとうございます
これを手がかりに色々調べてみます
541デフォルトの名無しさん:2009/07/04(土) 18:07:29
#include <iostream>

using namespace std;

class test {
public:
  test(int x) try : p(new int [x]) {cout << "test" << endl;} catch(bad_alloc& e) {cout << "err test: " << e.what() << endl;}
  ~test() {delete [] p; cout << "~test" << endl;}

private:
  int *p;
};

int main(void) {
  try {
    test t(-10);
  }
  catch(bad_alloc& e) {
    cout << "err main: " << e.what() << endl;
  }

  return 0;
}

出力結果
err test: bad allocation
err main: bad allocation

test()でbad_alloc例外をもみ消したはずなのに、main()で例外を補足してしまうのはなぜでしょうか?
542デフォルトの名無しさん:2009/07/04(土) 18:44:09
コンストラクタだから。
543デフォルトの名無しさん:2009/07/04(土) 20:15:52
shared_ptrに配列わたしたいときって

void satsugai(CFoo* aFoo) {delete [] aFoo;};
shared_ptr<CFoo> saFoo(new CHoge [num], satsugai);

ってやるのが一番スタンダードなの?
544デフォルトの名無しさん:2009/07/04(土) 20:21:07
>>541
コンパイル通らねえぞ
545デフォルトの名無しさん:2009/07/04(土) 20:31:50
>>544
インデントが全角になってるからそのままじゃコピペじゃできない
    test
546デフォルトの名無しさん:2009/07/04(土) 20:35:23
全角インデントにも気づかないコピペ厨
547デフォルトの名無しさん:2009/07/04(土) 20:56:17
まあ気づかないヤツもダメだけど、全角インデント使うヤツもアホだろ。
548デフォルトの名無しさん:2009/07/04(土) 20:57:46
>>545>>546
お前ら低脳か
全角がちゃんと□と表示されるエディタ使ってるわい

コンストラクタの所で

エラー E2040 constructor1.cpp 7: 宣言が正しく終了していない

というエラーが出るんだよ

コンパイラはCodeGear C++ 6.1.3(最新版)
549デフォルトの名無しさん:2009/07/04(土) 21:22:01
>>535
アロー演算子。

MyClass hoge;
hoge.foo();
に対して、
MyClass *p=new MyClass();
p->foo();
の様に使う。
550デフォルトの名無しさん:2009/07/04(土) 21:23:58
>>541
function try blockといって、throw;しなくても例外が再送出されることになってる。
ことコンストラクタに関しては例外をもみ消したところで
無効なオブジェクトがのこるだけだから意味がない
551デフォルトの名無しさん:2009/07/04(土) 22:22:02
>>535
(*a).bと同じ
552デフォルトの名無しさん:2009/07/05(日) 05:11:06
C++のSTLのpriority_queueで構造体を扱いたいのですが、

typedef struct{
char name;
int age;
bool sex;
}human;

priority_queue<human> pq;

とした場合構造体のageで並べ替えたい場合はどのようにすれば良いのでしょうか?
553デフォルトの名無しさん:2009/07/05(日) 07:47:42
human同士を直接比較できるようにすればいい
operator<()を定義するのが簡単じゃないかな

bool operator<(human& a, human& b) {
return b.age < a.age;
}
554デフォルトの名無しさん:2009/07/05(日) 09:45:41
>>550
わかりやすいです
thxでした
555デフォルトの名無しさん:2009/07/05(日) 11:56:49
>>553
constが必要だろ

bool operator<(const human& a, const human& b) {
return b.age < a.age;
}
556デフォルトの名無しさん:2009/07/05(日) 13:20:55
template classの実装を隠蔽する(ヘッダとソースに分離する)方法はないの?
特殊化したclassなら隠蔽できることまではわかったんだけど・・・なんかいいテクは無いものかな
557デフォルトの名無しさん:2009/07/05(日) 15:10:37
そしてお前はexportを調べてガッカリする
558552:2009/07/05(日) 16:35:53
>>553
>>555
const付けたらうまくいきました!
ありがとうございました。
559デフォルトの名無しさん:2009/07/05(日) 17:18:02
>557
最新のVSでもダメらしいね…
560デフォルトの名無しさん:2009/07/05(日) 17:57:59
何でexportって実装されないの?
561デフォルトの名無しさん:2009/07/05(日) 18:01:14
面倒だから
562デフォルトの名無しさん:2009/07/05(日) 22:54:17
演算子の日本語っぽい読み方ですが、
+は加算、ーは減算
++は、まぁインクリメントで妥協するとして
+=はなんと表現すればよいでしょうか?
563デフォルトの名無しさん:2009/07/05(日) 23:06:02
加算代入 たすわー
564デフォルトの名無しさん:2009/07/05(日) 23:08:16
++プラプラ
たすイコール
565デフォルトの名無しさん:2009/07/05(日) 23:12:26
アッド
566デフォルトの名無しさん:2009/07/06(月) 00:01:08
+プラス
++プラプラ
+=プラスイコール
567デフォルトの名無しさん:2009/07/06(月) 00:02:10
日本語っぽい読み方

って書いているのに英語っぽい読み方している人たちは
帰化人ですか?
568デフォルトの名無しさん:2009/07/06(月) 00:04:53
和製英語だと言いたいのでしょう
569デフォルトの名無しさん:2009/07/06(月) 00:07:39
どうみても日本語だな
570デフォルトの名無しさん:2009/07/06(月) 00:14:36
いえ、奇械人です。
571デフォルトの名無しさん:2009/07/06(月) 00:17:48
+たす
++たすたす、いんくり、まえいんくり、あといんくり
+=たすわ、たすいこーる
572デフォルトの名無しさん:2009/07/06(月) 00:19:42
+ぷらす
++ぷらぷら
+=ぷらすいこおる
573デフォルトの名無しさん:2009/07/06(月) 01:03:31
加算代入が良さげですね、例え造語でも。
いあ、しょーもない話、operatorのオーバーロードのコメント書いてて
なんてかきゃいいのか詰まったもんで

ほんとどーでもいいはなしで、さーせん
574デフォルトの名無しさん:2009/07/06(月) 01:11:48
造語じゃなくて文で書けよ
575デフォルトの名無しさん:2009/07/06(月) 01:33:51
なぜ調べないのだろうか。
http://msdn.microsoft.com/ja-jp/library/f6z5yhhs(VS.80).aspx
576デフォルトの名無しさん:2009/07/06(月) 01:44:57
俺の場合
/**
* オペレータを足し入れる
*/
577576:2009/07/06(月) 01:46:31
オペレータじゃなくてオペランド
素だった・・・ もう寝る
578デフォルトの名無しさん:2009/07/06(月) 01:58:33
/**
* 加算演算子のオーバーロード
*/

俺はこのコメントを見て、そしてそっと削除した
579デフォルトの名無しさん:2009/07/06(月) 02:05:55
/**
* 経理のあの子に入れて出したい
*/
580デフォルトの名無しさん:2009/07/06(月) 22:26:59
string str[10]={"aaa","bbb"・・・・};
にように配列を決めて、
cinで入力した文字列とif文で等号を調べます
if(ch==str[0])
{}
else if(ch==str[1])
{}
のようにして、最後に
elseとして合致しない場合のパターンもつけたいのですがうまくいきません。
なぜでしょうか?
581デフォルトの名無しさん:2009/07/06(月) 22:29:49
どううまくいかないのかかいてください
582デフォルトの名無しさん:2009/07/06(月) 22:32:42
>>580
「うまくいかない」では分かりません。
どう「うまくいかない」のか、
これを明確に書いてください

もうテンプレニイレヨウぜ、こういうやからが多すぎる。
583デフォルトの名無しさん:2009/07/06(月) 22:43:17
相手しない、という選択肢はダメですか?
584580:2009/07/06(月) 22:47:42
すいません。
どんな文字列を突っ込んでもelseifの方になってしまい、elseになってくれません
585デフォルトの名無しさん:2009/07/06(月) 23:03:44
何を言ってるのかわからん。「elseになってくれません」のelseって、このコードのどこだ?
あとchの型は?

何をどうしたら、こんなに説明下手になるんだ・・・電話の向こうの人にジェスチャーで物事を伝えるレベル。
586デフォルトの名無しさん:2009/07/06(月) 23:40:29
>>580
chが本当に文字列ならstrcmpを使って比較
587デフォルトの名無しさん:2009/07/07(火) 00:11:51
>>584
本当にあらゆる文字列を試した?
どれか一つくらい else の方にいくはずだよ
588デフォルトの名無しさん:2009/07/07(火) 01:02:41
chがstring型だとして、どんな文字列を入れても(ch==str[1])が真になっているということか。

可能性1
 ch = str[1];
 if(ch==str[0])
 {}
 ...
可能性2
 if(ch==str[0])
 {}
 else if(ch=str[1])
 ...
どっちかだとおもうんだけど。
589デフォルトの名無しさん:2009/07/07(火) 09:11:45
constしたクラスを使うには、一度別にキャストしないと駄目かな?
const指定したクラスのメソッドを使うと、thisポインタがなんちゃらってエラーが発生する
590デフォルトの名無しさん:2009/07/07(火) 09:17:38
なんちゃらすれば解決
591デフォルトの名無しさん:2009/07/07(火) 09:18:19
そのなんちゃらがconst this&に変換出来ないって内容だった気がする
592デフォルトの名無しさん:2009/07/07(火) 09:18:46
>>589
説明が下手なんだから、実例を挙げなさいよ。

>>580
あんたもコンパイルできて再現する最小のコードを挙げなさいな。
593デフォルトの名無しさん:2009/07/07(火) 09:18:59
きさま、Java厨だな!
594デフォルトの名無しさん:2009/07/07(火) 09:26:31
const CHoge *getHoge( ) { return &g_cHoge; }

const CHoge *pHoge = getHoge( );
pHoge->hogehoge( ); // ここでビルドエラー
595デフォルトの名無しさん:2009/07/07(火) 09:29:55
>>594
どうせhogehoge()がconstメンバになっていないんだろ。
596デフォルトの名無しさん:2009/07/07(火) 10:12:18
constぐらいググれ。
つーかいかなる本にでも書いてあるだろ。
597デフォルトの名無しさん:2009/07/07(火) 10:25:42
int **p;
const int **q = p;

がエラーになるのはなぜ?
598デフォルトの名無しさん:2009/07/07(火) 10:47:12
>>597
型が違うから。
前者はintへのポインタのポインタで、後者はconst intへのポインタのポインタ。
int * pp;
const int * qq = pp;
なら通るけど、const intへのポインタにintへのポインタを代入する際にはconstをひとつ被せるだけの暗黙の型変換が行なわれている。
従って、
int ** p;
const int ** q;
q[0] = p[0];
ならコンパイルは通る。
# が、勿論正しくない。
599デフォルトの名無しさん:2009/07/07(火) 10:54:26
>>594
const CHoge *getHoge( ) const { return &g_cHoge; }
600デフォルトの名無しさん:2009/07/07(火) 11:07:07
>>598
constを付加する暗黙の変換は
間接参照レベルが2以上になると効かないってことでいいのでしょうか。
一応、それを実証するべく

int a;
const int *p = &a;
const int **q = &p;

ってやったら、なるほど、エラー出ませんでした。
601デフォルトの名無しさん:2009/07/07(火) 11:47:05
>>598
>594の質問とは直接関係ないね。
602デフォルトの名無しさん:2009/07/07(火) 12:59:04
const int * const *q ってやれば一度で行くんじゃないか?

要するに暗黙変換は一度に一個しかconstを付けないよ、って事だろうな
規格票のどっかに書いてあると思うけど
603デフォルトの名無しさん:2009/07/07(火) 14:24:11
>>597
const int を int const に置き換えて (両者は同じ)、
T *p → T const *q って考えるといいよ

良い例
int *p → int const *q (T=int)
int **p → int *const *q (T=int*)
int const **p → int const *const *q (T=int const*)

ダメな例
int **p (T = int*) → int const **q (T = ?)
int **p (T = int*) → int const *const *q (T = int const*)
604デフォルトの名無しさん:2009/07/07(火) 14:32:07
>>599
getHogeじゃなくてhogehogeをそうしないと。
605デフォルトの名無しさん:2009/07/07(火) 15:31:39
3ケタの数字をランダムに被りなしで表示したいのですが、よくわかりません。よろしくお願いします。
606デフォルトの名無しさん:2009/07/07(火) 15:36:59
3桁の数字を全部生成してシャッフルしろ
607デフォルトの名無しさん:2009/07/07(火) 18:46:16
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

enum {
N = 1000
};

int main(void) {
int a[N], i;

for(i = 0; i < N; ++i)
a[i] = i;

srand((unsigned)time(NULL));

for(i = 0; i < N-1; ++i) {
int t = a[i], r = rand()%(N-i)+i;
a[i] = a[r];
a[r] = t;
}

for(i = 0; i < N; ++i)
printf("%3d%c", a[i], (i+1)%5?' ':'\n');

return 0;
}
608デフォルトの名無しさん:2009/07/07(火) 18:52:16
gccでOSのマクロ定義が書かれているヘッダファイルって
どこにありますか?
609デフォルトの名無しさん:2009/07/07(火) 19:09:42
定義済みマクロだろ
610デフォルトの名無しさん:2009/07/07(火) 19:16:27
>>608
find / -name '*.h'|xargs grep __YourOS__ | grep -w define
デモ実際は>609だと思われ。
611デフォルトの名無しさん:2009/07/07(火) 19:28:11
昔は gcc -dumpspecs で見られた気がするけど、いまは無いみたいだね。
612デフォルトの名無しさん:2009/07/07(火) 19:31:17
"_hoge", referenced from:
_hoge$non_lazy_ptr in hogehoge.o
symbol(s) not found
collect2: ld returned 1 exit status

ってリンクエラーはどうすりゃ解決できるのだろうか
613デフォルトの名無しさん:2009/07/07(火) 20:14:30
hoge の実態があるオブジェクトをリンクする
614デフォルトの名無しさん:2009/07/08(水) 05:35:35
動画再生ソフトでがバーをドラッグするとその時間から再生できるのがほとんどですが
再生が始まるポイントが絶対決まってると思うのですが、つまり4秒くらいのところにドラッグしても絶対2秒から始まるような
これは何故でしょうか?
615デフォルトの名無しさん:2009/07/08(水) 08:28:24
板違いです
616デフォルトの名無しさん:2009/07/08(水) 08:32:23
じゃあどこで聞けばいいのよ?
617デフォルトの名無しさん:2009/07/08(水) 08:55:25
>>616 板もそうだが、少なくともスレタイとは思いっきり無関係。

あえて強引に答えるとするなら、再生可能位置のアドレステーブルとかを持ってるような構造で作られてて、
バーを100%とした中でのxの位置からアドレステーブルの該当箇所をとりだして、そこを ** で拾って表示してるとかじゃないかな

他人が作ったなんらかのソースも無いアプリケーションの挙動について、全部想像で返答
618デフォルトの名無しさん:2009/07/08(水) 09:05:29
時間方向の情報を基に圧縮をかけると途中から再生が出来なくなるけど、
時間方向の情報を基に圧縮されていないデータが挟まれていればそこから
再生できるようになるのでは?
619デフォルトの名無しさん:2009/07/08(水) 09:37:09
>>614
ぜんっっっぜん
スレ違い。
さよーなら、おまぬけさん。
620デフォルトの名無しさん:2009/07/08(水) 09:48:47
サイコロ振って決めたとか、そのレベルの適当な理由がないと、
このスレで質問しようと思った経緯が理解しがたいよな。
621デフォルトの名無しさん:2009/07/08(水) 09:53:32
プログラム暦1年くらいで動画再生の方法とかはまだ知らないレベルで
DirectXサウンドの存在は知ってるレベルだからまあC言語スレかなと思いますた
622デフォルトの名無しさん:2009/07/08(水) 09:54:26
>>621
uskk
623デフォルトの名無しさん:2009/07/08(水) 10:26:49
>>614
キーフレームの途中からなら、すぐに再生できないのが当たり前。
これ以上は…どこだろ。DTV板かなあ。
624デフォルトの名無しさん:2009/07/08(水) 10:55:28
キーフレームって数秒おきじゃなくてもっと細かいのかとおもってた。
625デフォルトの名無しさん:2009/07/08(水) 11:15:03
圧縮時に決められるコーデックが多い。
基本はフレーム単位で指定するけど
1時間単位みたいなことにできるものもある。
626デフォルトの名無しさん:2009/07/08(水) 11:28:38
スレチだけど勉強になった。ありがとん
627デフォルトの名無しさん:2009/07/08(水) 18:04:32
ファイル入出力に関する疑問
ファイルを効率的に配列に読み込むにはどうしたらいいか、という問題です。
普段は下記のようにfstreamを使って領域確保後に一気に読み込んでいました。(エラー処理等省いています)
ifstream in( filename );
in.seekg( 0, ifstream::end );
*size = static_cast< int >( in.tellg() );
in.seekg( 0, ifstream::beg );
*buffer = new char[ *size ];
in.read( *buffer, *size );

しかし今回、上の意向でfstreamが使えなくなったので、stdioで同じように読み込もうと思ったのですが
File* fp = fopen(filename, "rb");
fseek(fp, 0, SEEK_END);
size_ = ftell(fp);
data = new char[size_];
fseek(fp, 0, SEEK_SET);

配列を確保した後、まとめてデータを読む方法がわかりません。
getcで1文字ずつ読むと非効率的のような気がするのですが、そんなことはないのでしょうか?
628デフォルトの名無しさん:2009/07/08(水) 18:06:59
fread
629デフォルトの名無しさん:2009/07/08(水) 18:10:06
ブラック企業だお(^ω^)
630デフォルトの名無しさん:2009/07/08(水) 18:12:42
freadなんてそのまんまな関数があるなんてしりませんでした、恥ずかしい・・・
631デフォルトの名無しさん:2009/07/08(水) 19:38:05
例外の伝播経路情報を残しつつ、ログとかダイアログを出す等の
最終的な処理はできるだけ後方でやるためのコードを書いてみた
のですが、いかがでしょうか。アドバイスお願いします。
#include <iostream>
#include <stdexcept>
class TestException : public std::exception
{
public:

TestException(const char *p) : std::exception(p), m_pE(NULL) {}
virtual ~TestException() { delete m_pE; }
void chain(TestException *p) {
if (m_pE != NULL) m_pE->chain(p); else m_pE = p; }
TestException *m_pE;
};
void a() { throw TestException("exception from a"); }
void b() {
try { a(); }
catch (TestException &e) {
try { e.chain(new TestException("exception from b")); }
catch (...) {}
throw;
}
}
int main() {
try { b(); }
catch (TestException &e) {
for (TestException *pE = &e; pE != NULL; pE = pE->m_pE) std::cerr << pE->what() << std::endl;
}
return 0;
}
632デフォルトの名無しさん:2009/07/08(水) 21:45:44

#include    "main.h"

////////////////////////////////////////////////////////////////////////////////////////////////
BOOL    InitApp( int iCmdShow )
{
    WNDCLASSEX  wcl;
    //HACCEL    hAccel;

    wcl.cbSize          = sizeof(wcl);
    wcl.hInstance       = hInstApp;
    wcl.lpszClassName   = APP_CLASS;
    wcl.lpfnWndProc     = WindowProc;

このようにインデントができるようになったらなw
633デフォルトの名無しさん:2009/07/08(水) 23:02:59
たすけてーーー。

今回、初めてC++Builder5を使用してプログラムを作成していますが
何もわからない。
誰も頼る人がいないので初投稿です。

1、以下のようなテキストファイルが存在する。
---------------------------------
1の要求を受付ました。
1の要求の応答を送信しました。
2の要求を受け付けました。
2の要求の応答を送信しました。
<-どんどん新しいデータが入る。

---------------------------------

2、テキストファイルのデータを新しいもの順に表示する。

※↓textArea??
--------------------------------- ↑新
2の要求の応答を送信しました。 <-新しいデータが来るたび一番上に追加される。
2の要求を受け付けました。
1の要求の応答を送信しました。
1の要求を受付ました。


--------------------------------- ↓古

上記のようなものを実現したいのですが、さっぱりわかりません。
誰か教えてください・・・(;;)w
634デフォルトの名無しさん:2009/07/08(水) 23:07:15
1行ごとに全部リストとかに読み込んで逆順に出力すればいいよ
635デフォルトの名無しさん:2009/07/08(水) 23:48:26
>>633
君達の友人の言葉送ろうか?

「しね」
636デフォルトの名無しさん:2009/07/09(木) 02:44:19
>>632
コピペすると大変面倒です。

インデント無しコードをコピペして再インデント、もしくは
>>631のインデントが有効となる状態でコピペをする方がいい。
というか、再インデントが一番楽。
637デフォルトの名無しさん:2009/07/09(木) 06:57:31
>>636
とりあえず
codepad
ttp://codepad.org/
に貼って実行してみろ。

個人情報が含まれないように気をつけてね。
638デフォルトの名無しさん:2009/07/09(木) 07:27:26
C言語の定番的な初級本・中級本を教えて下さい。

作りたいものはデータ入力したものをソートしディスプレイ表示と印刷するものです。エクセルで出来るのですが定型的なものを作りたいのです。
経験はN88BASICコンパイラ(20年前)です。
独習します。周囲には詳しい人がいません。よろしくお願いいたします。
639デフォルトの名無しさん:2009/07/09(木) 07:33:57
640デフォルトの名無しさん:2009/07/09(木) 07:41:59
>>639
うわ!
どうもありがとうございます♪
早速しらべます!
641デフォルトの名無しさん:2009/07/09(木) 09:03:35
VC2008 MFC SDIでの質問です。

xxxView.cpp でファイルオープンしてパスを
Cstring filename に格納し、
xxxDialog.cpp で利用するにはどうしたら良いですか?

宜しくお願いします。
642デフォルトの名無しさん:2009/07/09(木) 12:29:15
>>641
Mediatorパターンつうのか、
どちらのウィンドウクラスからもアクセス可能な第3者のクラスにファイル名を管理させれば?
第3者ってのは、たとえばメインウィンドウクラスとか、アプリケーションクラス
643デフォルトの名無しさん:2009/07/09(木) 12:45:52
>>641
ありがとうございます!
気付きませんでした!
644デフォルトの名無しさん:2009/07/09(木) 13:06:45
こうしてデザパタ信者がまたひとり誕生するのであった
645デフォルトの名無しさん:2009/07/09(木) 13:11:27
642です。
Mediatorパターン以外にもやり方はありますか?
646デフォルトの名無しさん:2009/07/09(木) 13:17:21
問題の要点はこういうことだな
「お互いにアクセス手段を持たない2つのオブジェクトが情報をやりとりするには?」

↓ここで識者登場
647デフォルトの名無しさん:2009/07/09(木) 13:46:32
>>641
ダイアログクラスのインスタンスにパスを設定してからダイアログ開く
648デフォルトの名無しさん:2009/07/09(木) 14:00:28
cinで入力を求めるとき一定時間入力がなかったらデフォルトコンストラクタを返すにはどうしたらいい
649デフォルトの名無しさん:2009/07/09(木) 14:05:56
デフォルトコンストラクタを返すってどういうこと
650デフォルトの名無しさん:2009/07/09(木) 14:21:34
>>638 さりげなく N88BASIC でなく、N88BASICコンパイラ って辺りに渋みを感じた
651デフォルトの名無しさん:2009/07/09(木) 15:17:26
>>648
タイマー付きのistreamっぽいクラスを作ってcinの代わりに使う
652デフォルトの名無しさん:2009/07/10(金) 12:48:14
>>647
ダイアログクラスのインスタンスにパスを設定してからダイアログ開く

がぐぐってもの良く解りません。
誰か詳しく教えてください。
653デフォルトの名無しさん:2009/07/10(金) 13:32:06
654デフォルトの名無しさん:2009/07/10(金) 22:51:43
C初心者です。ちょっと質問させて下さい。

main()
{
  int i = 6, j = 4, k;

  k = ++i * --j;
  k = i++ + k / j--;
  k = i * j - k;
  printf("%d", k);
}

という問題で苦戦してます。
優先順位や結合規則がイマイチわかりません。
答えは2になるみたいですが、どういった流れでトレースしていけば良いのでしょうか?
655デフォルトの名無しさん:2009/07/10(金) 23:00:39
>>654
優先順位の高い物からカッコでくくれ

k = (++i) * (--j);
k = (i++) + (k / j--);
k = (i * j) - k;
656デフォルトの名無しさん:2009/07/10(金) 23:04:15
優先順位で特に覚えておかなくちゃいけないのは2種類

1、関数の()、配列の[]、マンバ呼び出しの.と->は最上級
2、タンコ演算子(&、*、+、−、++、−−など)は第2位で、結合方向が右から左。
3、参考演算子と代入演算子も結合方向が右から左。

これだけしってればあとは祝詞勢い。
657デフォルトの名無しさん:2009/07/10(金) 23:10:49
>>655
どおしても人の顔に見える
658デフォルトの名無しさん:2009/07/10(金) 23:14:35
>>655>>656
レス有難う御座います。助かります。

明日、C言語検定3級の試験がありまして、その試験勉強をしているところなのですが
分からなくなったらまた質問してもよろしいですか?
659デフォルトの名無しさん:2009/07/10(金) 23:17:37
5時間以上考えるか調べるかしてそれでもわからないなら質問していいよ
660デフォルトの名無しさん:2009/07/10(金) 23:17:37
>*<
661デフォルトの名無しさん:2009/07/10(金) 23:42:38
>>654の件なのですがすいません。えーと・・・

自分なりにトレースしながら計算してみたんですが

一行目でi=7、j=3、k=21
二行目でi=8、j=2、k=18
三行目でk=-2

という様に代入されていって答えは-2になってしまったのですが
解答を見ると2になっています。どこが間違っているんでしょう?
662デフォルトの名無しさん:2009/07/10(金) 23:46:15
二行目、後置演算子。
663デフォルトの名無しさん:2009/07/10(金) 23:53:05
>654みたいな問題の存在意義が解らない。
こんな糞コードが世に放たれることがないよう
最初から可読性を重視したコーディングを
覚えさせる方が先じゃないのかね?
664デフォルトの名無しさん:2009/07/10(金) 23:53:41
前置増分演算子と後置増分演算子
については

2月 8日
ttp://guppy.eng.kagawa-u.ac.jp/2005/Programming2/060208pre.html
665デフォルトの名無しさん:2009/07/10(金) 23:53:43
>>662
できました!ありがとうございます。
666デフォルトの名無しさん:2009/07/10(金) 23:55:47
>>633
つ[tail -r]
667デフォルトの名無しさん:2009/07/11(土) 00:05:13
^>^
668デフォルトの名無しさん:2009/07/11(土) 00:08:52
連投すいません。

main()
{
  int l = 7, m = 6, n;

  n = l >= m;
  n += l == m + n;
  n += l != m + n;
  printf("%d\n", n);
}

関係演算子や等価演算子は、繰り返し文でしか使ったことが無かったものですから
一体何の値がnに代入されるのか見当もつきません。ご教授お願いします。
669デフォルトの名無しさん:2009/07/11(土) 00:25:30
C言語の場合、比較演算子、関係演算子、論理演算子の結果は
真ならば1、偽ならば0と定められてる。

余談だけど○○==TRUEってコード書くと
死ぬ目に遭う事になるかもしれないよ
670デフォルトの名無しさん:2009/07/11(土) 00:27:37
五時間考えろと言われなかったか?
優先順位を元に括弧で囲めというアドバイスはもらわなかったか?
なぜ何もしない状態で出てきた?
671デフォルトの名無しさん:2009/07/11(土) 00:30:04
○○==trueならそうそう死にはしないだろうけど、TRUEはだめだな。
672デフォルトの名無しさん:2009/07/11(土) 00:40:57
>>669
できました!助かります。

>>663
C担当の講師も同じようなことを言ってました。
彼曰く、C検定の勉強は不細工なソースでも読めるようになるための
勉強であって、実用的ではないのでプログラムを組む時は真似しないように。
とのことでした。
673デフォルトの名無しさん:2009/07/11(土) 00:48:12
>>669
すいません。
独学でこつこつやっていて、セミナーには週に一回しか通っていないので・・すいません^^;
674デフォルトの名無しさん:2009/07/11(土) 00:49:23
今のは>>670さんへの安価です。
675デフォルトの名無しさん:2009/07/11(土) 01:09:55
>>657
/* /// ω /// */
676デフォルトの名無しさん:2009/07/11(土) 01:29:05
あれ、俺独学でこつこつやってる人のイメージ間違えてたかも
677デフォルトの名無しさん:2009/07/11(土) 01:56:49
正直もっと前から始めるべきでしたw
こんなんじゃ間に合わねーって焦り出して一昨日から徹夜してました。
皆さんのお陰でなんとか受かりそうです。本当に有難う御座いました。

もう真夜中ですがまた何かありましたら宜しくお願いします<( _ _ )>
678デフォルトの名無しさん:2009/07/11(土) 10:27:40
ClassA A, B;
A = B;
となったとき、最初の宣言時のAはどこへ行っちゃうんですか?
679デフォルトの名無しさん:2009/07/11(土) 10:31:37
Aに割り当てられたメモリに、Bの内容がコピーされる。
だから、どこかへ行くのではなく、自身の形がBと同じ内容に書き換わる、が正解。
具体的に内容がどうコピーされるかは、operator=()次第だけれども。
680デフォルトの名無しさん:2009/07/11(土) 20:53:39
>>678
知識確認。
変数とかメモリって知ってる?
681デフォルトの名無しさん:2009/07/11(土) 21:07:16
ClassA A; // メモリ領域にAの内容が展開(インスタンス化)され、変数Aはその参照のような状態になっている
ClassA B; // もう一個生成する
A = B;   // 参照だけ置き換えてしまった事で、元々のAの領域はリークのような状態になってしまう

・・・みたいな想像したのではないかとエスパー。 しかし正解は >>679
682デフォルトの名無しさん:2009/07/11(土) 21:11:48
>>681
みたいなことをやりたいなら
独立参照が必要ですなぁ。

>>678
まずはC言語を学ぶといいよ。
いろいろ躓きづらくなる。
683デフォルトの名無しさん:2009/07/11(土) 21:18:16
=を定義してないとビットレベルで上書きされる
684デフォルトの名無しさん:2009/07/11(土) 21:55:38
そうでもない
685デフォルトの名無しさん:2009/07/11(土) 22:02:46
全ビットコピーは組み込み型だけ。
ユーザー定義型は代入演算子の挙動次第。
686デフォルトの名無しさん:2009/07/11(土) 22:41:42
HWPS! ≫ #pragma once
ttp://holy.enyou.org/2007/09/09/pragma_once/

ここの

> しかしこのアプローチは、2つの異なる場所に書かれた
> #include 指示子が同じヘッダファイルを指しているか
> どうかを知るのが根本的に困難であるため、
> うまくいかないことがある
> (例えば、シンボリックリンクの場合)。

この意味が分かりません。
どういう状況のことを言っているのでしょうか?
687デフォルトの名無しさん:2009/07/11(土) 22:45:25
>>686
例えばfoo.hがある場合、ln -s foo.h fooz.hとして
#include "foo.h"
#include "fooz.h"
としたときにpragma onceでインクルードガードをするのは難しいと言うこと。
688デフォルトの名無しさん:2009/07/11(土) 22:45:26
>>683-685
> =を定義してないとビットレベルで上書きされる
> 全ビットコピーは組み込み型だけ。
> ユーザー定義型は代入演算子の挙動次第。

class MyClass
{public :
unsigned int num;
double x;
YourClass hoge;
};
というクラスがあったとすると、
「コンパイラが自動生成する」MyClassのoperator=(const MyClass&)の定義は
YourClassのoperator=(const YourClass&)の実装次第って事かい?


689デフォルトの名無しさん:2009/07/11(土) 22:46:57
>>687
確かに普通のインクルードガードなら
そういったシチュエーションでも
対応できますね。

ありがとうございます。
690デフォルトの名無しさん:2009/07/11(土) 23:00:47
質問です。 次のような時、関数内で配列数を取得する方法はありますでしょうか。

void func(const char* p) [
 // ここで配列のサイズを知りたい
 // しかしこのポインタが、実は関数の外で配列のアドレスがコピーされた物だ、
 // という事を知るすべが無いから、知りようが無いような気がしています。
 // 何か方法は無いでしょうか。
}

void main() {
 char abc[100];
 char *p = abc;

 func(p);
}
691デフォルトの名無しさん:2009/07/11(土) 23:03:52
不可能
サイズも一緒に渡すかコンテナを使う
692デフォルトの名無しさん:2009/07/11(土) 23:04:52
template <int N>
void func(const char (&a)[N])
{
// Nは配列数
}

という風にC++なら出来るんだがな
693デフォルトの名無しさん:2009/07/11(土) 23:06:10
無い。
呼び出しにsize_tを追加するか、構造体を渡すのが定石。
694デフォルトの名無しさん:2009/07/11(土) 23:06:20
>>692
やっべ
初めて知った俺が居る
695デフォルトの名無しさん:2009/07/11(土) 23:06:47
>>690
そのサンプルのような使い方を想定する場合、ナル文字を探すと言うアプローチで充分。
何故なら、const char *である以上格納は行なえないから。
696デフォルトの名無しさん:2009/07/11(土) 23:08:00
>>694
Boostのソース見てみろよ
もっと凄い事いっぱいしてるから
697デフォルトの名無しさん:2009/07/11(土) 23:08:46
>>692
これ見るたび感心するんだけど、いざ使いたいときには思い出せないんだよな・・
698デフォルトの名無しさん:2009/07/11(土) 23:09:10
>>694
こんなのを作るのは、C++使いの誰もが通る道。
template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}
699デフォルトの名無しさん:2009/07/11(土) 23:09:24
>>692のやり方でも>>690みたいに一度ポインタに渡してしまうと
配列数の情報が失われてしまいコンパイルエラーになる

あくまでも func(abc); のように呼び出す事が原則
700694:2009/07/11(土) 23:12:45
>>698
> template<typename T, std::size_t N> inline std::size_t numberof(T (&)[N]) {return N;}

ええと、これはつまり
任意の型の配列を受け取れて、
TやNはコンパイラに推論させることで
こちらが打ち込む必要はないって事ね。

どうも。
701デフォルトの名無しさん:2009/07/11(土) 23:15:21
>>692
これ2次元でも大丈夫なのね
Sugeeeeee!
2次元配列の受け渡し問題がついに解決したわ
702690:2009/07/11(土) 23:29:58
ありがとうございます。やっぱり無理か・・
素直にエイリアス受け取るか、\0探す形にします。
あと、 templete 微妙に書かれてる内容の意味がわからないので
(特に N をどうやって取得するのか) これから勉強します

703690:2009/07/11(土) 23:33:25
ちなみに、>>698 のテンプレートって、要は

char abc[100];
int l = sizeof(abc)/sizeof(char);

の、任意型バージョンみたいな動作って事になるんですよね?
704デフォルトの名無しさん:2009/07/11(土) 23:34:11
>>697
使うだけなら<boost/range/size.hpp>のboost::sizeを使えばいい。
もっとも、Boost.Rangeの一部なんで、STLコンテナやBoost.Arrayなどにも返事を返すけど。
705678:2009/07/11(土) 23:42:24
情報不足で色々エスパーしてもらって申し訳ないです。
ClassA はそのなかでオブジェクトを生成したりしてるので、
どうなっちゃうんだろうと思ったのです。
何も考えずともC++がAを削除してからBをコピーしてくれるのか
クラスを書く人がoperator=()を上書きしてあげないといけないのか。

679さんの説明だと、ほんと=次第というか、class書く人間が
考慮してあげないといけないようですね。

うう・・・めんどくさい。
代入されたときの挙動まで考えるぐらいなら、
いっそ=を禁止したい(コンパイルレベルで
706デフォルトの名無しさん:2009/07/11(土) 23:48:59
>>705
>C++がAを削除してから
この表現がまた怪しいな。

>ClassA はそのなかでオブジェクトを生成したりしてるので、
pimplイディオムを使ったことある?
浅いコピーとかディープなコピーとか聞いたことある?
707デフォルトの名無しさん:2009/07/11(土) 23:50:02
private:
type& operator=(const type&);
708デフォルトの名無しさん:2009/07/11(土) 23:53:28
>>705
取り敢えず、EffectiveC++くらいは読んでからクラスの設計をするといいと思うよ。

>>703
テンプレート版のいいところは、配列以外だときちんとエラーになること。
char * pに対してsizeof(p) / sizeof(* p)なんてしたらどうなるかと思うとw
但し、>698のように小さい関数として実装する分には最適化で消えてなくなるからいいけれど、
>692のように大きい関数で使うとサイズの違う配列を使うたびに実体が作られることに注意。
709デフォルトの名無しさん:2009/07/11(土) 23:53:37
関テのテンパラはパラからコンパが類推するから、
配列aに対して単純に

numberof( a )

のように記述すれば、aの要素数が返る。
どこでも使える。

問題は、この関数は要素数の異なる配列ごとに
別々のコードが生成されるのでコードが肥大化するって言う点。
どう見てもnumberofはコンパイル後に定数に置き換わるようなないようだけど
現行のコンパイラはまだそこまで賢くない。
テンプレートメタプログラミングがもっと一般化すれば
これはとても良い具合になるはず。
710デフォルトの名無しさん:2009/07/11(土) 23:59:19
>>709
最近のコンパイラを舐めない方がいい。つーか、調べずに書きなさんな。
iccは勿論gccでも>698は最適化で定数に成り下がるよ。
711デフォルトの名無しさん:2009/07/12(日) 00:03:37
>>709の知識はそこまで最新じゃないんだろ。
コンパイラ作っている人ってホント尊敬するわ。
712デフォルトの名無しさん:2009/07/12(日) 00:06:44
ち。
713デフォルトの名無しさん:2009/07/12(日) 00:16:34
普通にvectorとか使った方が速いようなw
714デフォルトの名無しさん:2009/07/12(日) 00:18:04
動的配列で使えたら最高なのに
715デフォルトの名無しさん:2009/07/12(日) 00:26:59
>>713
何とvectorを較べてるの? まさかとは思うけど、vector::size()が速いなんて思ってないよね?

>>714
動的配列が欲しいなら、それこそvectorの出番。
716デフォルトの名無しさん:2009/07/12(日) 00:28:22
>>715
スピードが、じゃなくて、手っ取り早いって意味ね。w
>>690の用途ならvectorで十分じゃない?ってこと。

リニアなスピードが要求されるならともかく。
717デフォルトの名無しさん:2009/07/12(日) 00:30:51
ここでvectorじゃなくてstringだろ、という揚げ足取り↓
718デフォルトの名無しさん:2009/07/12(日) 00:34:36
>>713
速いじゃなくて早いだろ
719デフォルトの名無しさん:2009/07/12(日) 00:36:34
揚げ足じゃなくて至極もっともなツッコミだったな
720デフォルトの名無しさん:2009/07/12(日) 00:39:05
多次元配列の要素数を知りたいときはどうしたらいいのだ。
つまり、次元数も込みで、という意味だよ。^−^
721デフォルトの名無しさん:2009/07/12(日) 01:08:52
それが可能なコンテナを使う、かなあ
722デフォルトの名無しさん:2009/07/12(日) 01:56:57
>>705
クラスのあり方として複製という概念を持たないために
代入禁止とするいうのはよくあることだよ。fstreamとかそうでしょ。
JavaやC#とかよその言語だとライブラリ全体の中でCloneableなクラスのほうが珍しいくらい。
ここの参照オブジェクトというやつだな。
ttp://www.ogis-ri.co.jp/otc/hiroba/technical/CppDesignNote/

ちなみに、やるときには>>707に加えてコピーコンストラクタも禁じないと意味ないからな。
723デフォルトの名無しさん:2009/07/12(日) 01:58:29
>>708
<windows.h>のARRAYSIZEマクロを見るがいい。
テンプレートを使いつつ、sizeofによって確実にコンパイル時定数にしている。
まあ最適化目的よりも、言語仕様で定数が要求される場所でも使えるという意味合いのほうが大きいだろうけど。
> extern "C++" // templates cannot be declared to have 'C' linkage
> template <typename T, size_t N>
> char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
>
> #define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))

> #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
724デフォルトの名無しさん:2009/07/12(日) 15:20:38
すみません、質問です。 Win32環境で、メモリに既に読み込まれているバイトデータ(char*)に対して、
FILEハンドルを与える方法って無いでしょうか。

// 普通にファイルのハンドル
FILE *fp1 = fopen("C:\\hoge.txt", "rb");

FILE *fp2 = メモリに既に読み込まれているバイトデータに対してファイルコンパチなハンドルを生成

やりたい事は、ファイルストリームと互換性のあるメモリストリーム実装です
725デフォルトの名無しさん:2009/07/12(日) 15:31:15
>>724
メモリ空間をドライブとしてアクセスするためのドライバ(所謂RAMDRIVE)を作ればFILEをどうこうする必要はないよ。
そうでないのなら、いくらFILEと互換性を持たせてもライブラリ関数(例えばfputc)も自前で実装しなおす必要が出てきてしまう。
726デフォルトの名無しさん:2009/07/12(日) 15:43:56
>>725
すみません、やりたい事について情報が曖昧でした。
既存のライブラリの関数(具体的には lpng の関数 png_init_io(png構造体ポインタ、FILE*) )に、
既にPNGファイルイメージが生成してあるメモリ領域の char* を渡して、最終的に HBITMAP ハンドルを受け取りたいんです。

[PNGのメモリイメージ] → (変換) → [HBITMAP としてハンドル取得]
                 ^^^^^^ この部分を lpngライブラリに任せている。その際、FILE* が必要
727デフォルトの名無しさん:2009/07/12(日) 15:59:12
>>726
>725の一行目。
728デフォルトの名無しさん:2009/07/12(日) 16:06:54
>>726
lpng=libpngだとすると、たぶんライブラリの使い方を知らないだけ。

ここの前半部とか。
ttp://www.jah.ne.jp/~naoyuki/Writings/MngPng.html
これ以上はスレチなので、画像処理のスレに行ってください。
729デフォルトの名無しさん:2009/07/12(日) 16:10:24
生き物の祖先は魚(みたいな何か)のはずなのに
なんで虫にはあばら骨がないの?
730デフォルトの名無しさん:2009/07/12(日) 16:12:31
1.宇宙から来た(別の進化の系統に属する)から
2.実は魚に背骨が出来たのはずっとあと(マジで)

1または2、どちらか好きなほうを採用してください。
731726:2009/07/12(日) 16:15:22
>>728 すみませんでした・・ いきなり解決しました。 ただのコールバックだったのかorz
もしかしてコンパチFILE*を簡単に生成する方法でもあるなら、他の用途でも使えるかなとおもって
最初のような書き出しになりましたが、目的はこれで達成できます。 ありがとうございました。
目的明かしてスレチ確定。orz

>>727 そこまでの実装は望んでいなかったので、すみません
732デフォルトの名無しさん:2009/07/12(日) 16:29:15
>>728
その程度のことで画像処理のスレに誘導しないでください。あっちでライブラリの使い方を聞いても答えられませんし。
733デフォルトの名無しさん:2009/07/12(日) 16:44:29
>>726
Cygwinだとfmemopenが使える。

VCなら、_pipeでパイプを作成して、それを_fdopenでFILE*にするのがいいと思う。
_pipeは読み取り用と書き込み用の2つのファイル記述子がもらえるので、
書き込みのほうへ自分のデータを書いて、読み取りのほうをpng_init_ioに渡す。
734733:2009/07/12(日) 16:46:02
あれ、もう解決してた?すまん。
735デフォルトの名無しさん:2009/07/12(日) 20:27:20
aaa.cpp(main関数を含む。foo.hをインクルードしている。)
foo.h(class fooの宣言と定義を含む。)
foo.cpp(class fooの実装を含む。)

この時、g++ aaa.cppだけではコンパイルは出来ますがリンカエラーになります。

g++ aaa.cpp foo.cppとすれば実行ファイルまで出来るのですが、
これを他人に言いたい時はなんというのでしょうか?
foo.cppをリンクしてくださいで用語として通用しますか?
736デフォルトの名無しさん:2009/07/12(日) 20:44:39
分割コンパイルのやり方を調べれ
737デフォルトの名無しさん:2009/07/12(日) 22:08:33
g++ aaa.cpp foo.cppしてください

この辺りは方言多いので省略すると通じない可能性高いし、
そもそもcppファイルはリンクするものじゃないし
738デフォルトの名無しさん:2009/07/12(日) 22:38:36
fooがライブラリとして
 foo.h
 foo.cpp
の形で公開されていて、
この使い方を問うときに
適当な日本語が欲しいのです。

 foo.hをインクルードしてください

だけでは動きませんよね?
皆さんはこの場合どうやって伝えていらっしゃいますか?
739デフォルトの名無しさん:2009/07/12(日) 22:41:45
libfooをリンクしろ。ヘッダはfoo.h。

これだけで伝わるだろ。
740デフォルトの名無しさん:2009/07/12(日) 22:43:41
>>738
foo.hとfoo.cppが与えられたら、使い方なんて一通りしかないんだから、何も言わなくてもわかる。
741デフォルトの名無しさん:2009/07/12(日) 22:49:41
> fooがライブラリとして
>  foo.h
>  foo.cpp
> の形で公開されていて、

「ヘッダをインクルードして下さい。プロジェクトに foo.cpp も追加して下さい」
742デフォルトの名無しさん:2009/07/12(日) 22:55:50
>>741
プロジェクトってなんですか?
743740:2009/07/12(日) 23:05:52
>>741
ありがとうございます。
それで行かせていただきます。



>>742
失せろヴォケ
744デフォルトの名無しさん:2009/07/12(日) 23:10:29
コンパイルとかリンクの話はオライリーのC++クックブックがわかりやすかった
745デフォルトの名無しさん:2009/07/12(日) 23:47:56
740 名前:デフォルトの名無しさん[sage] 投稿日:2009/07/12(日) 22:43:41
>>738
foo.hとfoo.cppが与えられたら、使い方なんて一通りしかないんだから、何も言わなくてもわかる。

741 名前:デフォルトの名無しさん[sage] 投稿日:2009/07/12(日) 22:49:41
> fooがライブラリとして
>  foo.h
>  foo.cpp
> の形で公開されていて、

「ヘッダをインクルードして下さい。プロジェクトに foo.cpp も追加して下さい」


742 名前:デフォルトの名無しさん[sage] 投稿日:2009/07/12(日) 22:55:50
>>741
プロジェクトってなんですか?


743 名前:740[sage] 投稿日:2009/07/12(日) 23:05:52
>>741
ありがとうございます。
それで行かせていただきます。



>>742
失せろヴォケ


740=743???
746デフォルトの名無しさん:2009/07/13(月) 00:17:55
関数ポインタと関数参照ってどう違うの?
747デフォルトの名無しさん:2009/07/13(月) 00:20:45
関数ポインタ = 関数を指しているポインタ
 → 指しているのは関数だが、ポインタなので計算出来る

関数参照 = 関数のアドレス。元の関数のエイリアス
 → 指しているのは関数だが、ポインタじゃないので計算は出来ない
748デフォルトの名無しさん:2009/07/13(月) 00:23:29
>>747 に続けて使用例から見た違い
関数ポインタ ・・・
 ポインタなので、関数を列挙した配列(関数テーブル)を順に移動しつつ処理するみたいな事が出来る
関数参照 ・・・
 ただのエイリアスなので、元の関数を呼ぶだけ = その関数にだけ用があるようなコールバック動作の為に良く使う
749デフォルトの名無しさん:2009/07/13(月) 00:25:23
thx
ポインタ⊃参照な感じか
750デフォルトの名無しさん:2009/07/13(月) 00:33:56
Haagen-Dazs
751デフォルトの名無しさん:2009/07/13(月) 00:35:30
はあ?って書こうと思ったら、間違えて変換してしまった。すみません。
752デフォルトの名無しさん:2009/07/13(月) 02:40:35
ファイルから読み込んだデータは、C++の場合どのように持つのが定石なのでしょうか?
読み込んですぐ捨てるようなデータではなく、プロセスが生きている間使うようなデータです。
Cの場合だとグローバル変数として宣言した変数に入れると思うのですが。

753デフォルトの名無しさん:2009/07/13(月) 02:46:09
Cでもまともなプログラムならグローバル変数になんか入れねえよ
754デフォルトの名無しさん:2009/07/13(月) 03:07:34
いれるだろ?
まさか共有メモリを確保して・・・とかいいだすんじゃないだるな?
755デフォルトの名無しさん:2009/07/13(月) 03:16:29
入れねえよ ・・・ 「配列確保して持っとくみたいな事しねぇよ」
入れるだろ ・・・ 「malloc した後のポインタやサイズを持っとくだろ」

こんなすれ違い
756デフォルトの名無しさん:2009/07/13(月) 18:20:00
C++でC言語のsscanfと同じような働きをするクラスか関数は
どんなもんなんですか?
757デフォルトの名無しさん:2009/07/13(月) 18:37:40
遅くてもいいから、どうしても C++ のストリームを使いたい、ってことなら
strstream から >> 演算子で入力。

まあふつーは std::sscanf。
758デフォルトの名無しさん:2009/07/13(月) 20:48:51
遅くてもって
どんだけ大量のストリーム流し込む気だよ
759デフォルトの名無しさん:2009/07/13(月) 21:14:04
std::strstreamなんて使うなよ
前のC++の遺物だぞ

今はstd::stringstream、std::istringstream
760デフォルトの名無しさん:2009/07/13(月) 21:16:32
ここで敢えてregexを持ち出そうではないか。
本当はxpressiveを使いたいところだけど。
761デフォルトの名無しさん:2009/07/13(月) 21:23:12
ストリームをメモリにぶっこむのになぜ正規表現
762デフォルトの名無しさん:2009/07/13(月) 21:33:25
最近覚えたとかか
763デフォルトの名無しさん:2009/07/13(月) 21:59:02
>>761
区切り文字とかの規則がある中から文字列を切り出すようなことだろうと感じたから、
それには正規表現も選択肢の1つとして不思議ではないと思った。
764デフォルトの名無しさん:2009/07/13(月) 22:16:08
マルチスレッドの質問です。
インテルCPU, WindowsXP、Win32の処理系において下記のようなモデルを考えた時、
マルチスレッド間で1の処理や4の処理を if(式) として記述した時、その式評価中に割り込まれるような事は
あるんでしょうか。

TLS でない volatile なグローバル int A (実際には構造体のメンバ)

主スレッド
 1.A の 第2ビットが 1の時処理をスキップし、0の時、第1ビットを立てる
 2.〜スレッド間共有構造体にアクセス〜
 3.第1ビットを降ろす

副スレッド
 4.A の 第1ビットが 1の時処理をスキップし、0の時、第2ビットを立てる
 5.〜スレッド間共有構造体にアクセス〜
 6.第2ビットを降ろす

要はOSのスレッド処理の分解能の単位が知りたいのです。
765デフォルトの名無しさん:2009/07/13(月) 22:16:23
>>763
超絶エスパーだな。
766デフォルトの名無しさん:2009/07/13(月) 22:21:22
割り込まれます。 条件式をチェックしている間に、
別のプロセスに値を書き換えられたりとか普通。
だから条件式全体をむーてくすとかせまふ男とかで囲ってロックしないと
大変なことに。
767デフォルトの名無しさん:2009/07/13(月) 22:47:15
InterlockedCompareExchange使えって課題か?
それはともかく、volatileがマルチスレッドに効果あると謳ってるのはVC独自だよ。
gccなんかはそういう保証は付けていないはず。
768764:2009/07/13(月) 23:34:01
やっぱり割り込まれるか・・・ ちなみに、>>764 の1の処理、仮にフラグを1つだけにして、
そのビットが立っていれば主スレッドが構造体を触る権利を得て、降りていれば副スレッドが権利を得る
というルールにした場合に、評価式を


if(A^=1) {
 構造体を触る
}


if(A^=1) {
} else {
 構造体を触る
}

のようにしていたとしても、代入と評価の2ステップの間に割り込まれてしまうって事ですよね?

>>767 いえ学生では無いので課題とかではありません。
ちなみに volatile の動作って最適化を抑制してレジスタでの持ちまわしを止めさせる
= 常にメモリへのread/writeを行う事で整合が取れない自体になるのを抑える、みたいな感じでしたっけ。 VCの場合
769764:2009/07/13(月) 23:37:19
・・・すみません。てか毎回代入したら意味無い やっぱダメだorz
770デフォルトの名無しさん:2009/07/13(月) 23:46:45
>>767
volatile は、最適化されてメモリ上にとられなくなってしまう、という事態をなくすのではなかったかと。
とすれば 必要条件であっても十分条件ではないのは vc でも gcc でも同じはずでは
771デフォルトの名無しさん:2009/07/14(火) 00:12:51

if(A&1) {
 構造体を触る
A^=1;
}


if(A&1) {
} else {
 構造体を触る
A^=1;
}
772デフォルトの名無しさん:2009/07/14(火) 00:14:01
>>770
それだけでなくて、VCだと読み書きの順序にも影響が及ぶ。
Microsoft Specificのところ。
http://msdn.microsoft.com/en-us/library/12a04hfd.aspx
773デフォルトの名無しさん:2009/07/14(火) 00:27:51
ちゃんと道具があるのにそれを使わずにどうにかしようっていうのはおかしいよね
包丁使いたくないからカッターでどうにかする的な。
774デフォルトの名無しさん:2009/07/14(火) 00:29:36
ああでもどっちかがやったならもう片方はスルーすんのか
775デフォルトの名無しさん:2009/07/14(火) 00:29:43
揮発変数の読み書きを最適化によって消してはならないのと命令の順序を入れ替えてはいけないのは規格で決まってる。
もっともCの規格にスレッドに関する規定が何もないので、それがマルチスレッドにおいてどう働くかは定められていないが。
776デフォルトの名無しさん:2009/07/14(火) 11:14:21
だって volatile って元々、メモリマップドI/O 用でしょ?
同じ値を何度も書き込むことに意味があったり
同じ変数を読むたびに違う値が取れたり。
777デフォルトの名無しさん:2009/07/14(火) 11:19:09
そそ、マルチCPU環境でCPU1からの書き込みがCPU2からの読み込みの前に行われる保証なんて誰もしてくれない。
778デフォルトの名無しさん:2009/07/14(火) 12:29:09
>>771 だからそれだとifの評価の後Aが変えられてるかもしれないので
意味がないって話じゃないか?

評価→処理→フラグ更新
‥例えば主側のこの流れの間に副側がズレて重なってる可能性があるから
ダメって事
779デフォルトの名無しさん:2009/07/14(火) 12:51:40
>>771
それだと特に偽の時ヤバい
780デフォルトの名無しさん:2009/07/14(火) 18:30:23
C++のstringstreamで data%d.dat という文字列があったときに
data1.dat data2.dat ...
という文字列にして出したい場合はどのようにすればよいのでしょうか?
781デフォルトの名無しさん:2009/07/14(火) 19:37:42
基底クラスAの派生クラスBと同じく基底クラスAの派生クラスCがあって、
クラスBのメンバ関数で基底クラスAのメンバ変数の値を変更したとき
この値をつかって派生クラスCのメンバ関数で基底クラスAのメンバ変数について何らかの処理をさせたい場合はどのようにすればいいのか
簡単な例でいいので教えていただけませぬでしょうか?
782デフォルトの名無しさん:2009/07/14(火) 19:38:46
>>780
つ[std::sprintf()]
783デフォルトの名無しさん:2009/07/14(火) 19:56:31
>>781
それ要はクラスBとCって異なる二つのクラスのインスタンス同士で、
たまたま同じ基底であるA側のレイヤにあるメンバを触りたいって話か
784デフォルトの名無しさん:2009/07/14(火) 20:58:20
>>781
>基底クラスAの派生クラスBと同じく基底クラスAの派生クラスCがあって、
クラスA─(派生)→クラスB
クラスA─(派生)→クラスC

クラスB b;
クラスC c;

>クラスBのメンバ関数で基底クラスAのメンバ変数の値を変更したとき
b.proc(10); // メンバに10を格納

>この値をつかって派生クラスCのメンバ関数で基底クラスAのメンバ変数について
>何らかの処理をさせたい場合はどのようにすればいいのか
c.proc(ここにインスタンスbが保持する値を渡したい?);

継承元が異なってたとしても、単にインスタンスbに、cを渡してなんか処理すりゃいいんじゃね?
文面からまるで、b と c が aでつながってるとでも思ってるかのように見えるんだが
785デフォルトの名無しさん:2009/07/14(火) 21:12:21
hello.exeつくろうとしたらこうなたました

C:\aa>bcc32 hello.cpp
Borland C++ 5.5.1 for Win32 Copyright (
hello.cpp:
Error E2209 hello.cpp 2: Unable to open
Error E2282 hello.cpp 3: Namespace name
Error E2451 hello.cpp 7: Undefined symb
Error E2451 hello.cpp 7: Undefined symb
*** 4 errors in Compile ***
786デフォルトの名無しさん:2009/07/14(火) 21:18:23
報告ご苦労。下がってよいぞ
787デフォルトの名無しさん:2009/07/14(火) 21:21:46
>>785
マルチポスト乙。
消えろヴォケ。
788デフォルトの名無しさん:2009/07/14(火) 21:32:21
>>787
答えないならやめて、移しただけ
789デフォルトの名無しさん:2009/07/14(火) 21:52:21
>>788
> 答えないならやめて
おいどんだけ偉そうなんだよ。

> 移しただけ
そんな言い訳が有効だとでも?
それなら全てのマルチポストが許されるだろうが。
頭おかしいの?
790デフォルトの名無しさん:2009/07/14(火) 22:47:03
>>789
いや、お前の回答が無意味じゃん。聞く場所こっちのほうがいいかなっておもっただけ。

>おいどんだけ偉そうなんだよ。
マルチポスト乙。
消えろヴォケ。
791デフォルトの名無しさん:2009/07/14(火) 22:48:14
おつかれさまです><
792デフォルトの名無しさん:2009/07/14(火) 22:49:54
>>790
は?
お前マルチポストってなんだか分かってる?
重症患者?
そんな**にはプログラミングは不可能ですよ、無能君www
793デフォルトの名無しさん:2009/07/14(火) 22:58:53
>>792
マルチ廚マジキモい、IDあったらいいのに。うんそうだね。マルチあるといけないからそうやってキモウザイ事ばっかやってれば役立つかもね
794デフォルトの名無しさん:2009/07/14(火) 23:02:56
>>793
必死だなw
> hello.exeつくろうとしたらこうなたました
とか言ってるお前の脳がどうかしているとしか思えない。

・・・ま、いいよ。
何を2chでほざこうと、
お前が自身のプログラミングの無能さのせいで
現実で無職になれば、俺はそれで満足だから。
795デフォルトの名無しさん:2009/07/14(火) 23:11:16
俺の出番だな。

>>785
別のスレに回答しておいた。
796デフォルトの名無しさん:2009/07/15(水) 13:00:03
関数内でインスタンス生成したものって関数が終了したら消えますか?
それとも、deleteで関数終了時に消去するようにしなければならないでしょうか?
797デフォルトの名無しさん:2009/07/15(水) 13:03:02
自動変数として生成したものは消えます
newで生成したものはdeleteしなければなりません
798デフォルトの名無しさん:2009/07/15(水) 13:09:40
auto変数がデストラクトされる仕組みって、
最初はよくわからなかったけど(俺だけか?)
アセンブリ吐かせて中を見ると、関数の最後で律義にデストラクトしまくってるんだよね
初心者はぜひやってみて
799デフォルトの名無しさん:2009/07/15(水) 14:01:04
一応補足。当たり前だけど、中に別のインスタンスのポインタを持つ自動変数の場合、
中ポインタ変数については一緒に廃棄されるけど、ポインタの指す先は勝手に解放なんて
されないので初心者は注意すること
800デフォルトの名無しさん:2009/07/15(水) 14:08:03
ありがとう御座います、関数を生成するたびに引数にあわせて生成するインスタンスが変わるので
解放されないと大変な事になる気がしたので質問しました。助かりました、ありがとう御座います。
801デフォルトの名無しさん:2009/07/15(水) 14:43:39
C++を使い始めた最初は、やっぱみんな自動変数の破棄が心配でこういうの書いてみるよな

#include <cstdio>

int count = 0;

class hoge {
public:
int id;
hoge() { id = ++count; printf("construct <%d>\n", id); }
~hoge() { printf("destruct <%d>\n", id); }
};

void main()
{
hoge obj; // objは自動的に破棄される
hoge array[2]; // array[]の要素はすべて自動的に破棄される
hoge *p = new hoge;
hoge *q = new hoge[2];

delete p; // これを書かないとpが指すインスタンスは破棄されない
delete[] q; // これを書かないとqが指すインスタンス配列は破棄されない
}
802デフォルトの名無しさん:2009/07/15(水) 15:57:02
class A { };

A* p = new A[10];
delete[] p; // ←ここ!!

「ここ!!」で10個のインスタンスが破棄されるってことは、
pが10個の要素を持つことをコンパイラは知ってるんですよね?
この個数をプログラマが参照できれば配列引数とかの受け渡しに便利なのに…
803デフォルトの名無しさん:2009/07/15(水) 16:05:27
すべての実装が必ずしも大きさを覚えているとは限らない.
804デフォルトの名無しさん:2009/07/15(水) 16:11:52
operator new を自作すればそんなことも可能になるよ。
805デフォルトの名無しさん:2009/07/15(水) 16:48:10
配列の途中から渡された場合に困ると思う
806デフォルトの名無しさん:2009/07/15(水) 17:58:01
>>803-805
どもども。そりゃそうですよね…

operator newまわりは、まだ俺にはアンタッチャブルな気がするので
もうすこし勉強してみます
807デフォルトの名無しさん:2009/07/15(水) 19:58:48
でも >>802 を見て、「あぁ、じゃあ元が配列なポインタなら全部 delete [] で開放出来るんだ」 とか
単純に理解してしまうと、次のようなケースでハマるかもしれない。

A* p = new A[10];
delete[] p; // これはOK


A a[10];
A* p = a;
delete [] p; // コンパイルは通るが実行時エラー(於いてVC)


前者は 「自動変数でない配列を動的に生成した。その際のポインタなので delete[] で開放出来る/しなければならない」
後者は 「スコープ外れると開放される自動変数のアドレスをコピーしたポインタ。指す先は必ず開放されるので、それより先に開放してはならない」

ちょっと考えればすぐ気づくと思うけど、初心者が誤解して覚えてしまうとアレなので補足
808デフォルトの名無しさん:2009/07/15(水) 20:20:16
質問なのですが、

fprintf(fp,"%lf\n",(double)((short)x));

という文は何を示しているのですか?
fpで開けたファイルにxという数字をdouble型で格納しているのでしょうか?
shortとは何を示しているのでしょうか?
809デフォルトの名無しさん:2009/07/15(水) 20:26:03
>>802
もうstd::vectorでいいよ。
810デフォルトの名無しさん:2009/07/15(水) 20:26:11
自動変数ってスタックにとられるのではなかったか?これはC だけの話?実装依存の話?
811デフォルトの名無しさん:2009/07/15(水) 20:32:30
>>810
実装依存。スタックだのヒープだのの概念が無い計算機上でもC/C++の実装は作れる
812デフォルトの名無しさん:2009/07/15(水) 20:41:34
>>808 見たまま、shortのビット幅に一旦収めた(端数を捨てて整数化した)あと、
doubleの幅に拡張してから表示させようとしてるんじゃない?
それ自体何故そんな事してるのかってのは、書いた人の都合だろうとしか言えないが
813デフォルトの名無しさん:2009/07/15(水) 20:52:57
最適化について聞きたいんだけど、

for ( int i = 0; i < 10000; i++ ) {
pObj->pTable[ i ] = i;
}



char* pTable = pObj->pTable;
for ( int i = 0; i < 10000; i++ ) {
pTable[ i ] = i;
}

gcc4.0で、速度優先で最適化を掛けた場合、どっちが早いでしょうか。
814デフォルトの名無しさん:2009/07/15(水) 20:58:22
>>813
まあ、自動変数に入れたほうが最適化が掛かりやすいという話はあるみたい。
ttp://www.emit.jp/prog/prog_opt0.html

これくらいだったら、アセンブリ出力を見比べればどっちが速いか想像が付くのでは?
もちろん、どれくらいの差が出るかは実測が第一だけど。
815デフォルトの名無しさん:2009/07/15(水) 22:45:38
>>813
その程度で差が出るようなコンパイラは馬鹿です。

>>808
そのコードがレガシーC或いはC89などのC99以前のCであるならば、フォーマット文字列が規約違反です。
816デフォルトの名無しさん:2009/07/15(水) 22:50:50
>>813
pObjがグローバル変数だとしたら、前者と後者では意味が変わるのだけど。
817デフォルトの名無しさん:2009/07/16(木) 00:16:43
テキストデータをバイナリデータとして保存しようとし、下のプログラムを作りましたが動作しません。
何が悪いのですか?windowsのcygwin環境のC言語です。

書き込めなかったので次のレスにまたがって書きます。

#include<stdio.h>
#include<string.h>
#include<math.h>

int main(int argc, char *argv[])
{
char c;
int i,j,count;
FILE *fp,*fp2;

if(argc!=3){
printf("Usage is ...\n");
printf("trans.exe <input file> <output file>\n");
return(-1);
}
/* ファイルオープン */
if((fp=fopen(argv[1],"r")) == NULL){
return(-1);
}
if((fp2=fopen(argv[2],"wb")) == NULL){
return(-1);
}

>>818に続く
818デフォルトの名無しさん:2009/07/16(木) 00:18:52
>>817から

/* テキストデータをバイナリデータに変換/書出し */
while(1){
fgets(&c,1,fp);
if(feof(fp)){
break;
}
fwrite(&c,sizeof(double),1,fp2);
}
fclose(fp);
fclose(fp2);
return(0);
}
819デフォルトの名無しさん:2009/07/16(木) 00:35:30
sizeof(double)?
820デフォルトの名無しさん:2009/07/16(木) 00:47:20
>char c;
〜略〜
>fwrite(&c,sizeof(double),1,fp2);

これは一体
821デフォルトの名無しさん:2009/07/16(木) 01:03:06
>>819>>820

別のプラグラムでデータタイプがdouble型で入力というプログラムを貰ったのですが、そのときにバイナリファイルを入力しろと言われたので、
バイナリファイルdouble型で入力しようとしました。

この場合はcの宣言をcharではなくdoubleにすべきだったのでしょうか?

ファイル処理はCの絵本という本のみで学んだ(?)ので知識がほとんどありません。
822デフォルトの名無しさん:2009/07/16(木) 01:21:49
元のテキストデータってのは何?

↓こんな感じで人間が読める形の実数がずらずら書かれてるってこと?

1.41421356
1.7320508
2.2360679
823デフォルトの名無しさん:2009/07/16(木) 01:24:46
>>822

そういう感じです
824デフォルトの名無しさん:2009/07/16(木) 01:57:01
>>823
そういうことなら、「テキストとして書かれた実数」を読み込む方法が違ってます。
そういうときはscanf()系の関数を使ってください。
修正したソースをうpしておきます。
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9758.c
825デフォルトの名無しさん:2009/07/16(木) 02:00:37
↑入力ミスってたので1行修正
fwrite(&data, sizeof(double), 1, fp2);

fwrite()の第2引数と第3引数の順番て、いつも間違えるのさ・・・
826デフォルトの名無しさん:2009/07/16(木) 02:26:41
>>824
>>825
d。だけどfgetsとfscanfは何が違うんでしょうか?
fgetsはテキストファイル読み込みと書いていたんですが。。
827デフォルトの名無しさん:2009/07/16(木) 02:31:29
>>826
読み込んだものをどうするかが違う。
fgets()は文字列として読み込んだまま。
fscanf()はフォーマット指定に基づいて入力を分解し、型に合わせて変換してくれる。
828デフォルトの名無しさん:2009/07/16(木) 03:05:04
>>827
なるほど、fscanf()は少し入力量が多いものの優秀(上位互換)ということか。
勉強になりました、ありがとう

829悩み人:2009/07/16(木) 06:32:30
C++での日数差を計算するプログラムが全くわかりません。
西暦と月と日にちを入力して計算します。
どうか教えていただけませんか?
かなり悩んでます。早い解答待っています。
どうかお願いします。
830デフォルトの名無しさん:2009/07/16(木) 07:13:40
つ[<ctime>]
831デフォルトの名無しさん:2009/07/16(木) 07:17:51
struct tmに入れて、mktime()でtime_tに変換、difftime()で差の秒数にしたら、86400で割れば日数だね。
832悩み人:2009/07/16(木) 07:55:57
プログラミングが初心者でよくわからないのですが、頑張ってみます。
他に簡単な方法があれば教えて頂きたいのですが、ありませんか?お願いします
833デフォルトの名無しさん:2009/07/16(木) 12:11:01
理屈上は、年月日をを通算日数に直して差を求めればいい
たとえば2009年に限って考えると、2009/7/16は2009年の197日め、2009/12/31は365日目、
その日数差は168日になる。これはOK?

同じようなことを、たとえば「西暦1900年1月1日からの通算日数」でやれば
西暦1900年以降のどんな年月日についても日数差が計算できる。

で、その通算日数みたいなものを求めるには、ふつうはmktime()関数を使う。
これを利用しないで自分でがりがり計算するやつは、まずいない。
834デフォルトの名無しさん:2009/07/16(木) 16:07:47
【緊急】
手元に参考書がない・・・

誰かBCB5でのSetTimer,KillTimerの使い方おしえて
SetTimer
引数
戻値
説明

KillTimer
引数
戻値
説明
835デフォルトの名無しさん:2009/07/16(木) 16:54:43
>>834
ここに書き込みできるってことはインターネットが使えるってことでしょ。ググればいいじゃない。
SetTimer http://msdn.microsoft.com/ja-jp/library/cc411200.aspx
KillTimer http://msdn.microsoft.com/ja-jp/library/cc410876.aspx
836デフォルトの名無しさん:2009/07/16(木) 17:32:44
>>783
そういうことです
>>784でいいんですかね?
837デフォルトの名無しさん:2009/07/16(木) 17:43:12
人様の作ったソースを読んでいるんですが

typedef struct table_a{
int s_line;
int e_line;
}TABLE_A

int pp(TABLE_A table[], int x, char t);;

というのはtabel_aというタグ名の構造体を定義して
それをTABLE_Aという名前の構造体型として定義してるんですよね。

その後なんですが、int型のppという関数を作る所の
TABLE_A table[]とは何でしょうか?
引数にTABLE_A型の…table[]とは?
838デフォルトの名無しさん:2009/07/16(木) 17:45:31
引数に配列演算子がついた場合は、ポインタの意味。
つまり、

int pp(TABLE_A *table, int x, char t);

ってこと。
839デフォルトの名無しさん:2009/07/16(木) 17:46:18
int hoge[]の[]と同じ、配列。

ただし、そこは関数の仮引数なので、TABLE_A *tableと書いたのと同じこと。
840デフォルトの名無しさん:2009/07/16(木) 17:53:19
ポインタ表記じゃなくて、わざわざtable[]と書くのは、
「配列を渡すぞゴルァ」というプログラマの意思表示みたいなもんだね
841デフォルトの名無しさん:2009/07/16(木) 18:00:01
標準入出力でやりとりをするa.exeとb.exeがあって下のように起動します。
a.exe -run "b.exe -bar -baz"

無限ループに入ってしまうのでやりとりの内容を知りたいのですが下のshowpipeの様な形で使えるプログラムがあれば教えて下さい。
a.exe -run "showpipe b.exe -bar -baz"

もっと適切なスレッドがあれば誘導していただけませんでしょうか
842デフォルトの名無しさん:2009/07/16(木) 18:10:26
tee とか。
ってexeと書いてるからWinだったりする?
843デフォルトの名無しさん:2009/07/16(木) 18:10:56
ありがとうございます、レス読んでからもう一回検索してみたら
http://homepage3.nifty.com/mmgames/c_guide/15-06.html
こんなん出てきましたが、これのことですね。
>>838-840ありがとうございました。
844デフォルトの名無しさん:2009/07/16(木) 18:14:22
a.exeとb.exeは双方向でやりとりするのかな
teeだと一方向しか横取りできなくない?
845841:2009/07/16(木) 18:14:29
>842
windowsです
teeは聞いたことがありますが双方向のやりとりでも大丈夫なんでしょうか?
846デフォルトの名無しさん:2009/07/16(木) 18:19:56
双方向か、、まあc.exe作った方がはやいかもw
847デフォルトの名無しさん:2009/07/16(木) 18:25:08
a.exeが作れるなら、showpipe.exeを作るのもそんな難しくないはず。
ここは自作にちゃれんじだ。
848781:2009/07/16(木) 18:25:59
ポインタ使って基底クラスの値を操作するのってだめなんだろうか?
849デフォルトの名無しさん:2009/07/16(木) 18:32:00
>>781
なんだかとってもクソ設計に見えるのは俺だけではないだろう。
850841:2009/07/16(木) 18:36:39
a.exeはソースが公開されていないプログラムなのです・・・
851デフォルトの名無しさん:2009/07/16(木) 18:39:44
それは関係ないだろう
852841:2009/07/16(木) 18:52:51
>>851
自作にチャレンジしていますが
windowsAPIでのプロセス生成やファイルハンドルの扱いを全くやったことがないもので・・・
もしかして標準c/c++だけで何とかなりますか?
853デフォルトの名無しさん:2009/07/16(木) 18:55:00
#include <iostream>

using namespace std;

class A {
public:
int get() { return a_; }
protected:
static int a_;
};

int A::a_;

struct B : public A {
void set( int i ) { a_ = i; }
};

struct c : public A {
};

int main() {
B b;
c c;
cout << "before : " << c.get() << endl;
b.set( 10 );
cout << "after : " << c.get() << endl;
}
854デフォルトの名無しさん:2009/07/16(木) 19:05:02
>>836
> 文面からまるで、b と c が aでつながってるとでも思ってるかのように見えるんだが

インスタンスって理解出来てるか?
855デフォルトの名無しさん:2009/07/16(木) 19:05:21
>>852
標準Cだけだと、、、popen 使えればいけると思うけど試してない
856841:2009/07/16(木) 19:23:27
>>855
http://msdn.microsoft.com/ja-jp/library/96ayss4b(VS.80).aspx
_popenありましたが一方通行になりそうです
857デフォルトの名無しさん:2009/07/16(木) 19:50:54
C(UNIX)でTCP/IP関連のソースを組んでいるのですが、socket( ) を非ブロックにすることは出来ますか?
858デフォルトの名無しさん:2009/07/16(木) 19:51:04
char str[500];
char *x;
x = fgets(str,500,ファイルポインタ);

となっていて何も繰り返し処理が無い時って
xの中身[0]から[499]までは読み込んだファイルの1文字目から500文字目までがそれぞれ入るんですか?
もし配列が400しか指定してなくてファイルの文字数が500だった場合はどうなりますか?
859デフォルトの名無しさん:2009/07/16(木) 19:56:14
BCB5でSetTimerを使用してるんだが
はまってしまった

SetTimer(Handle, NULL, 3000, (TIMERPROC)TimerProc);


『E2235:メンバー関数は呼び出すかそのアドレスをとらなければならない』
というエラーが発生する。
第4引数が悪そうなのだがどうすればいい?

860デフォルトの名無しさん:2009/07/16(木) 19:57:07
>>858
メモリリーク
861デフォルトの名無しさん:2009/07/16(木) 20:19:19
>>858
xじゃなくて配列はstrでは?
xは何が入るんだっけ、fgetsの戻り値って何だ?
862デフォルトの名無しさん:2009/07/16(木) 21:07:01
>>858
500文字よりも前に改行があったら、その改行までしか読み込まない
改行がなかったら、499文字まで読み込んで、500文字目に '\0' を入れる
配列のサイズより長い文字列を読み込んだら死ぬ

>>859
そのTimerProcというメンバ関数の宣言にstaticを付ける
863デフォルトの名無しさん:2009/07/16(木) 21:12:25
>>859
そう言われるからには、TimerProcは非静的なメンバ関数なのだろう。

SetTimerに渡す関数は静的メンバ関数か非メンバ関数でないといけない。
引数のウィンドウハンドルから本来のオブジェクトを取得する
(Set/GetPropやSet/GetWindowLongPtrなど)などして、
改めて本来のメンバ関数を呼ぶという作りにするのがおそらく一般的。
864デフォルトの名無しさん:2009/07/16(木) 22:41:35
timerID(第2引数)がUINT_PTRだから、それ経由でthis渡すのもありか。
865デフォルトの名無しさん:2009/07/16(木) 23:31:44
>>861 バッファのポインタ。つまり

char* x;
x = str;

と同じ。ただし正常に終了しなかった場合NULLが返される

>>858 ただし改行までだった気がする。行末を見つけたら改行終端で終わる。
途中でEOFになると、NULL終端。 配列サイズをオーバした場合異常終了として戻り値がNULL。
866デフォルトの名無しさん:2009/07/16(木) 23:58:48
おまえら大嘘書き連ねるなよ。

fgets()は改行を見つけたらそこまで読み込みナル終端。
改行が見つからずにファイル終端になればそこまで読み込みナル終端。
バッファサイズをオーバーしそうならバッファサイズ-1バイト読み込みナル終端。

いずれの場合も戻り値はバッファを返す。
867デフォルトの名無しさん:2009/07/17(金) 00:11:28
>>866
char str[400]; // ←配列が400しか指定してなくて
char *x;
x = fgets(str,500,ファイルポインタ);

という顛末を予想してレスしたのかもしれない
868デフォルトの名無しさん:2009/07/17(金) 00:20:17
>>866
>いずれの場合も戻り値はバッファを返す。

その上の3行のいずれの場合も、という意味なら確かにバッファの先頭ポインタを返すが、
読み取りエラーなどの異常終了の場合はNULLが返るらしいぜ

http://www.cppreference.com/wiki/c/io/fgets
869デフォルトの名無しさん:2009/07/17(金) 00:20:34
だとしても、黙ってバッファオーバフローするので戻り値がNULLになることはない罠。
870デフォルトの名無しさん:2009/07/17(金) 00:21:19
>>868
「上記」いずれの場合も、だろ。
871デフォルトの名無しさん:2009/07/17(金) 00:22:47
>>870
だから「上記以外の場合」 を補足してんだろ。
872デフォルトの名無しさん:2009/07/17(金) 00:55:49
100点満点の答えを言ったつもりだから補足なんかされると悔しいんだよ。
873デフォルトの名無しさん:2009/07/17(金) 01:15:57
自分語りはいいから
874デフォルトの名無しさん:2009/07/17(金) 01:29:11
涙を拭けよw
875デフォルトの名無しさん:2009/07/17(金) 05:09:24
>>857
出来た気がします。何でするかはわすれてました。
876デフォルトの名無しさん:2009/07/17(金) 05:49:31

これも std::ostream& os = std::cerr;
これも std::ostream& os = std::ofstream(file);
OKなのに

なんでこれが std::ostream& os = strlen(file) == 0 ? std::cerr : std::ofstream(file);
だめなんですか?

1>c:\program files\microsoft visual studio 9.0\vc\include\ostream(584) : error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : private メンバ (クラス 'std::basic_ios<_Elem,_Traits>' で宣言されている) にアクセスできません。
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> c:\program files\microsoft visual studio 9.0\vc\include\ios(151) : 'std::basic_ios<_Elem,_Traits>::basic_ios' の宣言を確認してください。
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
1> コンパイラでのこの診断により関数 'std::basic_ostream<_Elem,_Traits>::basic_ostream(const std::basic_ostream<_Elem,_Traits> &)' が生成されました。
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>
1> ]
877デフォルトの名無しさん:2009/07/17(金) 05:51:13
キャストしたらいけた・・・
std::ostream& os = strlen(file) == 0 ? (std::ostream&)std::cerr : (std::ostream&)std::ofstream(file) ;
878デフォルトの名無しさん:2009/07/17(金) 05:52:46
c ? a : b はaとbの型が同じじゃないといけない
879デフォルトの名無しさん:2009/07/17(金) 05:57:24
キャストしたけどg++には怒られる

pipo.cpp:170: error: conversion to non-const reference type `struct std::ostream
&' from rvalue of type `std::basic_ofstream<char, std::char_traits<char> >'
880デフォルトの名無しさん:2009/07/17(金) 10:49:35
>>865
ということは
char型のstr[0]に一文字目の文字列が入り
xにはstr[0]のアドレス値が入るということですか?
881デフォルトの名無しさん:2009/07/17(金) 11:14:03
>>880
いいえ、
char型のstr[0]に文字列の一文字目が入り
xにはstr[0]へのポインタ値が入るということです。
882デフォルトの名無しさん:2009/07/17(金) 11:22:03
ポインタ値ってstr[0]のメモリアドレスじゃないの?
883デフォルトの名無しさん:2009/07/17(金) 11:33:43
そうかもしれませんし、そうではないかもしれません。実装依存です。
884デフォルトの名無しさん:2009/07/17(金) 11:34:32
ポインタ値は型情報つきのアドレス値。
ハードによってはアドレス値ですらない可能性も。
885デフォルトの名無しさん:2009/07/17(金) 11:35:42
昨日>>837で構造体について聞いたんですが、その後またわからない部分が出てきてしまいました。

typedef struct table_a{
int s_line;
int e_line;
}TABLE_A
TABLE_A *table;
// TABLE_A型(構造体)のポインタ型の変数を宣言

のすぐ後に
int line =1;
table[1].s_line=line;
TABLE_A *table
という使われ方をしているのですが、
typedef struct table_a[?]とか
TABLE_A table[]
のような宣言が無いのになぜ後ろで構造体配列のような使われ方をしているんでしょうか。
886デフォルトの名無しさん:2009/07/17(金) 11:40:34
>>885
単に簡単に書くためのお約束だから気にするな。
887至急伝授求む!:2009/07/17(金) 11:41:53
「error LNK2019: 未解決の外部シンボル _main が関数 ___tmainCRTStartup で参照されました」
なんだが、アプリケーションの種類以外の解決方法ある?

888デフォルトの名無しさん:2009/07/17(金) 11:42:37
>>885
table[1] は (*(table + 1)) のことです
読み替えてください
ポインタを通したアクセスをあたかも配列アクセスかのように書けるのは、C言語の仕様です
889デフォルトの名無しさん:2009/07/17(金) 11:52:46
>>887
Windows アプリケーションを
コンソールアプリケーションとしてビルドしたら
まあそうなるでしょうな。
>アプリケーションの種類以外の解決方法
何がしたいの?
890デフォルトの名無しさん:2009/07/17(金) 11:52:55
>>883-884
うーむ、難しくてピンと来ない…。
>>865の説明
char* x;
x = str;
と同じこと、というのは
x = &strじゃないからアドレスが代入されてるわけじゃないってことですよね。
ではもし「あいうえお」という文字列のファイルを読み込んだら
str[0]に'あ'、str[4]に'お'が入り、xには何が入るのですか?
*X = '●'なんてやってもstr[0]の中身は変わらない?
891デフォルトの名無しさん:2009/07/17(金) 11:59:59
x = &str; と x = &str[0]; は異なるが
x = str; と x = &str[0]; は同じ
なので *x = 〜; とやれば str[0] の中身が変わる
(ただし1個のcharに全角文字は入らないよ)
892デフォルトの名無しさん:2009/07/17(金) 12:21:39
>>888
つまり
TABLE_A *table;
int line =1;
(*(table + 1)).s_line=line;
ということですか。
tableはTABLE_A型のポインタ変数だけど*で通常変数モードに切り替わるんですよね。
tableという変数は1つしかないし配列ではないのに、+1というのはどう働くんでしょうか。
+1が+2や+3になった時、アクセス先はどこになるんでしょう。
893デフォルトの名無しさん:2009/07/17(金) 12:28:08
>>892
例えば、
TABLE_A hoge[100];
table = &hoge[0];
などとしていて、*table の後ろにもいくつか (この場合99個) の TABLE_A が存在している場合、
*(table + 1) で *table の次の TABLE_A (つまり hoge[1]) を指すことができる
894デフォルトの名無しさん:2009/07/17(金) 12:38:53
>>892
つーか、int ai[10]; int * pi = ai;と状況は同じだよ。少しは頭を使いなさいよ。
895至急伝授求む!:2009/07/17(金) 12:45:56
>>889
解決しました。

サンキュー
896デフォルトの名無しさん:2009/07/17(金) 12:55:06
>>893
この場合配列として宣言してなくても*(table + 1)とすると
table1個分先のアドレスに通常変数モードでtable[1]があるように振舞ってくれるんですか。

>>894
すみません、Cの知識一切ゼロで昨日から読み始めたので…。
*(table + 1) と int ai[10];int *pi = ai;が
どう関係あるのかよくわからないです。
897デフォルトの名無しさん:2009/07/17(金) 12:58:16
>>896
んじゃまず、ポインタと配列について勉強してきてくれ。構造体についてはその後だ。
つーか、初心者スレに逝け。
898デフォルトの名無しさん:2009/07/17(金) 13:02:37
>>885はメモリフォルトじゃないのかい?
どこにもメモリを確保している式なり文なりがないように見えるけど。

>>896
K&R第二版でも読んだら?
たった200ページで説明終了なので、
三日もあれば読み終わるよ。

899デフォルトの名無しさん:2009/07/17(金) 13:02:37
>>894って>>890へのレス番間違いじゃないの?
内容的にそんな気がするんだが…。
900デフォルトの名無しさん:2009/07/17(金) 13:06:33
マジな話、みなさんこちらへどうぞ。

C言語なら俺に聞け(入門篇) Part 50
http://pc12.2ch.net/test/read.cgi/tech/1246342847/
901デフォルトの名無しさん:2009/07/17(金) 13:10:37
>>898
すぐ後と書きましたがメモリ確保のくだりは特に疑問なかったので省略しました。実際には
table = malloc(sizeof(TABLE_A));

while(〜〜〜){
    table = realloc(table, (line + 1) * sizeof(TABLE_A));
があります。

>>900
誘導されます。
902デフォルトの名無しさん:2009/07/17(金) 13:19:04
配列とポインタに関する一連の疑問はここ読めば全くドンピシャな解説が書いてある。
http://homepage3.nifty.com/mmgames/c_guide/15-07.html
[]演算子についての質問はそもそも最初の>>837の質問に対する>>838の回答にも繋がる
903デフォルトの名無しさん:2009/07/17(金) 16:20:51
はじめて読むPentium マシン語入門編という本に出てきた
C言語の文がよく分からないので質問します

MOV EAX, [EBX+5]

[EBX+5]は「EBX(の内容)+5」をオフセットアドレスとするメモリの内容を表しています。

これをC言語で書くと

int Data = 100;

int *pData = &Data;

int Result;

Result = *(int *)((char *)pData + 5);

C言語ではint型ポインタに単に5を加えた場合、
5にint型のサイズ(4バイト)を掛けた値を加えるものとして扱われるからです。


こういう風に書かれているのですが

「5にint型のサイズ(4バイト)を掛けた値を加えるものとして扱われるからです。」
の意味が分からないです。

「Result = *(int *)((char *)pData + 5);で」
なんで(char *)が出てくるの分からないです。

C言語とかよくわからないのですが解説してほしいです。
904デフォルトの名無しさん:2009/07/17(金) 16:51:11
おー、説明すると長いよ。そこは読み飛ばしていいと思うぞ。
何より、C言語でもそんな書き方しないし。w

要するに、C言語のポインタというのは、単にアドレス値を格納するだけでなく
値を格納するのに何バイトを消費するかという情報も持っている。
こういうのを「ポインタ値」と呼ぶんだが、それはさておいて、
int* p、つまりint*型のpはint値を格納してあるアドレス値と、
そこから何バイト分を取り出してint値とみなすかを示している。
int型は4バイトなので、つまり、*pのように書くと、
pの持つアドレス値から4バイト分を取り出して、その情報をint値とみなすということになる。

次。p+5と書くと、pのアドレス値にint5個分が消費するバイト数を加算せよ、
という意味になる。つまり4バイト*5個で20バイトを足すわけだな。
一方、char型は1要素を格納するのに1バイトしか使わない。
char* pがあるとして、p+5と書くと、pのアドレス値にchar5個分が消費するバイト数を加算するから、
結局、1バイト*5個で5バイト分増加する。

んで、「Result = *(int *)((char *)pData + 5);」。
まずint*型のpDataをchar*型に変換する。
こうすると、保持するアドレスは一緒だが、指し示す値はchar型に変更される。
char*型であるpDataに5を加えるのだから、そのアドレスはちょうど5バイト分進む。
しかし、だ。これをこのまま*pDataのようにすると、
そのアドレスから1バイト分を取り出してchar値とみなしてしまう。
ほしいのはint値だ。だからもう一度pDataをint*型に変換する。
これにより、元のpDataから5バイト分アドレスが進んだpDataを
int*型として得ることが出来たことになる。
さぁ、あとは*をくっつけて(デリファレンスして)
その中身をint値として取り出そうじゃないか。

ちなみに、上記の話はすべて実装依存。
C言語の規格にはポインタがアドレスを格納するなどという話は一切でてこない。
メモリをどう管理するかはコンピュータによって異なるからね…。
905デフォルトの名無しさん:2009/07/17(金) 16:57:45
>>904
なげーよ。

>>903
Cは気にしないでいいよ。アセンブラはCより低レベルを扱うと言いたいだけだろうから。
906デフォルトの名無しさん:2009/07/17(金) 17:03:11
ちなみにアセンブラでも、

MOV ECX, [EBX+EAX*4]

みたいに4の倍数のオフセットが使えたりするでしょ。
あれも、こういったデータサイズの話に関係してるわけですよ
907903:2009/07/17(金) 17:14:42
>>904
非常に詳しい解説ありがとうございます。
C言語の本と併せて読んで理解したいと思います。

>>905
>>Cは気にしないでいいよ。アセンブラはCより低レベルを扱うと言いたいだけだろうから。
MOV EAX, [EBX+5]
これが
Result = *(int *)((char *)pData + 5);
になるのが全然理解できなくてすごく気になったのです。
908デフォルトの名無しさん:2009/07/17(金) 17:29:25
むしろこう書いたほうがよいのでは、と言う気がする。
Result = *(int *)((intptr_t)pData + 5);

intptr_tを知らないなら、適当にintかlongにでも読み替えてくれ。


909841:2009/07/17(金) 17:45:18
プログラム書いてみたんですが2,3うまくいってないところがあります
どこか貼るところありませんか(200行ぐらい)
910デフォルトの名無しさん:2009/07/17(金) 17:57:17
>>909
codepad
ttp://codepad.org/
に貼ってみろ。

個人情報が含まれないように気をつけてね。
911841:2009/07/17(金) 18:01:15
貼りました
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/9772.txt
2,3の問題というのは
・パイプからの読み出しがビジーウェイトになってしまう
・Ctrl-Cなどで元プログラムを終了させたときにReadFileから戻ってこれない
・Ctrl-Cなどで元プログラムを終了させたときに子プロセスを終了できてない?
などです

名前はteeっぽいのでexにしてみました
アドバイスあればなんでもお願いします

912841:2009/07/17(金) 18:02:34
>>910 ごめんなさい今度使ってみます
913デフォルトの名無しさん:2009/07/17(金) 18:35:38
>>904
解説をよく読んだらなんか分かったような気がします
分かりやすく丁寧な解説だったので勉強になりました。
重ね重ねありがとうございます。
914デフォルトの名無しさん:2009/07/17(金) 21:37:37
>>908
それは何バイトすすみますか
915デフォルトの名無しさん:2009/07/17(金) 22:31:11
int a[n][m]と宣言したとき

a[i][j] は *(*a + i*n + j) で代用できる

という認識は合ってますか?
916デフォルトの名無しさん:2009/07/17(金) 22:44:15
言いたいことはわかる。でも正しくは
*((int *)a + i * m + j)
だと思う
917デフォルトの名無しさん:2009/07/17(金) 22:51:03
>>916
キャストしてint *型のアドレスの足し算だと明示しないといけないんですね。
それと、mとnは間違えました。

回答ありがとうございます。
すごく気になってたので助かりました。
918デフォルトの名無しさん:2009/07/17(金) 23:07:46
915でも916でも大抵は問題ないだろうけど、
a[n][m]のそれぞれの添え字に沿って*(*(a + i) + j)とするほうがもっといいと思う。
919デフォルトの名無しさん:2009/07/17(金) 23:10:30
素直に a[i][j] って書こうよ
そう書きたくない何か特別な理由でもあるのけ?
920デフォルトの名無しさん:2009/07/17(金) 23:34:41
メモリ内の配置が(i * M + j)的なのか、(i + j * N)的なのかを知ってると、
a[i][j]をループで回すときCPUキャッシュにヒットしやすいプログラムが書ける
921デフォルトの名無しさん:2009/07/17(金) 23:47:35
>>920
それってコンパイラの最適化を頼りにしちゃダメなのかい?
922デフォルトの名無しさん:2009/07/18(土) 00:26:03
>>921
アクセスする順序にも意味があるのでは、と訝しんで最適化しないコンパイラのほうが多いと思う。

単純なケースなら並べ替えても問題ないと判断できるはずだけど、
例えばGCCでは最新の4.4で入ったばっかり。
ttp://d.hatena.ne.jp/pyopyopyo/20090418/p1
923デフォルトの名無しさん:2009/07/18(土) 00:31:49
きれいなソースだね
924デフォルトの名無しさん:2009/07/18(土) 01:29:48
ファイルから fileinput >> num で値を読み込んだ場合に、
"//"が文字列の先頭に入るとスキップして
さらに次の文字列を読み込むフィルタを作りたいのですが、
ifstreamにフィルタを加えるにはどのように記述したら良いでしょうか?
iostreamの場合なら以下のようにすれば、コンパイルが通ることが(なんとか)分かりました。

class IOStreambuf : public std::streambuf{/* フィルタ記述 */};
int main(){
  IOStreambuf iobuf;
  std::iostream ioinput( &iobuf );
  int num;
  ioinput >> num;
  return 0;
}

ifstreamの場合に以下のようにしてもコンパイルに失敗します。
この場合の簡単なフィルタの作り方をご教授いただけないでしょうか?
(とりあえず、コンパイルの通し方だけでも教えていただけないでしょうか?)

class FileStreambuf : public std::streambuf{/* フィルタ記述 */};
FileStreambuf filebuf;
std::ifstream fileinput( &filebuf );
fileinput >> num;
925デフォルトの名無しさん:2009/07/18(土) 08:11:08
926デフォルトの名無しさん:2009/07/18(土) 14:16:29
time_t time(time_t *t)
って何を意図してこんな形になってるの?

time_t* time(time_t *t)
なら渡したポインタに埋めてくれるんだろうと思うけどさ

927デフォルトの名無しさん:2009/07/18(土) 15:06:55
ポインタ型に-1を入れろと
928デフォルトの名無しさん:2009/07/18(土) 15:29:38
LISPっぽく書きたいから
929デフォルトの名無しさん:2009/07/18(土) 18:06:47
>>926
引き数はNULLでよいことに注意。
つまり、time_t time(void)でもよかったのだが過去との柵でtime_t time(time_t * t)となった。
930デフォルトの名無しさん:2009/07/18(土) 18:32:47
>>929
NULLでいいのは知ってる
互換性のためか。昔は構造体だったのかね。
931924:2009/07/18(土) 19:08:33
>>925
とても参考になりました。助かりました。ありがとうございます。
932デフォルトの名無しさん:2009/07/18(土) 22:29:46
ポンタってどういう意味でしょうか?
933デフォルトの名無しさん:2009/07/18(土) 22:55:20
きつねの名前か
934デフォルトの名無しさん:2009/07/18(土) 23:18:39
あるクラスが別のクラスをメンバ変数にしてる時に、このメンバ変数をpublicにしちゃってもいいんでしょうか?
クラス内の変数を変更するためにアクセサ用意するのも面倒だし、いいかなぁ〜と思ってるんですけど。
935デフォルトの名無しさん:2009/07/18(土) 23:20:44
普通ラッパーかます
936デフォルトの名無しさん:2009/07/18(土) 23:40:44
>>934
いいよ
無闇にアクセサメソッド付けてもデメリットしかない
937デフォルトの名無しさん:2009/07/18(土) 23:40:52
a1からh8なら縦横の位置を出して
qが入ると終了する。どうするの?
938デフォルトの名無しさん:2009/07/18(土) 23:41:53
65個switchすれば?
939デフォルトの名無しさん:2009/07/18(土) 23:51:39
int x = hoge[0] - 'a';
int y = hoge[1] - '1';
940デフォルトの名無しさん:2009/07/18(土) 23:59:42
>>935
それはsetterやgetterみたいなのとは違うんでしょうか?
>>936
リソースがきつきつな環境だから少しでもオーバーヘッドあることは減らしたいんですよ。
publicにしちゃおうかな。
941デフォルトの名無しさん:2009/07/19(日) 00:04:13
MSのMFCなんかだと、よくメンバ変数になってる構造体をpublicにしてますね
MFCとか参考にするな?こりゃまたしつれい・・・
942デフォルトの名無しさん:2009/07/19(日) 00:24:33
マンハッタン・フライド・チキンがどうしたって?
943デフォルトの名無しさん:2009/07/19(日) 05:44:14
>>933
普通タヌキだと思う
944デフォルトの名無しさん:2009/07/19(日) 11:11:35
カプセル化のためにとSet〜/Get〜とか書いてたけどさ、これ結局publicにしてんのと変わらないじゃ…と思うようになってきた。
945デフォルトの名無しさん:2009/07/19(日) 11:13:10
>>944
まぁ、publicよりはマシだと思う。
できれば、只の雪駄下駄ではなく意味のある名前にしてやればいい。
946デフォルトの名無しさん:2009/07/19(日) 11:17:46
>>944
947デフォルトの名無しさん:2009/07/19(日) 11:27:55
始めまして。最近、C++始めようと思っている初心者なんですけど、質問です。
皆さんオススメの、処理系ってありますか?教えて下さい
948デフォルトの名無しさん:2009/07/19(日) 11:28:01
たとえば、色のRGBAそれぞれをunsigned charで保持するクラスがあったとして、
いちいちGetRedとかGetBlueとかSetRedとかSetBlueとか書いてたら、
これ結局、自由に弄れるんだからpublicと変わらないんじゃ?と思うんだけどなぁって意味です。
949デフォルトの名無しさん:2009/07/19(日) 12:15:27
>>948
弄る前にチェックされるとか、弄った結果何も起こらないとか
スレッドセーフにするための同期が行われるとか、
そういうのがなければ、まあそうですね。
950デフォルトの名無しさん:2009/07/19(日) 12:28:23
単に値を保持するだけだから別にいいよね。
値を変えたからといってすぐに画面に反映させるわけじゃないし、スレッド使う予定もないし。
というわけで、publicでいこうと思います。
ありがとうございました。
951デフォルトの名無しさん:2009/07/19(日) 12:35:44
>>947 お勧めの処理系とか言われても、何をやりたいのかで変わって来るんじゃね?
言語は何かを成す為の道具なんだから

最終的に Windows上で動作するGUIなアプリケーション作りたいってんなら、最初から WindowsのVCでも使えばいいし、
Linux は詳しくないけど、そっちがいいならそっちの環境用意しないとだし

初心者なので最初はコンソールプログラムから、って話だとしても、最終的にどっちの環境で続けたいかで、
お勧めも変わって来るぜ。 もちろん途中から変更したっていいだろうけど
952デフォルトの名無しさん:2009/07/19(日) 12:36:13
むしろ、セッターゲッターになんの疑問ももたないやつのほうが、センスが足らないと思う。
953デフォルトの名無しさん:2009/07/19(日) 12:40:49
すいません。初めてc++をインストールしたのですが・・・・

初心者のためのサイトからコピペしたものをそのままペーストして

#include <iostream>

using namespace std;

int main()
{
cout << "Hello world." << endl;

return 0;
}
とデバッグし hello worldと出たのは良かったんですが
次に
#include <iostream.h>

void main()
{
cout << "ああ、";
cout << 20;
cout << "歳になると年金を・・・。" << endl;
}
とコピペをしてデバッグすると前回のhello worldがでるきりで

追加をしたり、新しいプロジェクトを作ったり、先のhello worldの作るときに使ったc++ファイルを
削除したりしたのですが、デバッグすると一向にhello worldのままです。

どうか解決方法を教えてください
954デフォルトの名無しさん:2009/07/19(日) 12:42:14
確かに単純な構造だったら意味ないしメンドクセーって思う気持ちもわかるが
将来のことを考えてアクセサにしたほうがいいと思うよ
955デフォルトの名無しさん:2009/07/19(日) 12:44:12
>>950
class Foo {
 private:
  int value;
  Bar *bar;
 public:
  〜略〜
  int getValue() {
   return bar->mod(value);
  }
};

getValueの中の処理は外からはブラックボックスなので、
こんな風に「何かの処理でモディファイされた値をさりげなく返す」みたいな事も
ゲッターなら簡単。 そして一箇所変更するだけで、これを利用している全てに影響を与える事が出来る。

直のメンバ変数を取り出す形で書いちゃってると、変更があった時、
それを使う箇所全てを書き直さなければならない。   ・・・・っていう観点もお忘れなく
956デフォルトの名無しさん:2009/07/19(日) 12:44:44
>>951
おまいさんにいうのもなんだが、gccならWin/Linux両立できるお


というわけで、個人的には msys + MinGW ( + vi) をよく利用する
が、初心者向けではない
957デフォルトの名無しさん:2009/07/19(日) 12:45:59
>>953
なんていうC++インストールしたのか教えて
958デフォルトの名無しさん:2009/07/19(日) 12:47:41
>>953
C++の何をインストールしたんだ?
VC++ならソリューションエクスプローラーのプロジェクトを右クリックで設定できる
”スタートアッププロジェクトに設定”になってないんじゃないの?
959デフォルトの名無しさん:2009/07/19(日) 12:48:25
>>953 二回目をコピペしたあと、コンパイルしてないとかそういう
960デフォルトの名無しさん:2009/07/19(日) 12:55:05
>>955
うーん、そういう用途はちゃんとprivateにしないといけないと思うよ。
でも、ポインタでも参照でもなく単に基本データ型なメンバ変数を操作するSet/Getなら
publicでもいいんじゃないかなっと思うわけなんだ。
961デフォルトの名無しさん:2009/07/19(日) 13:12:16
こういうときは、プロパティ構文のある言語は便利だと思うね。
さいしょはpublicなメンバ変数にしといて、不都合がおきたら
プロパティにすればいいじゃん、クラスを参照してるほうのソースはいじらずにすむんだしー。

でもそういう言語のユーザほど、けっこう「publicメンバ使うな」とかいうんだよなー。
もったいない。
962デフォルトの名無しさん:2009/07/19(日) 13:16:44
>>960
君の言ってることは逆も言えるよね
単純なアクセスもset/getも変わらないんじゃね?
っていうならpublicメンバ変数にこだわらずにset/getでもいいじゃない

とまあくだらん突っ込みはいいとして・・・
重要なのは『後で変更するかもしれない』ということだよ
たとえば後で参照回数を測定したくなったとしたらどうする?
ソースの該当箇所を全部探して書き換えるのはかなり大変
でも最初からアクセサを用意しておけばこの変更に楽々対応できる
アクセサに1行加えるだけだからね
もちろん参照回数以外の変更にも有効だ

もちろん生でアクセスする明確な理由があるなら生でもいいかもね
もう絶対に変更はしないことが保障されてて
inlineにしても気になるぐらい遅くなって
set/getをタイプするのがたまらなく苦痛だ
とかいうなら生でもいいかもしれない
963デフォルトの名無しさん:2009/07/19(日) 13:18:23
>>957-959

すいません自己解決できたみたいです。。どうもソリューションのソースファイルに2つ、cppファイルがあったとき
前回のcppファイルのデバッグが優先的に反映されるようになっていたみたいです。
本当に申し訳ありませんでした。
964デフォルトの名無しさん:2009/07/19(日) 13:29:42
>>963
君はきっと、VCのスレを覗いて来た方がよさそうだ。

>>962
>inlineにしても気になるぐらい遅くなって
クラス内に書くような雪駄下駄に関して言えば、inline指定は無意味。

>>960
どうせなら、publicにした方がいいと思った具体例を出してみなよ。
他人の意見を聞いてみるのもいいもんだと思うよ。
965デフォルトの名無しさん:2009/07/19(日) 13:35:11
RGBとか座標とか、小物のクラスはpublicでいいし、
普通のクラスでセッターゲッターがやたらとあったら、設計がおかしい。
966デフォルトの名無しさん:2009/07/19(日) 13:40:16
自分の場合、雪駄では少なくとも入力値がおかしくないかチェックを入れることが多くて、
本当にただ代入するだけのセッタってあまり書いた覚えがない。
967デフォルトの名無しさん:2009/07/19(日) 13:43:50
座標値なんかも、例えばxとyを常に別々に扱うわけはないからなぁ。
メンバ変数を公開しつつ、void set(int x, int y)なんて雪駄を用意するのもあれだしね。
968デフォルトの名無しさん:2009/07/19(日) 13:47:21
>>964
メンバ変数を基本データ型で持つクラスがあった時
たとえば、
calss Point{
private:
 int x;
 int y;
public:
 void setX(int x){ this->x = x; }
 void setY(int y){ this->y = y; }
 int getX(void)const{ return x; }
 int getY(void)const{ return y; }
};
みたいなのがあったとして、setでは特に制限もなく代入して、getでは単に返すだけ。
クラス自身は本当に値を保持するだけで何もしない。
privateにしてset/getしてるけど、してることは構造体のメンバに代入してるのと一緒じゃんって思ったの。
じゃあ、set/getはオーバーヘッドになるだけで邪魔なんじゃ…
いっそpublicにしてしまうか?←いまここ

ってな具合です。
969デフォルトの名無しさん:2009/07/19(日) 13:52:45
それくらいだったら、自分もいわゆる構造体にするなあ。
全メンバpublic(って書くのも面倒だからstruct)、
せいぜい、利便性のためコンストラクタを書くくらい。
970デフォルトの名無しさん:2009/07/19(日) 14:22:49
オブジェクト指向のカプセル化の概念を壊す

新人プログラマがかってにpublicにし、
熟練プログラマからいやがらせをうけてもしらんぞ

オブジェクト指向?なにそれうまいの?だったら Javaは無理
C/C++ で構造体で生き延びろ
971デフォルトの名無しさん:2009/07/19(日) 14:28:04
>>970
それさ、カプセル化と情報隠蔽がごっちゃになってない?
郷に入れば郷に従えでJavaでは雪駄と下駄を使うでしょ。

あれ、カプセル化は情報隠滅も含むもんなの?
972デフォルトの名無しさん:2009/07/19(日) 14:29:51
同じじゃないのか?
インターフェースと実装を分離して隠すのがカプセル化だろ
973デフォルトの名無しさん:2009/07/19(日) 14:31:33
>>970
全部のメンバにset/getをつけてないことを祈る
ウチのプロジェクトみたいになorz
974デフォルトの名無しさん:2009/07/19(日) 15:40:11
実装を考える時って、あくまで 「必要だからそうする」 っていう観点を忘れてはいけない気がする。

丸見えpublicなクラス(むしろ構造体)があった時、それを見たら
「あぁ、これはきっとただの構造体なんだろうな」 と想像がつくし、
全部 getter/setter が定義されてたら、「あぁ、きっと間に何か処理挟む可能性があるんだろうなぁ」 とか思う。

座標とサイズを保持する Rectangle とか、座標を表す Point とか、要は 「ロジック(機能)よりもデータ」 の立場に近い物は
クラスというより構造体的で、メンバは丸見えpublicで構わないし、

何かの集合をイメージしてはいるけど、そこにビジタやストラテジが介入するような 「データよりもロジック」 な
コンポジションイメージのクラスは、やっぱ値の保障や加工をする事があるので、getter/setter にした方がいい
・・・・ような気がする。 個人的な意見
975デフォルトの名無しさん:2009/07/19(日) 15:48:17
まったくもってそのとおりだ。興奮した。
976デフォルトの名無しさん:2009/07/19(日) 16:14:20
本気モードで作るときはちゃんとカプセル化しとけ。
今は直触りで良くても、あとで困るときがある。
977デフォルトの名無しさん:2009/07/19(日) 16:55:19
ここら辺の話は、”カプセル化 隠蔽”でググったら結構出てくるね。
カプセル化=隠蔽だったり、カプセル化≠隠蔽だったりで解釈?が違うのか。
978デフォルトの名無しさん:2009/07/19(日) 17:02:59
ただhogeって変数に、gethoge/sethogeって名前つけちゃうのはダメだと思う。
もっと意味のある名前の関数にしる、と統合環境依存症の奴には言いたい。Javaとかで。
979デフォルトの名無しさん:2009/07/19(日) 17:10:12
しかしJava Beans の命名ルールだと、get○○ set○○ と付けなさい、なんだよな
付けなさいって言うか、リフレクションで自動化する為のルールと言うか
980デフォルトの名無しさん:2009/07/19(日) 17:16:56
プロパティが使えれば面倒なせったげった考えなくても良さげですが
標準C++は使えないんですか
981デフォルトの名無しさん:2009/07/19(日) 17:23:03
プロパティってどの言語の話?
982デフォルトの名無しさん:2009/07/19(日) 17:31:48
C#やVBが持ってるようなプロパティ機構の意味なら、むしろそんな物ある方が独特

てか C++でもオペレータオーバロード使えば似たような処理出来なくも無い
やる必要があるかどうかは別として
983デフォルトの名無しさん:2009/07/19(日) 17:42:03
プロのパンティよりギャルのパンティ。
984デフォルトの名無しさん:2009/07/19(日) 18:05:19
>>976
べつに困らないよ。
RGBとか座標とかで、直でいじって問題おきたことがない。
985デフォルトの名無しさん:2009/07/19(日) 18:19:30
ひとりでやる分には
どうでもよい
986デフォルトの名無しさん:2009/07/19(日) 18:25:16
チームでも困らない。
987デフォルトの名無しさん:2009/07/19(日) 18:26:24
>>986
それは周りが関与してないだけ
988デフォルトの名無しさん:2009/07/19(日) 18:29:04
RGBも座標も、纏めてsetすることはないのだろうか。私はset(int x, int y)がないと面倒で嫌なのだが。
つーか、publicで勝手に触られると 最適化もしにくくなるし。
# RGBは元々メンバを分けることが少ない気がするけどね。
989デフォルトの名無しさん:2009/07/19(日) 18:30:45
>>987
MFCでもJavaでも座標クラスはメンバをpublicにしてるけど、それが問題だって話は聞いたことがない。
990デフォルトの名無しさん:2009/07/19(日) 18:32:32
>>989
たとえば?
991デフォルトの名無しさん:2009/07/19(日) 18:43:14
>>990
たとえばって、なにのたとえば?
992デフォルトの名無しさん:2009/07/19(日) 18:45:02
>>991
座標クラスの例
993デフォルトの名無しさん:2009/07/19(日) 18:47:11
>>992
JavaやMFCの座標クラスなんて、自分で見ればいいじゃん。
994デフォルトの名無しさん:2009/07/19(日) 18:58:48
C++標準の中にもあるじゃないか、pairというもろだし構造体が。
値の集合としての構造体は問題ない。
C++ Coding Standardsにもそう書かれている。
サッター先生より偉い奴はここにはいないだろうから、間違いない。
995デフォルトの名無しさん:2009/07/19(日) 19:38:09
pairについては分からないが
MFC,Javaでの座標の例は?
ていうか日本語分かる?
996デフォルトの名無しさん:2009/07/19(日) 19:42:18
あとで困る例が先じゃないの。
997デフォルトの名無しさん:2009/07/19(日) 19:43:31
「MFCやJavaの座標クラス」って、例をださないといけないくらいいっぱいあるのか?
まあ「Javaの」って言ったら、野良クラスとか含まれるって解釈もあるけど、MFCの
ほうは間違いようがないだろ。
もちろんJavaのほうもJDKのやつな。
998デフォルトの名無しさん:2009/07/19(日) 20:16:52
>>996
あー >>990 の「たとえば?」は >>989の「問題だって話は聞いたことがない」のことを
聞いてるのかな?

「問題だって話を聞いたことがある」に「たとえば?」って問うならわかるけど、
「問題だって話は聞いたことがない」にたとばってって聞いても例は出しようがないな。

それともやっぱり >>992 のとおり、「MFCやJavaの座標クラスの例」を聞いてるのかな?
pairも知らないし、「MFCやJavaの座標クラス」をなにか別のものと勘違いしてるのかね。
999デフォルトの名無しさん:2009/07/19(日) 20:17:10
MFCの座標クラスも妙に設定用のメソッドが用意されているよね。
>988の言うのはそのことだろうけど、にも拘らずMFCのメンバはpublicなわけだ。
1000デフォルトの名無しさん:2009/07/19(日) 21:37:54
1000
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。