08/05/15 12:46:16
平均点の高い順に並べ替えて表示するプログラムを作りたいのですが、結果が表示されません;
どこをどのように直したらいいか教えてください。お願いします。
URLリンク(kansai2channeler.hp.infoseek.co.jp)
32:デフォルトの名無しさん
08/05/15 12:55:41
>>31
sort()とやらはgccの拡張機能である、関数内関数定義を行っているだけで呼び出していないから。
他にもいろいろ突っ込みどころだらけだが……
33:デフォルトの名無しさん
08/05/15 12:57:32
なんか、ロジックをいろいろ寄せ集めただけっぽいな。
ソートを自分で書くのが目的なら、渡すデータ型に注意だ。
34:7
08/05/15 13:00:59
>>30
そういうことですか!!
確かに質問するにあたって情報が足りなかったですね。
warningが発生するHogehoge最小ソースは
class Hogehoge
{
public:
Hogehoge(){};
virtual ~Hogehoge(){};
};
です。
35:31
08/05/15 13:05:37
>>32
main関数の前に
void sort(int *p,int n);
を付け加えました。
他に間違ってるところってどこですか?
36:デフォルトの名無しさん
08/05/15 13:08:23
>他に間違ってるところってどこですか?
たくさん。あり過ぎて指摘する気にもならん。
まぁ、作った関数は呼ばなきゃ意味がないことくらいは判るだろうから、
後はコンパイラのエラーメッセージをよく読んで順に潰せ。
そうそう、gccを使っているだろうから、gcc file.c -ansi -Wall -pedanticすることをお勧め。
37:32
08/05/15 13:10:43
>>35
私の指摘をちゃんと読んでますか? 「関数呼び出し」って、理解できますか?
38:デフォルトの名無しさん
08/05/15 13:11:36
class HogeHoge
{
public:
HogeHoge(){};
virtual ~HogeHoge(){};
};
class Foo
{
public:
static HogeHoge hogehoge;
};
int main ()
{
Foo myClass;
return 0;
}
問題なく通るけど…
39:38
08/05/15 13:14:35
VC++2005EE
40:32
08/05/15 13:15:08
>>34
>38だとhogehogeの実体を参照しないからエラーにならないかと。
Hogehogeだけ抜き出さずに、実際にそのエラーが出るソースを作って貼ってみては?
41:7
08/05/15 14:08:53
さらに色々調査してみたところ、ソースコードというよりも環境が怪しい気が
してきました。
もう少し調べてみます。
42:デフォルトの名無しさん
08/05/15 14:10:17
もうこなくていいよ
43:デフォルトの名無しさん
08/05/15 15:58:58
>>7
C4251でググったりはしたよね?
44:デフォルトの名無しさん
08/05/15 16:09:49
> HogeHoge(){};
> virtual ~HogeHoge(){};
セミコロン要らないだろ
45:デフォルトの名無しさん
08/05/15 17:54:36
struct point{
double x;
double y;
};
struct point q[200];
memcpy(q,p,(n+1)*sizeof(struct point));
これってどういう事をやってるんですか?
46:デフォルトの名無しさん
08/05/15 18:02:55
pが指す所から(n+1)*sizeof(struct point)バイトqの所にコピーしてる
47:デフォルトの名無しさん
08/05/15 18:08:27
>>45
恐らくはstruct point * pがあるとして、
先ずはpoint構造体の要素数200の配列qを宣言している。
続いてその配列qに、point構造体(n+1)個分のデータを配列pからコピーしている。
この部分は、for (int ic = 0; ic < n + 1; ++ic) q[ic] = p[ic];とほぼ同等。
48:デフォルトの名無しさん
08/05/15 18:19:35
すいません。
int func(int n,struct point p[],double d){
struct point q[200];
;
memcpy(q,p,(n+1)*sizeof(struct point));
}
みたいに構造体が引数で渡されています。
49:デフォルトの名無しさん
08/05/15 18:21:52
>>48
「構造体」ではなく、「構造体へのポインタ」ね。つまりは、>47。
50:デフォルトの名無しさん
08/05/15 18:24:31
なるほどわかりました。
実際のpの大きさがソースを書くときには不定なので、
for文での代入をしていないってことでしょうか?
51:デフォルトの名無しさん
08/05/15 18:27:58
>>50
いや違う。pの大きさは、常に一定だ。何故ならpはポインタ変数だからだ。
pが指す領域のサイズについてはnに依存するわけだが、forループでも勿論巧くコピーできる。
では何故memcpy()を使うかというと、保守性よりも(見かけ上の)効率を優先したか、単に習慣か、
書いた人間にでも聞かないと判らないだろう。
52:デフォルトの名無しさん
08/05/15 18:29:13
for文で1個ずつでもいいけど、丸ごと全部いっぺんにやったほうが早いべ
53:デフォルトの名無しさん
08/05/15 18:42:40
いいえ、一概には言えません。まともなコンパイラにまともに最適化させてやれば恐らくは、目に見える速度差はないでしょう。
54:デフォルトの名無しさん
08/05/15 18:46:59
書く量だって少ないし、コーディングも早いだろ。
55:45
08/05/15 18:49:17
いろいろ教えていただきありがとうございました。
56:デフォルトの名無しさん
08/05/15 19:00:21
>>54
>memcpy(q,p,(n+1)*sizeof(struct point));
39文字
>for(int i=0;i<n+1;++i)q[i]=p[i];
32文字
57:デフォルトの名無しさん
08/05/15 20:30:03
VC++でインラインアセンブリを使うとき、
疑似命令によくある、生データを直接コードに埋め込む事って、どのようにすればいいのですか?
テーブル参照のようなことを仕様と思ったのですが、やり方がよくわからなくて…
58:デフォルトの名無しさん
08/05/15 20:34:29
>>53
逆に言えば
memcpyみたいな動作をする命令があるから、
まともでない(古い)コンパイラだとfor使うより遙かに速く動作する
そういう意味では書く人の習慣の影響が強いが
59:デフォルトの名無しさん
08/05/15 22:04:53
だんだんコンパイル速度が遅くなってきたので、参照箇所の
多いクラスにPimplを導入しようかと思ってるのですが、Pimplに
すると問題のあるケースなんてのもあるんでしょうか?
60:デフォルトの名無しさん
08/05/15 22:11:37
>>56
>memcpy(q,p,(n+1)*sizeof(*p));
29文字
61:デフォルトの名無しさん
08/05/15 22:27:54
std::copy(p,p+n+1,q);
21文字
62:デフォルトの名無しさん
08/05/15 22:45:30
>>59
pimplを経由することによる性能上のオーバーヘッド
63:デフォルトの名無しさん
08/05/15 23:02:23
>>59
メモリ確保のオーバーヘッドと、メモリ確保に失敗する可能性の増加。
64:デフォルトの名無しさん
08/05/15 23:23:16
>>62,63
なるほど。速度が重要な物や大量に生成される物には
避けた方が良さそうなんですね。
65:デフォルトの名無しさん
08/05/15 23:24:01
>>59
仮にPimplによる問題が出ても、
大した手間無く対処出来るから気にする必要無いよ。
66:デフォルトの名無しさん
08/05/15 23:36:11
>>59
相互参照の必要な場合が多いとソースが汚く見えるようになる。
67:デフォルトの名無しさん
08/05/16 02:57:03
すいません、質問お願いします。
独習Cで勉強しているのですが、月での実効体重だす問題で関数を作ったのですが
float moon(void)
{
float weight;
printf("体重を入力してください:");
scanf("%f",&weight);
return weight*(17/100);
}
という関数を作った時に
「return weight*17/100」や「return weight*0.17」時は正しい値を返してくれるのですが、
自分が分かりやすいように式を()で囲うと正しい値を返してくれずに0.00000という値が返ってきます。
理由がわからないのですが、どなたか分かる方教えて下さい。
68:デフォルトの名無しさん
08/05/16 02:59:30
すいません、>>67ですが、環境はDev-C++です。
69:デフォルトの名無しさん
08/05/16 03:01:40
intをintで割ったときでも値はint。つまり(17/100)は小数点以下が切り捨てられて0になる。
(17.0/100)とかならOK
70:デフォルトの名無しさん
08/05/16 03:04:13
>>67
17と100が整数だから、17 / 100の結果も整数(切り捨てで0)になってしまう。
weight * 17 / 100と書いたときには、(weight * 17) / 100と扱われ、
weight * 17がfloat型で結果を返し、それに整数100を掛けても
やっぱりfloat型になるのでうまくいくという具合。
逆にいえば、17などをfloat型にすればいいわけで、
return weight * (17.0f / 100.0f);とすればうまくいく。
71:デフォルトの名無しさん
08/05/16 03:09:58
>>69
>>70
なるほど、型が大きいほうに合わせられるっていうのは数値だけの計算にも当てはまるんですね。
変数だけしかそういう風にならないと勘違いしていました。
非常に分かりやすい説明ありがとうございました。勉強になりました。
72:デフォルトの名無しさん
08/05/16 11:46:56
直書きの数値にも型はあるんだぞ
73:デフォルトの名無しさん
08/05/16 11:58:44
リテラルと言いましょう
74:デフォルトの名無しさん
08/05/16 13:09:38
すまん、用語には疎いもんで・・・
75:デフォルトの名無しさん
08/05/16 20:39:22
>>20
>・templateクラスにして継承関係を逆にする
> ※ template<class T> class base : T {};
これ、よく分からないので具体例あげてくれるとありがたい。
76:デフォルトの名無しさん
08/05/17 03:21:50
struct A {
A() { f(); }
virtual void f() = 0;
};
struct B {
virtual void f(){}
};
を
template<class T>
struct X : T {
X() { f(); }
};
struct Y {
void f() {}
};
typedef X<Y> Z;
77:デフォルトの名無しさん
08/05/17 03:22:49
修正
> X() { f(); }
X() { T::f(); }
78:デフォルトの名無しさん
08/05/17 09:58:03
質問です
先日基底クラスのデストラクタを仮想にし忘れ、メモリーリークというお約束のミスをやってしまいました。
この手のミスを無くしたいのですが、warningを出させる方法や、チェックツールなどはないでしょうか?
環境はVS6.0です。
仮想関数テーブルへのアクセスによるオーバーヘッドは現状気にしていないので、全てのクラス関数を仮想にしたいのですが、たまにつけわすれてしまうのです。
79:デフォルトの名無しさん
08/05/17 10:04:15
初心者です。
C++を学ぼうと思ってるんですが良い参考書orWebページはありますか?
80:75
08/05/17 10:09:49
>>76-77
ありがとう。
ただこの方法だと元々の継承関係が失われないかい?
(76はミスタイプと思うが、元々はstruct A : B)
質問者は継承関係は維持したいと思うけど。
81:75
08/05/17 10:13:13
>>80
というか継承と同じことをテンプレートで実現するってことかな。あってる?
82:デフォルトの名無しさん
08/05/17 13:28:04
>>78
「メモリリーク 検出」とかでググれば解説してるサイトがいっぱいでてくる
83:デフォルトの名無しさん
08/05/17 13:55:08
>>78
デストラクタを仮想にした基底クラスを作って、クラスを作るときに必ずそれを派生して使うようにすれば忘れることはない。
84:デフォルトの名無しさん
08/05/17 13:57:15
>>83
それを忘れないようにするためって話じゃないのか?w
85:デフォルトの名無しさん
08/05/17 13:58:33
>>83
デストラクタの話ね。
86:デフォルトの名無しさん
08/05/17 14:43:18
>>83はルート基底クラス(C#とかのObject)を用意することで、
個別にvirtualを書かなくて済むようにした方が良い、って意味なのでは?
でもそしたら今度は、それ継承するのを忘れない方法は?
って話になりそうだけど。
87:デフォルトの名無しさん
08/05/17 14:46:51
クラスを定義するときに専用のマクロを使うことにするとか
88:デフォルトの名無しさん
08/05/17 14:57:06
>>87
それを忘れないようにするためって話じゃないのか?w
89:デフォルトの名無しさん
08/05/17 15:02:42
>>88
忘れにくさという点で、
>>78より>83
それより>>87
と良くなっているように見えるけど。
90:デフォルトの名無しさん
08/05/17 15:10:27
コピペ煽りに律儀に答えなくても
91:デフォルトの名無しさん
08/05/17 15:42:28
class NewClass : public Object
の : public Objectを書かなかったらやっぱりバグるわけだしなー
それじゃ意味ないだろう
継承しなければコンパイルエラーになるようにできるなら、別だが。
92:デフォルトの名無しさん
08/05/17 16:13:22
なんでループしてんの?
93:デフォルトの名無しさん
08/05/17 16:19:14
struct Object{virtual ~Object(){};};
#define STD_STRUCT(NAME) struct NAME : public virtual Object
#define STD_CLASS(NAME) class NAME : public virtual Object
STD_CLASS(ClassA) {
public:
~ClassA(){std::cout << "~ClassA" << std::endl;}
};
STD_CLASS(ClassB), public ClassA {
public:
~ClassB(){std::cout << "~ClassB" << std::endl;}
};
void f()
{
ClassA* p = new ClassB();
delete p;
}
94:デフォルトの名無しさん
08/05/17 16:27:10
そしてそのマクロを使うのをつい忘れるわけですね、わかります
95:デフォルトの名無しさん
08/05/17 16:30:03
>>94
>>89
5レス前すら読めない人はこのスレに必要ありませんよ
96:デフォルトの名無しさん
08/05/17 16:31:46
いや、お前ら質問者の意図無視しすぎだろw
97:デフォルトの名無しさん
08/05/17 16:33:46
ツールでなんとかしたいと言ってる人間に、忘れないようにマクロを使いましょうってどんな返事なんだ
俺は必要としたことないから知らんが、書式チェックツールくらいないのか?
98:デフォルトの名無しさん
08/05/17 16:36:19
virtual忘れをチェックしてくれるツールくらい自分作ればいいんじゃね
デストラクタは先頭に ~ が付いててわかりやすいから、
その前にvirtualが付いてるかどうかくらい簡単に判定できそう
そもそもデストラクタを書いてない場合は役に立たないが・・・
99:デフォルトの名無しさん
08/05/17 16:38:42
>>96
>>78を読む限り、まずミスを無くしたい、という目的があって、
その方法として警告、チェックツール「など」、
と手段の例を挙げているので、
同じく、ミスを無くす/減らす方法を書いてるレスが
意図を無視してるようには見えないけど?
100:デフォルトの名無しさん
08/05/17 17:06:19
とりあえず、抽象型へのアップキャストは極力控えて、
総称型プログラミングを覚えた方がいいと思った。
101:デフォルトの名無しさん
08/05/17 17:08:30
>>100
実行時ポリモーフィズムが必要な場合はどうするの。
102:デフォルトの名無しさん
08/05/17 17:10:55
だから極力控えて、って・・・。
103:デフォルトの名無しさん
08/05/17 17:31:36
静的な方が安全というのは分かるが、
export のない C++ でジェネリックばっかやってると
コンパイルが重くて現実的じゃない事も。
104:デフォルトの名無しさん
08/05/17 21:16:08
>>98
そしてそのツールでチェックするのをつい忘れるわけですね、わかります。
105:デフォルトの名無しさん
08/05/17 22:34:11
>>104
make使うならMakefileに組み込めばおk。
総合環境なら・・・ カスタムビルドステップ?
106:デフォルトの名無しさん
08/05/17 22:42:35
>>104
最悪、考え方としてはおかしくなったときにチェックすればいいわけだし。
107:デフォルトの名無しさん
08/05/17 23:08:54
あれ?ちょっとずれるが
なんかの統合環境で、virtualな関数をオーバーライドする時にvirtualつけておかないとワーニング出すって設定できたよな?
これはvirtualですよー、わかってますかー?って意味合いで
108:デフォルトの名無しさん
08/05/18 00:36:52
微妙に宣言間違えて、いつの間にか別の仮想関数が作られちゃうのを防ぐ方法ってないかな。
delphiならviryualで新しく作って、overrideでオーバーライドするから間違えたらエラーになるんだがなぁ
109:デフォルトの名無しさん
08/05/18 00:37:37
virtualだな
110:デフォルトの名無しさん
08/05/18 00:41:27
override は最近の言語によく取り入れられているね。
あれはいい仕様だと思う。
111:デフォルトの名無しさん
08/05/18 01:18:54
>>107
それは余計なお世話な気もするな。コーディング規約レベルだと思う。
112:デフォルトの名無しさん
08/05/18 01:25:16
いんや。
仮想関数じゃないつもりで関数追加して泣きを見るのを防止できる。
113:デフォルトの名無しさん
08/05/18 09:07:18
なんにしろON/OFFできりゃいいんだよな
overrideはいい仕様だ
114:デフォルトの名無しさん
08/05/18 11:38:49
Java みたいに問答無用で仮想関数にする言語は
typo で泣くことになる。
115:デフォルトの名無しさん
08/05/18 11:52:39
そうした事もあって、C#では明示的にoverrideする必要になりましたとさ
116:デフォルトの名無しさん
08/05/18 12:19:28
それにならって、javaもoverrideをチェックする
アノテーションが用意されました。
117:デフォルトの名無しさん
08/05/18 13:19:39
そしてC++はほったらかしと。
118:デフォルトの名無しさん
08/05/18 13:30:36
C++ は互換性を異常に気にするからな。
119:デフォルトの名無しさん
08/05/18 13:40:20
override付きのときだけチェックしてくれれば良いんだけどなぁ。その他(virtual付き/何もなし)の時は今まで通りで。
120:デフォルトの名無しさん
08/05/18 13:42:08
それはあんまり override の価値がない気が
121:デフォルトの名無しさん
08/05/18 13:42:41
override が無い時に警告出してくれるならいいけど