【初心者歓迎】C/C++室 Ver.63【環境依存OK】
>>1 乙です
前スレが終わってしまったのでもう一度貼ります
997 名前:デフォルトの名無しさん[sage] 投稿日:2009/01/09(金) 19:53:52
失礼します
コンストラクタについての質問なのですが
C → B → A の順で自身のコンストラクタを呼び出すことは可能でしょうか?
可能であればどのように書けばよいか教えてください
下の例は簡略化しているので全パターン書いても大したことはないですが
実際のものはもう少し引数が増えます
class hoge
{
int m_foo, m_bar;
public:
hoge(int foo, int bar) : m_foo(foo), m_bar(bar){} // A
hoge(int foo) : hoge(foo, 100-foo){} // B
hoge(void) : hoge(rand()){} // C
};
※これはコンパイルエラーになります
C++0x ではできるようになるんだった気がするが、今は無理。 初期化用の関数を作るといいよ。
そのパターンだけだったらこれで行ける hoge(int foo = rand(), int bar = 100 - foo) : m_foo(foo), m_bar(bar){}
>>3 無理なのですね
分かりました。ありがとうございます
ということは、代替手段としては
次のようにするしかないということですね
class hoge
{
int m_foo, m_bar;
void init(int foo, int bar) { m_foo=foo; m_bar=bar; }
void init(int foo) { init(foo, 100-foo); }
void init(void) { init(rand()%101); }
public:
hoge(int foo, int bar) { init(foo, bar); } // A
hoge(int foo) { init(foo); } // B
hoge(void) { init(); } // C
};
まあ大体そうだな わざわざinitをオーバーロードする必要はないと思うけど
>>4 コンパイルエラーになりました
g++ -c -o hoge.o hoge.cpp
hoge.cpp:7: error: `foo' was not declared in this scope
make: *** [hoge.o] Error 1
コンパイラのバージョンはこれです
g++ (GCC) 3.4.5 (mingw special)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8 :
7 :2009/01/09(金) 21:00:29
ソースファイル忘れてました #include<cstdlib> class hoge { int m_foo, m_bar; public: hoge(int foo = rand(), int bar = 100 - foo) : m_foo(foo), m_bar(bar){} };
あれ?本当だそこでfoo見えてないのか 知らんかった
引数はデフォルト引数にはできんぞ
もうひとつ質問です 下側のクラス hoge の三番目のコンストラクタを実現する方法はありますか? あるとすれば、どのように書けばいいのでしょうか? #include<cstdlib> class base // このクラスは変更できないものとする { int m_foo, m_bar; public: base(int foo, int bar) : m_foo(foo), m_bar(bar) {} }; class hoge : public base { public: hoge(int foo, int bar) : base(foo, bar) {} hoge(int foo) : base(foo, 100-foo) {} hoge() : base(int tmp=rand()%101, 100-tmp) {} // このコンストラクタはどのように書けばよいですか? };
この場合は hoge(int foo = rand() % 101) : base(foo, 100 - foo) { } でいいと思う。
私にc++の極意を教えてください
__stdcall
おぉ
17 :
デフォルトの名無しさん :2009/01/09(金) 22:54:18
(int*)p->num; (int*)(p->num); ((int*)p)->num); これは全部同じですか? if( a==b && a==c) if( (a==b) && (a==c) ) これも同じですか?
>>17 はい全部同じです
優先順位ぐらい自分で調べましょう
>>18 違うwwwww
3行目は明らかにエラーだろwwwwww
18の2行目と3行目が逆だったら理解できるのだが……。
そもそも括弧のネスト壊れてるし
25 :
デフォルトの名無しさん :2009/01/10(土) 01:01:57
strcmpの文字列比較の結果が0,1,-1以外の時ってありますか??
新スレ早々ワロタw
>>25 strcmp の戻り値は 正数 か ゼロ か 負数 かのいずれかなので
1 とか -1 であることは保証されてないです
そもそもに、0,1,-1ではなく、0,正,負を返すとしか定義されてない?
かぶった
>>30 0,1,-1 しか無いとは書いて無いよ。
最近新しい出会いがありません。 もっと勉強しなくてはと思わせるようなアルゴリズムを紹介してください。
エラー訂正符号とか勉強すると面白いよ
complex<double> x[num]; これどうやって宣言するんですか? numを変数にしたいんです
>>36 寝言は寝て言え。
>>35 std::vector< std::complex<double> > x(num);
38 :
36 :2009/01/10(土) 02:43:37
num を変数にするっていうのは 後でサイズを変えたいと言う意味か!
>>39 コンパイルできるでしょ?
#include<complex>
int main(void){
int num=5;
std::complex<double> x[num];
x[0].real()=0.0;
x[0].imag()=1.0;
return 0;
}
fgetsは処理ごとにメモリが動くので、一様な使い方ができません。 どのように切り抜けるか知っていますか。下記例。 #include<stdio.h> int main(){ FILE *fp; char a[256]; char *b[4]; char *c,*d; int i; if((fp=fopen("address.dat","r"))==NULL)exit(1); c=fgets(a,256,fp); printf("%s",c); d=fgets(a,256,fp); printf("%s",d); fclose(fp); } これを c=fgets(a,256,fp); d=fgets(a,256,fp); printf("%s",d); printf("%s",c); のような順序にすると同じ値が出てしまいます。(1行目が消えて、ファイルの2行目の出力になる)
釣られないぞ
>>40 C99に対応したコンパイラならできるかもね
いやC99の仕様も取り込んだC++コンパイラ
g++ならできるよ
それ g++ の拡張機能だろw
C++0xにC99の可変長配列入るんだっけ?
入らないはず。 std::vector の方が色々出来て便利だし。
sizeofがコンパイル時に決まらなくなるから 色んなテンプレートが破綻するので入れられない
>>48 vectorみたいなコンテナクラスで生成時可変長の配列なら入るんじゃなかったかと。
質問させてください。 以下をコンパイルすると 17: error: class ‘Ext’ does not have any field named ‘Base’ 17: error: no matching function for call to ‘Base<int, int>::Base()’ 12: note: candidates are: Base<T1, T2>::Base(T1) [with T1 = int, T2 = int] 7: note: Base<int, int>::Base(const Base<int, int>&) というエラーになるのですが、 テンプレートで指定したクラスをコンストラクタの引数に 指定してはいけないのでしょうか?
53 :
52 :2009/01/10(土) 15:07:27
template <class T1, class T2> class Base { protected: int num; T2 value; public: Base(T1 val) : num(0), value((T2)val) { } }; class Ext : public Base<int, int> { public: Ext(int val) : Base(val) { } }; int main(int ac, char *av[]) { Ext myext(1); return 0; }
>>51 そうなの?
もうvector::resize()しなくていいの?
56 :
52 :2009/01/10(土) 15:18:27
>>55 ありがとうございます。
g++ 4.2.4なんですが、コンパイラのせいですか orz
文法的には問題ないのですよね?
>>51 もしかして、arrayのことを言っているなら、それは違うと言っておく。
中身はただの配列で、つまり固定長。
58 :
51 :2009/01/10(土) 15:21:28
あーごめん、boost::arrayがC++0xに入ったらいいなぁという話だった。
59 :
52 :2009/01/10(土) 15:36:36
自己解決しました コンストラクタの定義が間違っていました。
boost::anyってどんな型を入れられるの?どんな型を取り出せるの?
Cで組み込み開発、 C#でwindowsアプリ開発経験あり。 そんな俺がC++を学ぶとしたら何かお勧めの書籍とかサイトはありますか?
俺
Cの文法は知ってて、C#でオブジェクト指向も知ってるんだな だったら基本はすぐ理解して書けるだろうからC++特有の罠を勉強した方がいいな とりあえずEffective C++を読むがいい
>>64 俺は、この正月にC,Java,ruby知っててC++に手を出したが
More Effective C++はわからんかった。英語のせいもあるけどw
結局、独習C++のお世話になってます。
コンストラクタの引数とかテンプレートとか
なかなか変態的だよね。
Visual C++で可変引数リストの関数をDLLにエクスポートできるのでしょうか? 今、次のような関数をエクスポートしようとしているのですが、うまくできません *.h部 __declspec(dllexport) void debug_message( const TCHAR *format, ... ); *.cpp部 __declspec(dllexport) void debug_message( ) {
Cで三角関数のテーブルを作っているのですが、質問です。 以下はヘッダファイルの一部です。 /* テーブル化したsin() */ double sin_table(double radian); …… #ifdef USE_TABLE #define sin sin_table #endif 上記のように、テーブルを使う際にUSE_TABLEを定義すればsin_table()をsin()と書けるようにしたいのですが、 こういう書き方は元々のsin()を隠してしまうのですべきでは無いのでしょうか?
#ifdef USE_TABLE #define SIN sin_table #else #define SIN sin #endif みたいに別のものを使うべきだな。
71 :
69 :2009/01/11(日) 15:13:43
>>70 なるほど。そう書くことにします。
ありがとうございました。
72 :
デフォルトの名無しさん :2009/01/12(月) 13:26:30
ポインタを利用した二分探索木のデータ削除で質問なのですが、下のプログラムではデータが消えません。 どうしたらいいですか?? 子を2つ持つ場合です。 if(head->right!=NULL && head->left!=NULL){ y=head->left; if(y->right==NULL && y->left==NULL) { strcpy(head->data,y->data); free(y); head->left=NULL; } w=head; while(1){ if(y->right!=NULL){ w=y; y=y->right; } else break;} strcpy(head->data,y->data); if(y->left!=NULL) {w->right=NULL; w->right=y->left; free(y); } else{ free(y); w->right==NULL }}
PC shutdownすれば消えるよ
初心者歓迎だったので失礼いたします。
Cを勉強しているんですが、ポインタと構造体が何を読んでも分からなくて
質問させてください。
http://codepad.org/rnSOFLEU このようなソースで、とても皆さんにはお目汚しかも知れませんが
独学で色々とやっていて至らない点だらけなんですが、
実行してみると、main関数ではAA[0]とAA[1]に入って欲しい値が入っているのに
関数に飛ぶと、AA[0]にAA[1]がはいってしまうんです・・・
良ければどなたか教えていただけませんでしょうか・・・
>>72 ソースはコンパイルできるように貼ってくれ。それだけ見ても、 head とか y とか data とか
わからんものが多すぎる。
>>74 > ulint A[1]={0},B[1]={0};
...
> for(i=0;i<2;i++){
> A[i] = a & 0xffff;
> B[i] = b & 0xffff;
これだけで死亡確定だな。
>>76 さん
32bitを16bitにして別々に分けたかっただけなんですが・・・
一応printfでもちゃんと分けれたんですが・・・
なぜいけないんでしょうか・・・
>>77 A は要素数 1 の配列だから A[0] まではアクセスできるけど A[1] はダメ。
>>78 さん
ありがとうございます!
A[2]だけどA[0]から始まるので、勘違いしてました。
後、ポインタと構造体なんですが、やはり色々試してみても
main関数でAA[0]の値としたの関数でのAA[0]の値が変わってしまうんですが・・・
こちらの原因は一体何なんでしょうか・・・
80 :
デフォルトの名無しさん :2009/01/12(月) 14:54:09
C言語について質問させてください. char型(1byte)の配列にデータを格納して,その配列4つ分のデータを int型(4byte)の変数に代入するにはどういうコードにすれば良いでしょうか. よろしくご教授お願いします. C言語についての私のレベルはなんとかポインタを理解している程度です.
ポインタを理解しているなら ポインタを使えばできることも分かるはずだ。 それが分からないなら、ポインタを理解できてはいない。 あまり見栄を貼るものではない。 char hoge[4] = { 0x12, 0x34, 0x56, 0x78 }; int n = *(int*)hoge;
それってエンディアンよって動き変わらないか?
変わるけど、目的が分かんないからな・・・。
>>74 正直、あんたにそのプログラムは未だ早すぎる。もっと配列について勉強してくれ。
>>81 それはやってはいけないコードの一例。
hogeがint境界に置かれる保証はないぞ。
# 大抵は大丈夫だが。
>>84 さん
締め切りが明日なんです・・・
今日中にどうにかしないとやばいんです・・・
しかも、17時からバイトで帰ってこれるのが0時過ぎなんで・・・
86 :
デフォルトの名無しさん :2009/01/12(月) 15:11:28
81さん ありがとうございます. "*"を一つだけ使用するポインタについては動作を理解できるのですが, 例示して頂いたような"*"を2回使うポインタについては,内容を 理解できないのが実情です. 明解C言語入門編を教科書に勉強しているのですが,"*"二つ使いのポインタ について理解するのにお勧めの本,又はwebを教えていただけないでしょうか? >82,83さん 想定しているのはビッグエンディアンです >84さん 確実に動作補償されるコードをよろしければ教えていただけないでしょうか?
>>85 宿題は宿題スレへ。他のスレにも同じようなコード貼ってる同じ穴の狢がいるようだから、
同病相哀れむなり何なり、好きにしてください。
>>86 確実に動作「補償」されるようなコードはありません。
union使えばいいんじゃないの?
>>79 46行目が嘘付いてる。kだけインクリメントしておいて、sはそのままだ。
91 :
デフォルトの名無しさん :2009/01/12(月) 15:16:11
>88 確かに!! 動作保証するコードのことでした^^;
>>86 >char型(1byte)の配列にデータを格納して,その配列4つ分のデータを
>int型(4byte)の変数に代入するにはどういうコードにすれば良いでしょうか.
そのまま書けば宜しい。
char foo[] = {0x12, 0x34, 0x56, 0x78}; //char型の配列にデータを格納
int bar; // int型の変数を確保し、
char * pBar = (char *) & bar; // その場所をchar *としてpBarにポイントさせる。
for (unsigned ic = 0; ic < sizeof(bar); ++ic) pBar[ic] = foo[ic]; //その場所に、配列をコピー
>>87 さん
聞きながらでも自分でどうにかしたかったので・・・
>>90 さん
*s=k;
で*sのk番目って事じゃないのでしょうか・・・
何をやっても関数のAA[0]番目にmainのAA[1]が着てしまいます・・・
>>93 s=F.AA; で、sはAA[0]をさしている。
*s=k; はAA[0]にkを代入する。
>>94 さん
では下の関数でs -> AA[0]で上でAA[0]に入れたところを指しているわけでは無いのですか?
mainでいれたAA[0]の値と下の関数で出てくるAA[0]の値が同じにならない原因が分からないのですが・・・
さすがにいい加減うざいが・・・ *sっていうのは常にAA[0]と同じところを指している。 たぶんs[k]と書きたいのだと思われる。
アドレス、データをダンプしながらやれば いやでも解るようになるとおもうんだ
>>95 > では下の関数でs -> AA[0]で上でAA[0]に入れたところを指しているわけでは無いのですか?
そうではない。
main内の*s = k;および2つの*s = c & 0xffff;は、すべてAA[0]に代入している。
sがAA[0]を指したままだからだ。
tas内でAA[0]を見たときは、2つ目の*s = c & 0xffff;で代入された値が入っている。
マルチは放っておけばいいと思うんだ。
100 :
デフォルトの名無しさん :2009/01/12(月) 15:42:50
>>92 >そのまま書けば宜しい。
>char foo[] = {0x12, 0x34, 0x56, 0x78}; //char型の配列にデータを格納
>int bar; // int型の変数を確保し、
>char * pBar = (char *) & bar; // その場所をchar *としてpBarにポイントさせる。
>for (unsigned ic = 0; ic < sizeof(bar); ++ic) pBar[ic] = foo[ic]; //その場所に、配列をコピー
詳しい解説ありがとうございます.
教えて頂いたコードで試してみました.
int barを出力してみたところ”2018915346”という値が入っていました.
ですが,intに入れたのは 0x12, 0x34, 0x56, 0x78なので,期待する値としては
”305419896”になると思います.
この違いは何故生じるのでしょうか?
エンディアンでぐぐれ
102 :
デフォルトの名無しさん :2009/01/12(月) 15:48:05
失礼しました.ビッグエンディアンと思っていた研究室のワークスペースが リトルエンディアンでした. 助言頂いた皆様ありがとうございました.
2018915346=0x78563412 305419896=0x12345678
出直せといわれたので、初心者歓迎のところへ来て・・・
宿題なら宿題板行けといわれ・・・
世知辛いです・・・
>>96 さん
理解力無くてすみません・・・
ということは、どこででもs[k]と書けば、そのアドレスの数値を取り出せるって事ですか?
>>98 さん
なるほど!*sで指定したアドレスの順番に従ってk=0ならs=0番目のところ
k=1ならs=1になると思ってました。
分かりやすく説明してくださって有難うございます!
後、色々な板で詳しく丁寧に教えてくださった皆様有難うございます。
それぞれの板でお礼したかったですけど、マルチになっちゃうみたいなんで
ここでお礼させてもらいます。
有難うございました。
.ccpのインクルードヘッダーは宣言が書いてある.hだけにしたほうがいいんですか? それともstdafx.hで統一して問題ないんですか?
それは既にC++の話ではなくなってる
error LNK2019: 未解決の外部シンボル "public: virtual __thiscall CMyClass::~CMyClass(void)" (??1CMyClass@@UAE@XZ) が 関数 "public: virtual void * __thiscall CMyClass::`scalar deleting destructor'(unsigned int)" (??_GCMyClass@@UAEPAXI@Z) で 参照されました。 このエラーはなにがいけないんでしょうか?
>>107 ソース内に構文としては正しそうに見える、勘違いによる間違いがある。
それ以上はソースを見ないとはっきりしないと思う。
# エスパーならどんな間違いかを推定できそうだけれど。
デストラクタが宣言だけされて実装が書いてないんじゃないの。 virtualみたいだから、仮想デストラクタで=0でもつけただけだとか。
よくわかるね・・・デストラクタの宣言だけで中身がなかった ありがとう!
コンパイルエラーとリンクエラーの違いが分かっているか、お兄ちゃんは心配だ
いやわかるって。 リンカが「シンボルが見つからない」って言ってて アンマングリングされた名前(デストラクタ)も示してくれてるんだから。 コンパイル通ってリンクエラーなら、宣言だけで実装がないとしか考えられない。 あと外部ライブラリでlibを指定してないとかもあるけどね。
114 :
113 :2009/01/12(月) 20:04:19
相変わらずタイミング悪いな俺。
>>113 は108や111宛てだ。
質問者(おそらく初心者)はともかく、108がこの程度でエスパーとか言い出すのが不思議過ぎるよ。
115 :
111 :2009/01/12(月) 20:20:17
流れにワラタ、といえばよかったか
自動変数は限りのあるスタックに置かれると書いてあったんだが、どのぐらいの容量までOKなのかどうやって知るの? 俺スコープ使うのばっかで、全くnewとかしてないんだけど、これからアプリがどんどんでかくなると思うと不安になってきた
>>116 環境によるけど、コンパイラやリンカのマニュアルに何か書いてあることが多い。
VCは1MB
VCはデフォが1MB。コンパイルオプションでMB単位で指定可能。
単位違ってたま
スタックサイズって固定だっけ? 実行時に動的に増えたりしないの?
123 :
122 :2009/01/13(火) 22:43:24
VCで実験してみたら、余裕でスタックオーバーフローになった。
>>122 WindowsやLinuxなどのOSの場合、初期サイズはうんと小さくて、
そこから増えていく(必要に応じて確保される)。その上限が
>>119 。
どんなにでかいソフトでもサイズオーバーするなんてありえない int宣言100万個も保持するソフトなんて作ろうと思ってそうそうできるもんじゃない
>>125 1MBなんだから、4バイトint換算で高高25万個だ。
うっかりヒープに取らずにスタックに取れば簡単に溢れるサイズでしかないよ。
if (エラーチェック) { MessageBox(エラーメッセージ); func(); // 自分自身呼び出し return; } このまえ↑みたいなコードを見た。 エラーだったらメッセージ出して、再度処理させるみたいな。 まあ、ひらすたOKボタン押し続けるやつはいないだろうけど、これでいいのかって感じ。
>>127 末尾再帰なら最適化で単純なループになる可能性は高い。
文字列クラス使ってたから、末尾再帰にはなってなかった。
引数を与えてないtemplate classに別名を付けることって可能でしょうか? typedef std::vector localvector; localvector<int> v; というような書き方がしたいのですが。
>>130 できません。
貼ってあるコードを見た感じだと意味無いんだけど、なんでそんなことがしたいの?
目的によっては代替方法があるかもしれない。
C++のメンバ変数で公からの値の変更は受け付けずに、 自己クラス含め特定のクラスからのみの変更を受け入れるような場合、 アクセス関数を定義するしかないですか? 自己クラス以外から変更したいときは、アクセス関数をprivateにしておいてfriendを使うみたいな。
>>131 引数にテンプレートクラスを受け取るテンプレートクラス
(例えばコンテナラップなテンプレートクラス)を書くときに
template<template<class> class T>な記述だと引数の個数などで
統一しにくい場合が多いので、何かもっと汎用性のある方法無いかと思いまして。
template<typename T> struct localvector { typedef std::vector<T> type; }; みたいな感じで何とかするしかねぇんじゃねえの
135 :
デフォルトの名無しさん :2009/01/14(水) 17:38:36
スレ違いだったら申し訳ないです。 IDirectMusicSegment8 *m_Segment[50]; 質問@ これをクラス内のデフォルトコンストラクタで初期化する場合は for(DWORD i = 0; i < 50; i++) { m_Segment[i] = NULL; } 以外にどんな方法がありますか? ------------------------------------- 質問A クラスのprivate部分で IDirectMusicSegment *m_Segment; で宣言して デフォルトコンストラクタ部分ではNULLで初期化 初期化する関数で m_Segment = new ???[50] メモリを確保できると思ったのですが???の部分をIDirectMusicSegmentにしても できませんでした。 newでメモリを確保する場合はどうやればいいですか? ---------------------------------------------- 先輩方レスよろしくお願いします
>>135 つ[std::fill]
あと、ただ「できない」じゃなく、エラーが出たならエラーメッセージを貼れ。
>>135 IDirectMusicSegment(というよりIUnknownとその派生すべて)は、
実装を持っていないインタフェース(C++的には抽象クラス)なのでnewできない。
どこかにIDirectMusicSegmentへのポインタを得る方法があるはずだから、それ使え。
>>136 >>137 ありがとうございます
>どこかにIDirectMusicSegmentへのポインタを得る方法があるはずだから、それ使え。
探してみます〜
139 :
デフォルトの名無しさん :2009/01/14(水) 20:59:51
多重継承のダウンキャストについて質問です。 --------------------------------------------- class BaseActor { }; class MeshActor : virtual public BaseActor { }; class SpriteActor : virtual public BaseActor { }; class MainActor : public SpriteActor, public MeshActor { }; int main() { MainActor* pActor = new MainActor(); BaseActor* pBase = (BaseActor*)pActor; MainActor* p = (MainActor*)pBase; //エラー!! delete pActor; } ------------------------------------------------------------- で、コンパイルエラーメッセージは ..\src\cppTest.cpp:23: error: cannot convert from base 'BaseActor' to derived type 'MainActor' via virtual base 'BaseActor' と出てしまいます。ですが、やりたいことは 「//エラー」の行のようなことなのです。 質問は、ひし形の基本クラスのポインタ(上記の例では pBase)のみがわかっている状況で、 そのポインタから、ひし形以降の派生クラスの型にダウンキャストできないのでしょうか、 上記の例では pBase から最初の pActor のようなポインタ変数がほしいのだが無理なのか。ということです。 いろいろ検索してみましたが、「どうやっても無理!」か否かが明確にわかりません。 どなたかご教授お願いいたいます。
菱形って言うより仮想継承のダウンキャストができないってだけだと思うけど
>>139 dynamic_cast しる。
ただし、仮想関数が最低でも1つは必要。
普通はデストラクタが仮想関数だから 大して気にする必要はないがね。
143 :
デフォルトの名無しさん :2009/01/14(水) 21:41:22
↓のソースで関数ポインタについて誰か助けて下さい ○ データ型 (void (*)(char*)) の観点からは (*p)() と p() とではどちらが自然な書き方ですか? ○ if 文以下で定数式を使って関数を呼び出すことはできませんか?可能ならば,関数の処理内容を16進でダンプしたいのです #include <stdio.h> void func(char* str) { printf("%s\n",str); } int main(void) { void (*p)(char*) = func; func("call func()"); // call func() (*p)("call (*p)()"); // call (*p)() p("call p()"); // call p() printf("%x\n",func); // 実行するといつも 80483d4 printf("%x\n",p); // 上と同じ if (func == (void (*)(char*))0x80483d4) { 0x80483d4("call 0x80483d4()"); // test.c:21: error: called object '134513620' is not a function (*0x80483d4)("call 0x80483d4()"); // test.c:22: error: invalid type argument of 'unary *' (have 'int') (void (*)(char*))0x80483d4("call 0x80483d4()"); // test.c:23: error: called object '134513620' is not a function *(void (*)(char*))0x80483d4("call 0x80483d4()"); // test.c:24: error: called object '134513620' is not a function } }
144 :
143 :2009/01/14(水) 21:46:54
>>143 今やってみたら,後ろの方は↓であっさりコンパイルできました.すみませんOTL
(*(void (*)(char*))0x80483d4)("call (*(void (*)(char*))0x80483d4)()")
>>143 C の規格では、関数呼び出し演算子は以下の2通りの使い方が可能であると規定されている。
関数(引数)
関数ポインタ(引数)
つまり、どちらでも構わない。
個人的には (*p)(); とか冗長で読み辛いので p(); の方が好きだが、
関数ポインタであることを強調した方が良いという考え方の人なら (*p)(); の方が好きだろうな。
146 :
143 :2009/01/14(水) 21:51:27
>>143 また,いまやってみると,↓もコンパイル通りました.
((void (*)(char*))0x80483d4)("call ((void (*)(char*))0x80483d4)()");
(*p)() と p() までは C の約束で同義として捉えていたのですが
((void (*)(char*))0x80483d4)() と (*(void (*)(char*))0x80483d4)() までもが同じというのは..どうもとっつけません...
>>146 関数(引数) → (*(void (*)(char*))0x80483d4)()
関数ポインタ(引数) → ((void (*)(char*))0x80483d4)()
何か問題でもあるか?
>>147 データ型が *(void (*)(char*)) → 関数(引数)
データ型が void (*)(char*) → 関数ポインタ(引数)
ということですか?
だとすると func は関数なので,そのデータ型は *(void (*)(char*)) でいいんですか?
あと,
int* p = malloc((size_t) sizeof(int)); // 仮に 0xff が返ったとする
*p = 10;
のときに
*p(=10) と p(=0xff) は違うというのは,全く無関係な世界の話し..ということでいいのですか?
ばかなの
関数ポインタはいくらデリファレンスしても関数ポインタのまま。
func の型は void (char*) だな。(配列型へのキャストが無理なのと同じく、この型への直接的なキャストは無理だが) typedef すると分かるが、 typedef void foo(char*); とした時、 foo* は関数ポインタになる。 だから、foo は関数を表す型である。 もし foo が関数ポインタ型なら、 foo* は関数ポインタへのポインタ型となるからね。 >全く無関係な世界の話 まあそうだな。 関数型の値を関数ポインタ型の変数に代入しようとすると、 自動的に関数ポインタ型へと変換される。 このあたりは、配列とポインタの関係に似ている。
>>151 処理系が関数呼び出し演算子 () を見つける
↓
() の前にある式のデータ型を確認する
↓
そのデータ型が「関数」かまたは「関数ポインタ」であれば,それに対応する関数を呼び出す
「関数」のデータ型 → void (char*) // キャスト不可
「関数ポインタ」のデータ型 → void (*)(char*)
ということですね
> 関数型の値を関数ポインタ型の変数に代入しようとすると、
> 自動的に関数ポインタ型へと変換される。
納得です.すっきりしました.どうもありがとうございます
>>152 自分用のチラシの裏.スレ汚しスマソ
(*p)() // *p は関数型 void (char*)
p() // p は関数ポインタ型 void (*)(char*)
(*(void (*)(char*))0x80483d4)() は関数型へのキャスト?
((void (*)(char*))0x80483d4)() は関数ポインタ型へのキャスト
>>150 によると *p も関数ポインタ型のようだが。
C++ でチェックしてみた。 #include <iostream> #include <typeinfo> void foo() { } void (*p)(); int main() { std::cout << typeid(foo).name() << std::endl; std::cout << typeid(p).name() << std::endl; std::cout << typeid(*p).name() << std::endl; } 出力 FvvE PFvvE FvvE *p はやっぱり関数型じゃねえか。
****p(); を試したらわかるんでないか
関数型の値に * をつけると、 一旦関数ポインタ型に変換されてから また * が作用して関数型に戻るんでないかい?
以下の4つは全部同じ printf("%p\n", func); printf("%p\n", &func); printf("%p\n", p); printf("%p\n", *******p); うろ覚えだけど、 関数型は値を評価すると自動的にアドレス(関数ポインタ型)に変換されるので、 関数ポインタ型を間接参照で関数型にしてもまた自動的にアドレスに変換される (関数ポインタ型の間接参照は実質的に意味をなさない) だったかな
関数型の値は左辺値で、 右辺値に変換すると関数ポインタ型の値になる。
>>155 C/C++の式の世界には「関数」は存在できない
生の関数が出現すると即座にその関数ポインタに変換される
だがsizeofとtypeidの中は関数が関数として存在できる数少ない例外的な場所になってる
だからtypeidすると「関数型」を見ることは出来るが、外でそれを使うことは出来ない
(ちなみにもう一つは「単項&演算子のオペランドになる時」=結局行き着く先はポインタ)
>>160 いい加減な事を言うなよ。
関数は左辺値であるから、
左辺値を要求する所に使えば関数は関数のまま存在できるし、
typedef void hoge();
hoge& r = foo;
そもそも関数の使い方で最も代表的な関数呼び出しでは
関数が関数のまま扱われているだろう。規格的に考えて。
>>161 そりゃ関数の参照だからだな。関数の参照は存在できるよ
hoge f = foo;みたいに関数そのものを作ろうとするとfは関数ポインタになるよ
あと関数呼び出し演算子のオペランドは関数ポインタだから
r()と呼び出せるのは関数の参照から関数のポインタに暗黙変換されるから
>>162 規格読め。
関数呼び出し演算子のオペランドは関数あるいは関数ポインタと規定されている。
左辺値と右辺値という言葉くらいは調べてから出直してこい。
a.foo(); みたいなのもあるからな。 () のオペランドが関数ポインタだけとすると不都合がある。
>>163 どこにそんなこと書いてあるんだ?
6.5.2.2 Function calls
The expression that denotes the called function shall have type pointer to function
returning void or returning an object type other than an array type.
で、注にはこう書いてる
Most often, this is the result of converting an identifier that is a function designator.
関数呼び出し演算子がさも「関数」に適用できてるかのように見えてるのは、
実際には関数から暗黙変換された関数ポインタに適用されてるんだ
あー、C++では違うんだな ごめん
>>165 それって「a.foo()」で一つの構文じゃないの?
「a.foo」に関数呼び出し演算子を適用すると解釈するなら「a.foo」って何になるの
C/C++ スレだから両者で違う点について話す時はややこしいな。
char abc[]="ABC"; /* 文字列変数宣言 */ char *p; /* ポインタ変数宣言 */ char wk; p = &abc[0]; と p = abc; は同じですか?
同じです
ビット演算?(16進数)がいまだによく分からないのですが 分かりやすいサイトなどご存じないでしょうか? スレ違いでしたら申し訳ないです (それと2月18日にC言語検定2級を受けるのですが 特に抑えておいたほうがいいポイントはありますか?)
ビット演算がわからんというのもよくわからん 十六進数から二進数への変換はわかるよな? その逆もわかるよな? ANDとORとNOTの意味はわかるよな? 右シフト、左シフトもわかるよな? 全部わかってるならビット演算を全部わかってることになるから大丈夫
16進数は2進数を4ケタまとめて1ケタで表す それだけ
孔子はこう言った ならず者にはポインタを、聖なるものには列挙体を アラベスクに幸あれ
176 :
デフォルトの名無しさん :2009/01/15(木) 20:54:12
オブジェクト(内の変数の値)をファイルに保存・復元する お手軽な方法ってないでしょうか? .NetのXmlSerializerみたいな感じで。(別にXMLじゃなくても良いです) 環境はVC++2008 Expressです。 よろしくお願いいたします。
>>176 参照だとかポインタだとか、他のオブジェクトの依存関係がどうなってるかは設計者しかしらんことだ。
一律に単純にやる方法は無いと思う。
boost 導入してみるとか
179 :
デフォルトの名無しさん :2009/01/15(木) 21:19:23
>>177 やっぱそうですか。自分でがりがり書くことにします。
>>178 serializationあたりでしょうか?
状況によって役に立つようでしたら使ってみます。
ともかくありがとうございます。
ビット演算の~って 0xf003 だったら 0x0ffc ですけど 0 → f f → 0 c → 3 3 → c って感じでいいんですか?
チルダは反転だな 0x0 = 0000b → 1111b = 0xF 0xC = 1100b → 0011b = 0x3 あってるけど、分からなきゃ一度2進数に変えた方がいい
>>183 > ありおがとうございます
ありおwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
185 :
デフォルトの名無しさん :2009/01/15(木) 22:29:37
istreamから前方反復子って作れないんですか?
istream_iterator
<iterator> に std::istream_iterator ってのがある。 だがしかし・・・ ++ の仕様が期待通りではないかもしれない。( >> で読み出しているので) もし期待通りのものでなかったなら、 簡単に作れるので自分で作ってみてもいいかと。
188 :
デフォルトの名無しさん :2009/01/15(木) 22:53:54
それって入力イテレータじゃないの?
char *st[] = { "ne", "ushi", "tora", "u", "tatu", "me", "uma", "hituji", "tori", "inu", "i" }; char *pt1, *pt2; pt1 = *st; pt2 = *(st + 7); printf("%c\n", (*pt1) + 1); 出力される文字がoなのですが30分考えてもなんでか分かりません・・・ 教えていただけませんか (*pt1) で nをさして + 1 で次のe だと思ったのですが・・
>>187 つistreambuf_iterator
アルファベット順(というか文字コードの順)に並べて、nの次の文字がoだったから。 *pt1の段階で、*を剥がしまくってもはやnという文字そのものと化している。
>>192 そういうことだったのか!!!
ありがとうございました
かなりスッキリしましたw
195 :
デフォルトの名無しさん :2009/01/15(木) 23:09:46
入力反復子でアルゴリズムを適用すると、読み取った部分って捨てられてしまうよね? 普通は読み取った部分が欲しいはずなんだけど、これってどうなってるの?
196 :
デフォルトの名無しさん :2009/01/15(木) 23:10:34
あほなの?しぬの?つけ忘れた。
>>190 *pt1は'n'なので、'n'+1で'o'
>>195 copyとかtransformとかfor_eachとか読み取ったのが捨てられて構わないアルゴリズムに活路を見出すんだ。
再帰ってどこまで深くできるんですか? 戻ってこられるように元の場所を保持し続けたらいつかは限界がくると思うんですが
スタックが溢れるまで
場合によっては永遠に
goto文を使うと最適化が無効になると書いてあったんですが 全体が無効になるんですか?それとも使用している関数内で無効になるんですか?
迷路を再帰で脱出するプログラムがあったので、あまり大きな迷路は無理なのかなーと 保持するのに使うメモリ容量がわかりませんが、32bit使うとしたら、1Mまで再帰中に変数を使わなかったとして 250k階層まで深くできるってことですか?
特定のコンパイラでそういうこともあるかもしれないが一般的な事象ではないな。
例外処理は仕組みがわかってもどこで使えばいいのかわからず活用できないでいます。 例外が発生しそうな部分を囲むってあるんですが、場所がわかるなら1行をtryで囲めばいいですよね? mainの次のネストで囲って全プログラムに適応した方が2か所以上例外が出る場合は面倒がないし、1回で書ける とかいう理由で使えばいいんでしょうか?
template<typename T> typedef std::vector<T *> pointers<T>; pointers<int> int_ptrs; ということはできませんか?
>>206 >>130-131 >>133 ↓こんなのが使えるかもしれない。テンプレートメタ関数ってやつね。
template<typename T>
struct vector_of { typedef std::vector<T> type; };
vector_of<int>::type int_ptrs;
212 :
デフォルトの名無しさん :2009/01/16(金) 14:32:59
#include <iostream> class X { public: void show() { std::cout << "X" << std::endl; } }; class Y : public X { public: void show(int) { std::cout << "Y" << std::endl; } }; int main() { Y y; y.show(); } ってしたらこんぱいるできないんですがなんでですか?
宣言にはセミコロン必要。
>>212 オーバーライドされたから。
y.X::show();
>>212 Y::show によって X::show が隠されるから。
両者は別物で、両方をまたがってオーバーロード解決はできない
YのshowがXのshowを隠蔽するから。 class Y : public X { public: using X::show; (略) }; というように書けば、Yの中でshowがX::showを隠蔽していても、X::showが選択肢に追加される。 return 0;
g++,cygwinです 1.ファイルの有無を確認する方法はありますか? Cでは読み込み専用のファイルオープンでファイルの存在確認した後上書き確認の表示してましたが、C++も同様(ifstreamで確認)ですか? 2.int型を16進バイナリで出力したい std::ofstream ofs_out( filename, std::ios::out | std::ios::binary ); oofs_output << std::setw(4) << std::setfill('0') << std::hex << 0xFFFF; このコードでは出力先にFFFF(0x46464646)がそのまま表示されますが、どうすればファイルにバイナリで0xFFFFを出力できますか? 3.string->int でエラーを検出したい std::istringstream iss(str); int i; iss >> std::hex >> i; (または、i = boost::lexical_cast< int >( str ); ) このコードで、str="123w"の場合、i=0x123となりそのまま実行されますが、エラーとして処理したいです。 strtol関数の他に何か方法はありますか? お願いします。
>>217 1. それでもいいでしょう。
2. oofs_output << 0xFFFF;
3. if (!(iss >> std::hex >> i).eof()) { /* error handling */ }
>>203 関数コールするたびに、引数の合計分と、関数を出たときに戻るアドレス分スタックが消費される。
消費スタックサイズ量を保持する分もスタック使ったかも
>>218 ありがとうございます。
1は実装してませんが後でやってみます。3はできました。
2は10進のテキスト(ASCII)で表示され、0xFFFFは出力されませんでした。
書き忘れてしまって申し訳ないのですが、欲しい出力形式はint型変数の下位2バイト、16進数4桁(0x0000〜0xFFFF)です。
int var[10] = {0,1,2,3,4,5,(.....)}; //ここに出力したいデータが入っている
std::ofstream oofs_output( "out.txt", std::ios::out | std::ios::binary );
for(int i=0; i<5; ++i)
oofs_output << std::setw(4) << std::setfill('0') << std::hex << var[i];
としたとき、
> od out.txt -x
0000000 0000 0001 0002 0003 0004 0005
という出力を得たいです。実際はASCIIコードでこうなってしまいます
> od out.txt -x
0000000 3030 3030 3030 3031 3030 3032 ...
下のように共用体で実装したら意図した結果が得られましたが、
代入のし直しは無駄な気がしてあまりやりたくないです。
int var[10] = {0,1,2,3,4,5,(.....)};
union test{
char c[4];
int i;
}ut;
for(int i=0; i<10; ++i){
ut.i = var[i];
oofs_output << ut.c[0] << ut.c[1];
}
write使え
WindowsでVisual C++ 2005を使っています。 isgraphでsjisの2バイト文字も判定させるにはどうすればいいでしょうか。 他に有用なライブラリがあれば教えてください。
板違いかもしれませんが、
C言語のライタとコンパイラの機能をもつGCC Developer Liteというソフトがインストールできません。
ファイルを開く、実行、言語選択まで進めるのですがその後エラーを知らせるメッセージが表示されインストールができません。
8.3filenameというフォーマットに私のPCが対応していないらしいのです。調べたところ、8.3filenameはMicrosoft の初期の
OSのフォーマットで、Windows XPも対応しているようなのです。
原因のわかる方、何か思いついた方、何かアドバイスをいただけたら非常に助かります。
・表示されたメッセージ
Your PC dose not support 8.3filename format.
Cannot continue installation of this program.
・インストールしようとしたファイル
GCC Developer Lite Ver.2.1.0.20r2 GDLFull2.1.0.20r2.exe (81Mb)
サイト
http://www.besttechnology.co.jp/download/ ・私のPC環境
購入元
マウスコンピュータ
OS
Microsoft Windows XP Home Edition Version 2002 Service Pack 3
CPU
Intel(R) Core(TM)2 CPU T7200 2.00GHz
メモリ
2GB
227 :
217 :2009/01/16(金) 21:00:43
>>222 こうですね、スマートにできました、ありがとうございました。
oofs_output.write( (char*)&var[i], sizeof(int)/2);
printfで表示するとき %3.1fだとすると 3ケタで小数点は1ケタまで表示ですが 1.255とかだったら 1.2ですけど.も桁数にカウントするんですか?
しません
桁数って考か文字列の幅って考えだから
1.255で"%3.1f"なら1.3だな。
233 :
デフォルトの名無しさん :2009/01/16(金) 23:26:25
初歩的な質問ですが・・・ よく関数のオーバーヘッドと言うものを聞くのですが、これは class A { void funcA(); void funcB(); void funcC(); } とあった場合に、funcA〜funcCの中から呼ばれた関数を探し当てるのにかかる時間のことという理解でいいでしょうか? つまりメンバ関数の数が増えるほどかかる時間は多くなる、、ということかと思っているのですが。 そしてそれを避けるためにinlineが存在すると。
探すのなんてリンク時にやることだ。 実行時にそんなことしない。 関数呼び出し時には ・ リターンアドレスをスタックに積む ・ 命令の実行位置を関数のあるところに移動する という処理が必須。 関数から戻ってくる際には ・ リターンアドレスを読み出す ・ 命令の実行位置をリターンアドレスに移動する という処理が必須。 メモリアクセスとジャンプは両方とも遅い処理。
>>233 探し当てる時間というのはまぁある意味あってるが、少し理解よくない感じに間違ってる
関数の呼び出し元には、どこに関数があるかが書いてあって、それを元に関数に飛ぶ感じに近い
つまりメンバ関数増えても探すのに時間がかかるようになることはない
CやC++の場合、それはコンパイル時に決まる事柄。 オーバーヘッドとされるのは、実際の実行位置の変更や引数・戻り値の受け渡し。
237 :
233 :2009/01/17(土) 00:11:49
>>234 ,235,236さん、ありがとうございます。
こんなに早くわかりやすい返信が来ると思いませんでした。。
つまり関数を呼ぶときには、戻ってこないと駄目なので自分の位置を記憶してから
別の関数に飛ぶということですね。
それがinline関数だと直にその関数が呼ばれた場所におかれるので記憶も飛ぶ必要も
無くなるということがわかりました。
両方とも遅い処理なのでしたら、かなり実行速度を気にするプログラムを書く場合は
要所要所でinlineを使ったほうがいいということですか。。
いいえ、関数を静的にしたら後はコンパイラに任せてしまいましょう。
命令もメモリ上に置いてあって 命令を実行するのもメモリアクセスが必要だから、 キャッシュに載るくらいコンパクトな方が キャッシュ効率は良くなる。 大きな処理を inline 化して、それが inline 展開されまくると、 逆に遅くなるなんてこともある。 あるいは、速くはなったけど、ファイルサイズが妙に肥大化したり。 まあ、実際には inline にしても inline 展開されるとは限らないけどね。 どんな処理を inline 関数にするのがベストなのかは難しいところだけど、 inline 関数の中身は短い1文かそこら程度で終わるもののみにするのが一般的。
>>234 関数呼び出し時にリターンアドレスをスタックに積むとは限らない
リンクレジスタを持つCPUだったり
末尾の最適化で消されたり
それを言ったら、inline じゃなくても最適化で inline 化されたり。
>inline 関数の中身は短い1文かそこら程度で終わるもののみにするのが一般的。 アナクロな発想は身を滅ぼす典型ですね。
inline 関数はヘッダに書かなきゃいけないから、 再コンパイル範囲が広くなってしまう。 だから複雑な処理を書いたら、 修正が必要になった時に場合によっては面倒臭いことになる。 そういった意味でも複雑な処理を書かないのは普通だ。
全部静的とかありえねー。 趣味プロかよ。
inline つけたら展開しちゃって遅くなるって実際ありうるの? 早くなりそうなら普通の関数を展開してもいいよっていうオプションがあるぐらいだし、 コンパイラがうまいこと判断してくれそうな気がなんとなくするんですが
そんなときはオブジェクト間最適化を備えたコンパイラを使えばOK。
テンプレートのせいでinlineの有無にかかわらずヘッダに書かざるを得ないことのほうが多い。
>>246 gccの例だけど、インライン展開によってオブジェクトモジュールが大幅に大きくなってしまうケースで且つ、
インライン展開されたコードが殆ど実行されない場合に、ロード時間を含めて計測すると遅くなったことはある。
逆に言えば、余程の事がない限り遅くなるようなケースはないと考えていいと思う。
テンプレートは仕方が無いよね。 面倒臭いからクラス宣言内で関数実装しちゃうから 全関数がinlineになっちゃう。
>>246 関数がある程度の大きさを持っていて、
しかもその関数がありとあらゆるところで使われまくってると
出力コードが肥大化して、キャッシュヒット率が下がって遅くなるかも。
>>251 あらゆるところで呼ばれる関数ならキャッシュに居つくんじゃねーの
>>252 インライン化されたらコードが実行部分に分散する。
速度が問題になるまでコンパイラに任せとけばおk
みなさんありがとうございます
>>249 なるほど、そういうことがあるんですか
でもやっぱ基本コンパイラが判断してくれるんですね
>>251 関数大きかったら展開しないんじゃないの?
関数が巨大でも、必要と判断したらインライン展開するのが今のコンパイラ。 但し、コードキャッシュが問題になる程度のプログラムでは殆ど影響が出ない。
u_char array[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC} という配列があったとするとarray[1]は0x34になりますが array[1]を無理矢理u_intとして読み込むことは可能でしょうか? つまり&array[1]のアドレスにあたかもu_intが格納されているように見なして 0x9A785634という値(リトルエンディアン)を取り出したいのです。 array[4]<<24 + array[3]<<16 + array[2]<<8 + array[1] を計算すれば同じ値が得られますが もう少し低レベルにメモリを直読みするような文法は 無いのかなということで質問させていただきました。
>>253 勘違いしていた。
あらゆるところで呼ばれる関数コールがなぜコスト増になるんだ?って思っちまった。
インライン展開したら、か。
そりゃ無駄だな。
>>258 *reinterpret_cast<u_int*>(&array[1])
BOOL m_fLostDevice; BOOLなどの場合fをつけることが多いですが これは初期化する際にfalseということですか?
flag?
>>261 >260では環境によっては破綻するよ。
そうでない環境ならコンパイラが>258でも最適化で>260と同じコードにしてくれるかもしれないからお勧め。
厳密には環境依存になるけど、これもあり。
union {
u_char c[sizeof(u_int)];
u_int i;
} foo;
for (unsigned ic = 0; ic < sizeof(foo); ++ic) foo.c[ic] = array[1 + ic];
>>262 単にフラグ(flag)の意味じゃね?
265 :
デフォルトの名無しさん :2009/01/17(土) 11:46:38
機能のinline展開の話題に乗っかって質問させてほしいんですが FileA.cpp ,FileA.h FileB.cpp ,FileB.h という 二つのファイルとヘッダがあったとして、 FileA.cpp内部のClassAでは、FileB.cpp内部のClassBを持っていて、ClassAからは頻繁にClassBの メンバ関数が呼ばれるとします。 そこで速度が気になりだしてClassBのメンバ関数をinline化したいとなったときはどうすればいいのでしょう? 単純にinlineをつけただけでは別のcppファイルのinline関数を予防とするとエラーになるのですが
inline は内部リンケージ
267 :
262 :2009/01/17(土) 11:50:10
レスありがとうです フラグという意味ですかw
このスレの最近の流れはすばらしいなぁ Win32APIスレにみせてやりたいわっ
>>266 なるほど、、staticと同じという感じですね。
つまり別のcppファイルのinline関数を呼ぶためには
ヘッダーの宣言部ですでにinline関数だけでも実装しておかなくてはならないということか
プロセス:君の全てを見せてくれないか FILE *fp = fopen(”yome.conf”, “r+”); ファイル:や、開かないで、開いちゃいや /// プロセス:ほら、よーく見せてごらん while( !feof(fp) ) printf( “%c”, (char)fgetc(fp) ); ファイル:見ないで、恥ずかしいよ /// fseek( fp, 0L, SEEK_SET ); プロセス:君の設定を最後の1バイトまで書き換えてあげるよ fprintf( fp, “[あなた好みの設定でおk]” ); ファイル:らめぇぇぇ //// プロセス:ずっと一緒にいようね ファイル:/// fclose( fp );
(char) へのキャストは別に要らないんじゃね? 規格的にはどうなんだろう。 %c は char -> int で変換された(可変個引数の仕様により変換された)値しか受け付けないのか、 それとも fgetc の返す EOF 以外の値(つまり符号無しの値)をそのまま渡して良いのか。
最後にゴミをプリントするけどいいのか?
int ch; while( (ch = fgetc(fp)) != EOF ) printf( "%c", ch ); だぁな。 しかし、fopen の ( ) の中だけは空白入れてないのに何かポリシーあんのか?
>>271 暗黙の型変換が行なわれるので、厳密に解釈するとfgetc()の戻り値を一旦charにしてから再びintにすることになる。
その影響を受けるのは、最後の1回だけではあるが。
>>270 つーか、先頭に戻すだけならrewind()を使えばいいのに。
printf( “%c”, (char)fgetc(fp) ); (char)を入れると、符号拡張で値が変わる可能性あるな。
大丈夫、どっちみち255だ。
printf()の%cって、マイナス値が送られてきたらどうなるんだろう。
>>277 大丈夫、最下位1バイトを送出するだけだ。
次のような場合でXのメンバ関数testの中の変数をインスタンス生成時に初期化できませんか? iをXのメンバ変数にして、コンストラクタで初期化すればいいんですが、iを使うのはtest関数の中だけなので・・。 class X{ public: void test(void){ static int i=0; if(i==1) std::cout<< "i=1" << std::endl; i=1; } }; int main(void){ X objx; objx.test; X objx2; objx2.test; //i=0になってほしい } //結果 i=1
メンバ変数にすべきだろ インスタンスごとにiのインスタンスを別にしたいならstaticは使えない そもそもiは何だ?
iは色々処理をしてある条件の時に1になるフラグみたいなものです。 インスタンス生成時に0にしたいけれどtest関数でしか使わないからtestのメンバで・・って考えてました。 >インスタンスごとにiのインスタンスを別にしたい 確かにこの通りです。メンバ変数にするべきですね。 ややこしく考えすぎでした、ありがとうございました。
>>278 規格でそうなってんの?
知りたいのはそこなんだが。
じゃあなんで規格読まないの? 文盲なの?
int型の配列をすべて0で初期化したいんですが、C++にmemsetと同じことができる関数はありますか?
>>284 std::fill を使っても良いが、
int なら memset で十分だとは思う。
>>285-286 cstring (string.h)のインクルードですか?
ありがとうございます。
int a[100] = {0};でいいのに
static int a[100];でもいいね。
>>288 以前gcc(C言語)でそれをやったとき怒られたのでそれはあまり気が進まなかったです
コンストラクタで初期化したいので、その書き方はできるんですかね、、
>>289 そうですね。ただ今回は静的にはできないですが・・。
32ビットコンピュータで 参照渡し、int型変数の値渡し、ポインタ渡し それぞれのオーバーヘッドって同じですか?
>291 ふつうのx86などであれば、 値渡しが最速、参照とポインタは同じ だと思われる。後者は実際の値を取るためにメモリアクセスが余計に必 要なので。
>>290 あー、コンストラクタでは出来ないな
C++0xではm_a{0}って書けるようになるけど今は無理
>>286 逆だろ。
memset を使っても int なら問題ないが、 std::fill のほうが見た目も安全で望ましい。
読みやすいコードの定義の1つに 例えばDWORDの変数を宣言するとき DWORD dwPoint; DWORD dwStack; などdwをつけて分かりやすくするなどは入りますか?
>>296 そうなんですが、理論上ではどうかと思いまして
>>297 ハンガリアンでぐぐったらその辺の議論はでてくるかと
あまり意味がないとされることが多いと思うよ
>>295 std::fill ってどこまで最適化されるのん?
>>300 実装依存だから何とも言えんな。
気になるなら試せば?
>>298 理論上は、コンパイラの実装や最適化の影響によってどうなるかわからないから同じとも違うとも言えない。
MFCなんかはシステムハンガリアンそのものだもんなぁ
まあ実測したところで明日には古い知識になるかもしれないってことだよな 気にしないのが一番だ
#include<stdio.h> void main(void); void main(void) { char c='c'; printf("c='%c'\n",c); if(c>='a' && c<='z'){ printf("cは小文字です\n"); } else{ printf("cは小文字ではありません\n"); } if(c>='0'&&c<='9'){ printf("cは数字です\n"); } else{ printf("cは数字ではありません\n"); } if(c=='+'||c=='-');{ printf("cは符号です"); } else{ printf("cは符号ではないです\n"); } } をBCCでコンパイルしようとしたら 「elseの位置が誤っています」とエラーが出ます。 間違えをご指摘お願いします。
if(c=='+'||c=='-');{
指定された日付(2008/1/17)を gettimeofday()関数で扱ってる double型の数値に変換したいのですが どうすればいいのでしょうか
(double)
310 :
305 :2009/01/17(土) 19:19:52
キャスト演算子をオーバーロードした時に疑問に思ったのですが これを使うと戻り値はコピーか参照かどっちでしょうか
普通に代入するだけなら、原則全てコピー
型が参照なら参照だし 参照でなければ値だ。
(Foo)bar = foo; とか無理なんだっけ
315 :
311 :2009/01/17(土) 19:37:50
>>307 gettimeofday()はdoubleなぞ扱わない。
年月日から1970/1/1 00:00:00からの経過秒を作りたいならmktime()
>>297 型をプリフィックスにするシステムハンガリアンには意味がない。役に立たない情報である上に、コードを修正するときの障害になる。型情報はコンパイラがチェックする方が正確。
意味をプリフィックスにするアプリケーションハンガリアンなら意味がある。カウンタだとか安全な値であるとか記憶クラスであるとかコンパイラがチェックできない情報を持たせると良い。
間違ったコードは間違って見えるようにする でググレ
でもまあ C++ ならクラスでカプセル化するのも手だけどな。
error C2664: 'fopen' : 1 番目の引数を 'LPTSTR' から 'const char *' に変換できません。 HRESULT FInit(HWND hWnd, LPTSTR filename); FILE *fp = fopen(filename, "rb"); 解決方法教えていただけませんか
Win32API 使ってんなら CreateFile 使おうぜ。 fopen じゃ共有モードも指定できないし。
LPTSTRを使ってるところを見るとUNICODEでビルドしてないか? たぶん_tfopenみたいなマクロ関数があるはずだが、そっちを使うべきだろう
ファイルの読み込みをCreateFileで行ったら 今までやっていた fseek()がCreateFileではどうやるのかが アドバイスいただけませんか
Windows APIの話はWin32APIスレがあるのでそちらでやってください。
ftell 相当のものがなくて fseek(fp, 0, SEEK_SET); 相当のものの戻り値で取得しないといけないとか fprintf 相当のものが無くて sprintf してから書き込まないといけないなど面倒臭いことも多い。 しかし、_tfopen だと別アプリから編集中のファイルを操作され放題。 _tfopen_s が使えるならそっちのがいい。
>>323 細かいオープンモードを指定したいがためにCreateFileW()を使いたいが、
その後の読み書きはstdioで行いたいという場合は、
1. _open_osfhandle()でHANDLEからCRTのファイルディスクリプタを取得
2. _fdopen()でファイルディスクリプタからFILE*を取得
すればよいぞ
VC++の場合はね
329 :
323 :2009/01/17(土) 23:16:36
レスありがとうございます これからはMSDNで調べてから質問します
システムハンガリアン記法をやめてアプリケーションハンガリアン記法を使えというレスはよく見るのですが、 アプリケーションハンガリアン記法の一覧みたいなものは無いのでしょうか?
>>330 そんなものはあるわけがない
アプリ独自のモデルに応じて設定するから「アプリケーション」ハンガリアンと
言ってるんだからさ
んでも、静的型の言語、特に型の別名をつけられるタイプの言語での
アプリケーションハンガリアンの重要性は、相対的に低いと思うよ
LispだのPerlだのPythonだの使ってるんなら、変数の名前で何者かを示すことが
ものすごく重要なことが多いと思うけどね
マルチバイトとUnicodeどっちでビルドしたほうが有効性が高い?
>>319 明示的にキャスト汁。
C++ではポインタの暗黙の型変換はvoid*にだけじゃなかったっけ。
今ならUnicodeにしとけ 9x系なんて既にMSがサポート切ってるんだし MSLUもある
>>333 キャストして済ませようとすんじゃねーよボケ
最適化なしビルドから最適化ありビルドに変更して出てきたエラーの原因はなんですか? めちゃくちゃなんですけど
>>331 名前はWindowsに採用されたシステムハンガリアンに対して、Officeに採用されたアプリケーションハンガリアンと呼ばれているんだと思うぞw
命名規則を設計で決めるのはその通りだけどさ
批判も多いけど、場合によってはシステムハンガリアンがいい場合もあるな
>>333 これは酷い・・・
お前、地雷プログラマだろ
deleteについて質問なのですが ObjectA の中に ObjectBがある場合 delete ObjectA とする前に delete ObjectB; delete ObjectA; と中のものから消さなくてはいけないのでしょうか? もうひとつ質問させていただきたいのですが vecter<ObjectA> obje とあった場合に obje.clear() ではObjectAのデストラクタは呼ばれますか?
>>338 新人君がコンパイルエラーを無くすためになんでもかんでも
とりあえずキャストしてうまく動かないって言ってきたのを思い出したw
Aの中でBをnewしているのであれば、Aのデストラクタの中でBをdeleteしとけば問題ない
うへぇシステムハンガリアン記法思いっきりしてた 普段はやらないけど、グループでプログラム作るっていう課題があって 変数の命名方法決めようぜ!ってことで あぁ
Win32やMFC環境から始めた人は、システムハンガリアンに慣れてしまっても仕方ない気もするけどなぁ
職場の規約で強制されてる人も多いはず 規約を変えたりするのって非常に面倒なんだよね
_bstr_t にキャストするのであれば、あるいは
メモリリーク検出したら鬼のように出てきなさった {125} normal block at 0x003E7080, 352 bytes long. Data: < ? > 00 00 80 3F 00 00 00 00 00 00 00 00 00 00 00 00 ここから、どこが原因かわかるの? at 0x3E7080 とかいわれてもわからん・・
_CrtSetBreakAlloc(125);
std::stringと文字定数を大文字小文字区別せずに比較するにはどうすればいいですか?
>>348 352バイトと、1.0f(00 00 80 3f)もヒントになるかもしれない。
>>349 全部小文字(または大文字)に変換しながら(またはしてから)比較する。
352 :
351 :2009/01/18(日) 00:34:10
マルチバイト文字が入ってるなら wchar_t への変換が要るかもね。
353 :
349 :2009/01/18(日) 00:38:23
>>351 すみません、ASCII英数字のみです。
stricmp関数など、char型にする必要があるということですか?
==演算子か、compare関数など簡単にできないかなと・・
stdにはNoCaseとかないんだっけ?
c++には例外処理機構とかいうものがあるらしいですが、使い方がよくわかりません。 Ctrl+Cを検出してcatch節に処理を移したいのですが、下記のような操作は可能でしょうか? try{ char *buffer = new char[1024](); hFile = CreateFile(ほげほげ); // ほにゃらら }catch(なんちゃら){ delete []buffer; CloseHandle(hFile); // 後処理 } Ctrl+Cが押されたら、いきなりプログラムを終了するのではなく、それまでに動的に確保したバッファを解放したりしたいのですが・・・
>>353 stricmp() 使えるのか。
1文字の比較なら string の [0] 取ればいいし、文字定数が文字列定数のことなら
string の c_str() を stricmp() に突っ込めばいいだろ。
関数で簡単にしたいなら自分で定義すればいい。
>>355 コンパイルできないコード貼って可能かどうか聞く意味がわからん。
例外使うなら動的配列には std::vector 使え。
ファイルについても RAII に沿ったラッパーにする必要がある。
Ctrl+Cはイベントであって例外ではないだろう? 正常動作系を例外としてプログラムするのはちょっと
359 :
349 :2009/01/18(日) 00:57:02
そもそも現代的なOSならCtrl+Cしたらメモリは開放される。 ただ、メモリ以外のリソースは知らないがな!! Ctrl+C を検出するにはシグナルを使うことになるのかね。
>>355 ctrl+CはC++の機能じゃない。例外というよりも割り込み処理になる。トラップしたいならOSの機能を調べた方が良い。
WindowsならSetConsoleCtrlHandler
364 :
デフォルトの名無しさん :2009/01/18(日) 18:06:26
コンパイラはMINGW32でまさに今しがたプログラムの勉強を始めたばかりです 参考書に例題どおりの文字列(芭蕉の俳句)をメモ帳に ソースコードを書きコンパイルしたら error: syntax error before "printf" というエラーメッセージが出ました。 ソースコードは参考書通り打ち込んだんですが・・・
365 :
364 :2009/01/18(日) 18:07:42
これが上記のソースコードです #include <stdio.h> int main(void) { printf(" 夏\n") printf(" 兵草\n") printf("夢どや\n") printf("のも\n") printf("あが\n") printf("と") return 0; }
もう一回参考書と自分で書いたコードを見比べなさい。
セミコロンは?
368 :
364 :2009/01/18(日) 18:47:43
369 :
364 :2009/01/18(日) 18:56:37
恥のついでにもうひとつだけ教えてください
>>365 のソースコードからint、voidそしてreturn 0を
消してもMINGW上では正常にコンパイラされ実行もされます。
intやvoidを消しても大丈夫なのは理解できるのですが
return 0はソースコードの締めとして絶対必要なものではないのですか?
C89 : 無くても警告で済む。 C99 : 無ければ return 0; が補填される。
371 :
364 :2009/01/18(日) 19:26:50
372 :
デフォルトの名無しさん :2009/01/18(日) 20:42:28
大元の流出報告スレ
仁義なきキンタマ ウイルス情報 Part80
http://changi.2ch.net/test/read.cgi/download/1229742858/546 546 :[名無し]さん(bin+cue).rar :sage :2009/01/04(日) 00:24:59
報告する時は、詳しく的確に、一部だけ報告しないでお願いね
[殺人] Administrator(20081230-101522)のキンタマ.zip 2,263,376,860 09ed98f10653c3fc2555621ceeed6bc33e8f6228
[殺人] Administrator(20081230-101522)のメール.zip 59,426,579 4da9459b30eec31f58b86530dbb48d1cf86ef4be
[写真集][IV] Administrator(20081230-101522)のアルバム.zip 2,205,946,474 9d87cc0e08dc0e3afd959fcead6c48d569787cee
膨大な量のファイル数キンタマ ファイル数 13508 フォルダ数2381
以前勤めてた会社の資料など多数 独立行政法人情報処理推進機構などの資料など無いと思うが
有るかも知れない、あまりにも数が有り過ぎる、メールなどは、古いものばかりメルマガなど膨大な量
個人情報などは、披露宴主席者などの住所、名前、電話、メール 数十人分しかしエロばっかり落としてるな
ちなみに ハメ撮りscr 踏んだみたいね
早稲田実業学校中等部卒業
早稲田実業学校高等部卒業
早稲田大学政治経済学部政治学科卒業
卒論「知的財産権とインターネット技術」
当時の同大学理工学大学院の大川功 賞佳作を受賞
コンピュータ関連会社に入社ソフトウェア開発の仕事を経て
2005年に独立行政法人情報処理推進機構に入社
ソフトウェア・エンジニアリング・センター企画グループに配属
同グループ主任 岡○さん33歳
373 :
デフォルトの名無しさん :2009/01/18(日) 20:43:06
374 :
デフォルトの名無しさん :2009/01/18(日) 20:43:43
375 :
デフォルトの名無しさん :2009/01/18(日) 20:44:12
376 :
デフォルトの名無しさん :2009/01/18(日) 20:44:36
コピペ君って馬鹿だな、まで読んだ
list<vector<int> > lst とやってイタテレータで *lst[0] みたいにアクセスしたいのですが上手くいきません。 こういう場合はどういう使い方をすればよいのでしょうか。
何がやりたいのか分からん。
vector<vector<int> > lst;
vector<int> vct(2);
vct[0] = 1, vct[1] = 2;
lst.push_back(vct);
lst.push_back(vct);
vector<vector<int> >::iterator it, itEnd;
it = spMv.begin(), itEnd = spMv.end();
while(it!=itEnd) cout<<*it[0]<<","<<*ti[1]<<endl;
>>379 こんな感じな事がしたいのです。
すみません、誤字がありました…。 vector<vector<int> > lst; vector<int> vct(2); vct[0] = 1, vct[1] = 2; lst.push_back(vct); lst.push_back(vct); vector<vector<int> >::iterator it, itEnd; it = lst.begin(), itEnd = lst.end(); while(it!=itEnd) cout<<*it[0]<<","<<*it[1]<<endl;
(*it)[0]でいいんじゃね?動かしてないからわからないけど
(*lst)[0]
>>382 出来ました! 教えて下さりありがとうございました。
(*it)[0] だな。 演算子の優先順位の問題だ。
vectorみたいな連続したメモリのend()イテレータから実アドレスを得たい場合、 --itr; (&*itr) + 1; とやるしか無いのでしょうか?
vector みたいな、って、vecotr 以外で得る必要のある場合があるのか? (vector 以外で得たとして、まともに使えるのか?) vector のイテレータからなら、そうするしかないんじゃね。 イテレータからでなければ &v[0] + v.size() でいいと思うが。
>>387 やっぱそうなりますか。
>vecotr 以外で
boost::array::iteraterとか。
boost::circular_buffer::iteraterなどでも制限があるけどまぁ意味あるかな。
大抵の環境なら &*end() でできる気はするが 保証はされてないんだろうな。
end()はデリファレンスしちゃダメ。begin()==end()の可能性もあるから無条件に>386してもダメ。
元の質問者ではないんですが、その場合もオーバーライドと言っていいのでしょうか?
規格でも、*で逆参照するまではまだ平気で、その左辺値から右辺値を取りだしたり代入したりするときに はじめてアクセスが起こるという考え方になっていなかったっけ? もしそうだったら、operator *がreturn *p;で参照型を返すというような 単純な実装になっていれば平気だと言えるはず。 その保証がないだろうから、結局やめておくべきだろうけど。
*が逆参照とは限らない iterator::operator*が何をやってるかわからない以上しないのが無難
396 :
デフォルトの名無しさん :2009/01/19(月) 20:32:04
ど素人です、質問です #include <stdio.h> main() { int k; for (k=0;k<1000;k++); printf("sunrise\n"); } このソースコードをmingwで実行するとmingw上で”sunrise”が1000回 でると思ったんですが、そういうわけではないのですね
"sunrise\n"が一回しか表示されないように書かれてるからな
ど素人がぶら下がり構文なんか使おうとするんじゃありませんっ
>>398 #include <stdio.h>
main()
{
int k;
for (k=0;k<1000;k++);
{
printf("sunrise\n");
}
}
こうですね、わかります
400 :
396 :2009/01/19(月) 21:27:35
#include <stdio.h> main() { int k; for (k=0;k<1000;k++) { printf("sunrise\n"); } } おまえらあんまりおちょくってやるなよ
いくら初心者でも、自分が参考書どおりに書けてるかのチェックできるでしょ。
404 :
デフォルトの名無しさん :2009/01/19(月) 21:48:04
forの行の;を削除
405 :
396 :2009/01/19(月) 21:54:16
ありがとうございました
俺はパっと見、分からんかったwwwww forの後ろにセミコロンとか、滅多に見ねーw
初心者歓迎スレと聞いて飛んできました。 本当に初歩的な質問で申し訳ないのですが struct kouzoutai{ int menbahensuu; }; int kouzoutaihensuunokosuu=3; struct kouzoutai kouzoutaihensuu[kouzoutaihensuunokosuu]; こうすると「定数式が必要」と出てエラーが出ます0。 構造体変数の個数を変数で管理したいのですが、無理なのでしょうか?
>>407 それはC99から使えます
それ以前では使えません
>>407 変数じゃだめだな。
C++なら、
const int kouzoutaihensuunokosuu = 3;
Cなら
#define kouzoutaihensuunokosuu 3
で。
>>408 買った本の発行日が2006年なのでそんな古い規格では無い・・・と信じたい
>>409 前者です。動きました!
これで構造体変数の個数を変える時にそれに関わるfor文まで一々直さなくて済みます。
本当にありがとうございました!
どうしても変数にしたいなら new するくらいしかないな 当然deleteが必要になるがw
C99は最新のコンパイラでも対応してないことがザラだから
>>410 > 買った本の発行日が2006年なのでそんな古い規格では無い・・・と信じたい
最新のgccだって、オプション付けなきゃ通らないだろ
最近の現場でも、やっぱり主流はC89くらいか?
>>412-413 そうなんですか
HSPから移ったばかりでそこら辺がどうにもよくわからず・・・
ありがとうございました
大体C89/90が主流だろ C99を積極的に使ってる話はほとんど聞いたことがない それでも標準化委員会は懲りずにC1Xというのの策定を進めてるようだが
あれ・・・C++0xは? ^^;
そっちはC++の新規格だ
FORTRAN77がそうであったように 最初の「標準規格」には皆こぞって準拠させようとするけど それ以降の新規格にはベンダーの姿勢がまちまちな場合が多いよね。 書かれるコードも「最初の規格に準拠したものなら動かせる」ように努力するから 「動かすには最新規格に準拠した処理系が必要」なコードはなかなか生産されないし。
>>419 FORTRANみたいに、おじいちゃん先生が教えてる言語は基準にならないだろ・・・
こういうのがゆとりっていうんだろうね
>>411 動的配列は new より先に std::vector を薦めるべきだ。
C++のdynamic_castは型が不適当な場合0を返しますが、Cのようなキャストでは型テストは行われないのですか? つまり、速度はCキャストの方が上ですか?
dynamic_castはコンパイル時に静的に解決できるかどうか判断してくれるので、 お前の心配は無駄なことだといえる
425 :
デフォルトの名無しさん :2009/01/21(水) 15:22:02
初歩的な質問です。 CSVのデータを1行づつ持ってきます。その後カンマで分割し、それぞれを全てバイナリでテーブル形式にします とあるのですが、テーブル形式とはなんでしょう?バイナリとは? 教えてくださると助かります。
426 :
423 :2009/01/21(水) 15:27:01
ありがとうございました。
>>425 テーブルは表のこと。配列を使うことが多い。
バイナリは内部表現形式のこと。"abc"のバイナリは(普通は)0x61, 0x62, 0x63, 0x00。
って説明しちゃうと混乱するかなぁ。
プログラムで扱うデータは全部バイナリなんで、その文章中の「バイナリで」はあまり意味がないよ。
それとも、数と解釈できる文字列は整数型か浮動小数点型にするって意味なのかな?
CSVデータとして扱ってる間はそんなことしない方がいいと思うけど。
428 :
デフォルトの名無しさん :2009/01/21(水) 16:00:00
>>427 ありがとうございます。
とすると、バイナリというのは16進数ということですか?
それと、テーブルの指定で
31 0
|データ1|データ2|
|データ3|データ4|
というのが在ったのですが、この場合どう配列を作ればいいでしょうか?
ちなみに全て数値で、データ1のみ16進数です
>>428 >とすると、バイナリというのは16進数ということですか?
16進を使うのは、バイト単位で区切られているものの列を人間が見易いようにするため。
コンピュータの内部は2進。だからバイナリという。binaryは本来は2進数という意味。
(以上わかってたならいいんだけど念の為説明。わかってたら無視して。)
> 31 0
> |データ1|データ2|
> |データ3|データ4|
うーん、うまく解釈できない。
あなたに要求を出した人に、あなたが要求の仕様を理解できるように説明してもらうべきです。
430 :
デフォルトの名無しさん :2009/01/21(水) 16:48:31
>>429 すみません、ありがとうございます。
多分、short型にするということかな・・・?と思ったのですが、あまり詳しくないので聞いてみました。
そうですよね。忙しそうなので聞きづらかったのですが聞いてみます
敢えてコミュニケーションの訓練のために仕様を曖昧にすることもあるけどねぇ。 まさか2chで聞くとは思ってもいないだろうよ。
csvに入ってる数字を、int〜doubleで格納汁って事じゃないの? atoiとか使ってさあ。どんなデータか知らないけど。
バイナリっていってるからな そのままダンプするともとれる
ヌル文字の'\0'と0はいっしょなの? よくchar型配列に文字列の終端として0を入れてるソース見るけど ありえないだろうけどヌル文字が値0じゃない環境の為に常に'\0'でかくべき っていうスタンスは要らぬ気遣い?
>>434 \141 は何を表す?
\x61 は何を表す?
では \0 は?
>>435 8進数の0ってこと?
それは説得力ないなぁ
>>434 ヌル文字の文字コードは0であると規格で規定されている。
ただ、0 と書くより '\0' と書いた方が文字である事が分かりやすくはある。
>>436 本当に8進数の0です。
438 :
デフォルトの名無しさん :2009/01/21(水) 20:35:39
CDXInputクラスのpublicにDirectInputを初期化する関数を作りました その一部に // 利用可能なゲームコントローラーの列挙関数を実行 if(FAILED(m_pDInput->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY))) { return E_FAIL; } という部分があるのですがビルドすると error C3867: 'CDXInput::EnumJoysticksCallback': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&CDXInput::EnumJoysticksCallback' を使用してください とエラーが出るので指示通り引数の一部を&CDXInput::EnumJoysticksCallbackと変えたら error C2664: 'IDirectInput8W::EnumDevices' : 2 番目の引数を 'BOOL (__stdcall CDXInput::* )(const DIDEVICEINSTANCE *,void *)' から 'LPDIENUMDEVICESCALLBACKW' に変換できません。 とエラーが出ます。 解決方法教えていただけませんか ちなみにEnumJoysticksCallbackは同じクラス内のpublicにBOOL CALLBACK CDXInput::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, void *pContext) としてあります
>>438 EnumJoysticksCallbackにstatic付けておけ。
おそらく、EnumDevicesでNULLを渡しているところにthis渡せばいい。
すると、EnumJoysticksCallbackのpContextから渡したthisが取り出せるという仕組みのはずだ。
ヌル文字って英語でなんていうの?
null character
テリー伊藤 < ヌル文字って何?
443 :
デフォルトの名無しさん :2009/01/21(水) 21:53:52
初心者ですいませんがC#なんですけども、10万個くらいの配列のデータの正規化をしたいのですが、どのようにすればいいのかまったくわかりません。誰かご教授いただけないでしょうか?
スレ違い
77
448 :
439 :2009/01/21(水) 22:55:37
EnumJoysticksCallbackにstaticをつけたら
>>438 のエラーはなくなりましたが
その代りに
'->SetProperty' : 左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。
'->CreateDevice' : 左側がクラス、構造体、共用体、ジェネリック型へのポインタではありません。
静的でないメンバ 'CDXInput::m_pJoyDevice' への参照が正しくありません。
=======================================================================================
if(FAILED(m_pDInput->CreateDevice(pdidInstance->guidInstance, &m_pJoyDevice, NULL))) {
return DIENUM_CONTINUE;
}
=======================================================================================
と新たに3つエラーが出てきたので
クラスのprivateで宣言されている
LPDIRECTINPUT8 m_pDInput;
LPDIRECTINPUTDEVICE8 m_pJoyDevice;
にstaticをつけたらエラーはなくなりましたが
外部シンボル ""private: static struct IDirectInputDevice8W * CDXInput::m_pJoyDevice" (?m_pJoyDevice@CDXInput@@0PAUIDirectInputDevice8W@@A)" は未解決です。
外部シンボル ""private: static struct IDirectInput8W * CDXInput::m_pDInput" (?m_pDInput@CDXInput@@0PAUIDirectInput8W@@A)" は未解決です。
というエラーが発生しました
解決方法ご教授ください、宜しくお願いします
ちなみにスレ違いだったら申し訳ないです・・・
長文失礼しました
お礼忘れてました><
>>439 レスありがとうです
静的メンバ関数と普通のメンバ関数の違いを理解したうえで、
>>439 を読み直す。
451 :
448 :2009/01/21(水) 23:31:31
下調べ不足で申し訳ないです 静的メンバ関数とメンバ関数の違いを理解しました 実体を宣言していなかったので LPDIRECTINPUT8 CDXInput::m_pDInput = m_pDInput; LPDIRECTINPUTDEVICE8 CDXInput::m_pJoyDevice = m_pJoyDevice; と宣言したら無事ビルドできました。 ありがとうございました
452 :
デフォルトの名無しさん :2009/01/21(水) 23:40:19
#include <stdio.h> int main() { int x = 0; while( x < 10000 ) { printf("ループ%d回目です\n", x ); x++; } printf("ループ終了"); return 0; } キー入力でこのループを止められるようにしたいんだが これからどうすればいいのかわからん 助けてくれ
455 :
デフォルトの名無しさん :2009/01/22(木) 00:00:56
環境というのがいまいちわからんが windowsXPでVisual Windows for BC++ってソフト使ってます
>>448 その2つにstaticつけちゃ意味ないだろ。
457 :
デフォルトの名無しさん :2009/01/22(木) 00:12:14
458 :
448 :2009/01/22(木) 00:28:50
>>456 staticをつけないでできる方法はどんな方法がありますか?
アドバイスください;;
staticなEnumJoysticksCallbackをこうする。 BOOL CALLBACK CDXInput::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, void *pContext) { return static_cast<CDXInput*>(pContext)->(pdidInstance); } んで、非staticなBOOL CDXInput::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance)を作る。 当然、この中では非staticなメンバにもアクセスし放題というわけだ。 そして、EnumDevicesの3番目の引数に必ずCDXInputのthisを渡すこと。
struct **hogeをfreeする場合の正しい文法は free(*hoge)でいいの?
アロケートの仕方にもよるけど、それでいい場合もあるんじゃないかな
BOOL CALLBACK CDXInput::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, void *pContext) { return static_cast<CDXInput*>(pContext)->pdidInstance; } としたのですが error C2039: 'pdidInstance' : 'CDXInput' のメンバではありません。gamelib.h(787) : 'CDXInput' の宣言を確認してください。 と出ます。 pContex->はCDXInputクラスの関数とメンバ変数が出るので詰まってしまいました static_castなどでググっても解決しなかったので教えていただけませんか 宜しくお願いします ちなみに return static_cast<CDXInput*>(pContext)->(pdidInstance); とするとエラーで出まくります error C2059: 構文エラー : '(' error C2143: 構文エラー : ';' が '__stdcall' の前にありません。 error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません こういう感じのが30個くらい
XMLのデータに日本語を使いたくてUTF-16にしたんですがIEで開けません。どうしてですか?
>>462 何がしたいのかよく判らんが、CDXInputのメンバを参照したいのでなければそのキャストはおかしい。
逆に言うと、そのキャストはCDXInputのメンバを参照する目的に適っている。
pdidInstanceとやらがCDXInputのメンバでないのなら、そりゃぁエラーにもなるさ。
>>459 は間違ってるだろ。
staticなEnumJoysticksCallbackはこう。
BOOL CALLBACK CDXInput::EnumJoysticksCallback(const DIDEVICEINSTANCE *pdidInstance, void *pContext)
{
return static_cast<CDXInput*>(pContext)->EnumJoysticksCallbackNonStatic(pdidInstance);
}
そして、非staticなEnumJoysticksCallbackNonStaticを作る。
BOOL CDXInput::EnumJoysticksCallbackNonStatic(const DIDEVICEINSTANCE *pdidInstance)
{
//メンバにアクセスし放題
}
なんだ、継続してた話題だったのか。コテないから無視してしまった。
int i = fread(buf, 1024, 1, fp); if(i) fwrite(buf, 1024, 1, fp); こういう風にするとデータが1024byte未満の場合、iが0になって書き込みがスルーされてしまいます。 1byteずつ読み書きするようにしてやれば意図通り動くのですが、遅くて使い物になりません。 C/C++で大きな容量を一度に読み書きするにはどうすればいいのでしょうか?
int i = fread(buf, 1024, 1, fp); if(i) fwrite(buf, 1024, 1, fp); ↑
int i = fread(buf, 1, 1024, fp); if(i) fwrite(buf, 1, i, fp);
>>468-469 ありがとうございます
fread(buf, 1, 1024, fp)
fread(buf, 1, 1, fp) //*1024
この二つは同じことだと思い敬遠していましたが、全然違いますね
>>470 前者は1回しか関数が呼び出されないが後者は1024回の関数呼び出しが行われるからな
472 :
462 :2009/01/22(木) 17:52:44
コマンドライン引数で受け取った複数のファイルをむにょむにょするコンソールプログラムを作っているのですが ある一定の数以上渡すと(プログラム本体にD&D)アクセス権がないと表示されます。 なにか文字数等の制限でもあるんですか? OSはWinXPです
476 :
472 :2009/01/23(金) 06:42:52
>>464 返事遅れて申し訳ありません
やりたいこととは
DirectInputを初期化して使用可能にするクラスを作っていたのですが
使用可能なコントーラーを列挙するCallback関数を作るときに
>>438 のエラーが出たので質問したらstaticをつければいいってことなのでその方向で
やってました
静的メンバ関数と静的メンバ変数は、クラス名前空間の中だけどクラスインスタンスの外側にあります。 ますそこを理解してから、どのようにすれば静的メンバ関数にクラスインスタンスの内容を渡せるのか考えてみてください。 何でも言われた通りにするだけではなく、きちんと意味を理解すべく自助勉強しましょう。 なお、このメッセージに対する返答は必要ありません。読み終えたら、ただちに自習を始めてください。
478 :
デフォルトの名無しさん :2009/01/23(金) 10:04:39
LinuxでCやC++のプログラムを作る場合、 いまだにemacs上でシコシコやるのが一般的なの? eclipse + cdt とか邪道?
俺は jude とかで設計して emacs でシコシコ。 そういえば C++ なフリーソフトのプロジェクトって設計資料どうしてんだろ。
480 :
デフォルトの名無しさん :2009/01/23(金) 12:04:49
静的メンバ関数から、静的でないメンバ関数を呼び出すことができません。 staticにする以外できないから。
481 :
デフォルトの名無しさん :2009/01/23(金) 14:05:14
8000という10進数を 15 0 ├┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┤ 8 0 0 0 こんな感じで4バイト区切りで変数に格納したいのですがどうやるのでしょう? 格納後、1000|0000|0000|0000| となっていてほしいんです
んなアホな
インスタンスへの参照さえあればprivateメンバにだって自由にアクセスできるが
483は
>>480 な。
てかお前ら書き込みすぎだろwww
>>481 とりあえず自分で書いたコードを貼ってくれ。意味がわからん。
>>481 4「ビット」の間違いだよな?
BCDとかパック10進数とかでぐぐれ
>>481 4バイト区切りじゃなくて4ビット区切りだよね。Packed BCDという形式。
ある数Aを10で割った余りは、Aの10進表記での1の位の数なんだ。
ある数Aを10で割った商は、Aの10進表記での1の位を除いた数なんだ。
これを繰り返すことでAの 1の位の数, 10の位の数, 100の位の数, ・・・ を得ることができる。
それらを収めたい位置にシフトして足せば終わり。
このシフトして足すのも、普通は割るのと同じループ内でやってしまう。
マルチだが c言語によるgmres法のプログラムがあったら教えてもらいたい。 今日どうしても必要なんだ。
>今日どうしても必要なんだ。 急ぐならならマルチはやめるべきだね。
以下のようなことがしたいのですが、 何か方法はありませんか? typedef struct { int a; int b; } structure; void hoge( structure::int* p, structure* p0, structure* p1 ) { printf( "%d %d\n", p0->*p, p1->*p ); } void hogehoge( void ) { structure a, b; a.a = 0; a.b = 1; b.a = 2; b.b = 3; hoge( &structure::a, &a, &b ); hoge( &structure::b, &a, &b ); }
>490 すみませんでした 反省します
>>492 ぐぐったらそれっぽいコードが結構出てきたよ?
>>491 配列にしてindexを指定するのはダメ?
495 :
491 :2009/01/23(金) 15:31:47
>>494 ポリゴンの座標や回転、拡縮などの値を
キーフレーム毎にグラフにしたいのですが、
既にクラスは使用されていてかつ、
intやfloatが入り混じっているため
templateで解決したいなぁ、と。
やっぱりunionあたりで解決すべきなのかなぁ・・・。
>>491 メンバaを呼ぶ関数とメンバbを呼ぶ関数を作って、関数ポインタを使って切り替えるってのはどうかな
そんなことしなくても、普通にメンバのオフセット使えば良いと思うよ
>>491 C++を使う。
まさにそれ、メンバへのポインタと言う。
その中のstructure::int* pをint structure::* pにして
<stdio.h>をインクルードすればコンパイル通る。
>>491 offsetofとかその手のマクロの利用で可能
ってtemplateゆーことはC++か じゃぁ出番無いわごめんね
SK法とソートどっちが重要ですか?
Cのマクロでreturnっぽい動作ってできますかね? できるはずなのですが、いまいち書き方がわからないです。
#define MacroReturn return
#define RETURN return
508 :
デフォルトの名無しさん :2009/01/25(日) 23:31:54
ワロタwww
伝統芸能マクロリターンか
マクローリンタンに見えた
マクロリターン展開という奴か。 昔数学で習ったような。
そろそろ飽きてきたよ
win32apiスレでやれ
514 :
デフォルトの名無しさん :2009/01/26(月) 00:26:42
なんでいきなりWin32APIなわけ?
文字列へのポインタ char* s が与えられてるとき,これを標準ライブラリのstringに 変換するにはどうすればいいでしょうか? string str = new string(*s) とすると 「'char' から 'const std::allocator<_Ty> &' に変換できません。」 というコンパイルエラーが出ました。@VisualStudio2008EE
string str = s; string *str = new string(s); // これはあんまりやんね
>>516 ああポインタそのまま使えるんですね
どうもありがとうございました><
518 :
491 :2009/01/26(月) 14:12:36
>>496-501 お礼が遅くなり申し訳ありません。
>>496 ゲッターをインスタンス化するのは
私個人のイメージ的によくないのです・・・
>>497 ありがとうございます。
自分なりに考え、以下のように実装してみました。
structure* p(0);
hoge( (int)&p->a, &a, &b );
>>498 そんな書き方があるのですね。
試してみます。
ありがとうございます。
>>499 ,501
offsetofというのは継承などが考慮されるのでしょうか?
>>518 > structure* p(0);
> hoge( (int)&p->a, &a, &b );
よりによって最悪な方法を選んだな。
520 :
491 :2009/01/26(月) 14:29:47
>>498 できました。
ありがとうございます。
>>519 やっぱりなにかまずいのでしょうか?
以下のように使っているのですが・・・
void hoge( int ofs, structure* a, structure* b )
{
int valuea ( *( (int*)( (char*)a + ofs ) ) );
int valueb ( *( (int*)( (char*)b + ofs ) ) );
/*略*/
}
>>520 ヌルポインタ p に -> を適用した時点で未定義動作。
offsetof() の典型的な実装ではあるけど、実際にそれをやっていいのは
動作保証のできるコンパイラ実装者だけ。
522 :
491 :2009/01/26(月) 14:38:03
>>521 そうなのですか・・・
ただ、VC上でテストしてみたところ、
想定していた値(オフセット値)が出てきたため
VCでメイクしている限りは大丈夫と
思っているのですがどうなのでしょうか?
VCのデバッガ上でもNULLポインタのメンバアクセス時は
オフセット値がthisポインタだったりしますし・・・
if(){ } と if() { } はどっちがいいと思いますか? 3年間自分の中で決着が付きません
俺はどっちも好きではない
質問ですAスライムとBゴブリンとCトロールをゲーム内で出現させたいとします この場合は例えば CMobA CMobB CMobC というクラスを3つ作るのと CMobというクラスを作り配列で一度にやるのはどちらがいいですか?
なんのためのクラスだよ CMobという抽象クラスを作って、それを継承したCSlimeとCGoblineとCTorolというのを作れ AやBやCは、クラス名というより変数名だ CMobがnameというメンバを持っているなら、そっちに保持してもいいけどな
俺はifの行にブロックを書くな つい最近だがelseは下のように書くようにした // 1つ目のifの中に入る条件のコメント if () { // ifの中で行う処理のコメント } // 2つ目のifの中に入る条件のコメント else if() { // ifの中で行う処理のコメント } 仮に間違ってelseより前に処理を記述しても、コンパイルエラーが起きてくれるからという理由 まぁ、所詮この辺は好みだよな・・・昔は違ったし
if () { } VC使うようになってこうなった。 理由は、エディタの行間を広くできなくて、{で一行分あけたいから。
俺もそのスタイル 理由は、目視でブロックを把握しやすいから
そうやってブロックわけしたいんだけどdo whileだけは悩む
C++だけでなく、Cも関係あるのですが、 stack overrun を検出するツールなどはありますでしょうか? 現在のテスト環境はlinux(kernel 2.6系), gcc(g++)です。 デバッグは主に、valgrindを使ってますが、coreをバックトレースすると、 スタックが壊れてるような感じになっています。
移動するなら移動元に一言書いておかないとマルチと思われるよ。 まして、移動先でも何にも触れてないし。 で、valgrindで何が不満なの?
スタックオーバーランてスタックオーバーフローと同じ?
スタックオーバフローはスタックが溢れて戻り先やら何やらを壊すことで、 スタックオーバランはスタックが暴走してスタック外のエリアを壊すイメージなんだが。
スタックが溢れると戻り先じゃなくてヒープが壊れない?
スタックじゃなくてスタックフレームが溢れるんだろうな。
>>536 スタックがあふれるも何か変だが、スタックが暴走するって意味不明すぎ
>>534 すいません、一言入れておくべきでした。ご指摘ありがとうございます。
valgrindもstackを一応チェックしてるっぽいのですが、
検出されない場合もあるので、困っております。
例えば、以下のような場合です。
(スタックでこのようなエラーを検出するのは無理そうな気もしますが。)
int main(void) {
int arr[10];
int arr2[10];
arr[12] = 20;
return 0;
}
void CClass::main() { static UINT __cdecl thread(LPVOID pParam); BOOL flag = 0; AfxBeginThread(CClass::thread, this, THREAD_PRIORITY_NORMAL); } UINT CClass::thread(LPVOID pParam) { While( flag == 0 ){ ; } } flagが静的じゃないとコンパイルエラーが出ます。 While( ((CMainFrame*)AfxGetMainWnd())->m_Class.flag == 0 ) とするとコンパイルはできるんですが、電源切らないと何も操作できなくなるんです。 動的な変数を別スレッドの中で使うにはどうすればいいんですか?
>>522 なんで標準で用意されたoffsetofマクロ使わずに自分で再発明しようとするの?
話はそこからだ
void CClass::main() { static UINT __cdecl proxy(LPVOID pParam); UINT thread(); BOOL flag = 0; AfxBeginThread(CClass::thread, this, THREAD_PRIORITY_NORMAL); } UINT CClass::proxy(LPVOID pParam) { CClass *const this_ptr = (CClass *)pParam; return this_ptr->thread(); } UINT CClass::thread() { While( flag == 0 ){ ; } }
おk合流な
>> 542 いや、なのでvalgrindでなく、他にstack overrunを検出できるようなツールはないかなーという質問でした。
ありがとうございます。 しかしlinux上のシステムなので、linux上で動くツールに関してはいかがでしょうか?
>>544 ありがとうございました。2段階にしてできました!
>>544 constはどういうことですか?はずしても動きますが、constを使ったことがないので教えてください
>>552 ここで訊くことこそ調べることです。
回答したくてしたくて仕方がない回答者に回答する機会を与えているのに
何がそんなに不満なんですか?
目の前のありとあらゆることに苛立ちを感じる青春真っ只中のボクちゃんですか?
>>547 gcc4 の -fstack-protector
>ここで訊くことこそ調べることです。 いいえ。
>>553 やめてくれ
俺はここでconstを使う理由を知りたいだけなんだ
教えてくれた本人にスルーされたらお前のせいだぞ
>>556 少なくとも、あんたが>551なのだとしたら「理由を教えてください」と書かないから混乱する。
それはさて、書き換えることが判っているオブジェクトじゃなければ、constをつけておくのはいい習慣だと思うが。
thx。静的でとらぶったのでこのconstは重要なのかと思った。 はずしても動くから心配だった。thx
BoundsCheckerって定期的に名前出てくるけどなんなわけ? なんでメモリリークの追跡とかいう基本的な機能がVSにはないの?
>なんでメモリリークの追跡とかいう基本的な機能がVSにはないの? あるよ。 BoundsCheckerはそれだけに留まらず、例えば関数単体試験なら入力条件を自動生成したり、 パフォーマンス分析をしたりといった機能がある。 激しく重いし、決して使い易いとは言えないけどね。
VSにあるやつってDEBUG_NEW? STLのメモリリークとかClose忘れとかはどうしようもなくない?
constを付ける習慣の無いヤツの書くソースは十中八九汚い。
まぁ書き手によらずC++のソースは十中八九汚いんだけどな。
必要だと思うまで絶対書かない なるべく短い方が見やすい
>>564 constが正しく設定されてないソースを組み込むと、プロジェクト全体に波及してぐちゃぐちゃになるからしっかり書いてくれ。
>>564 constが必要にならないプロジェクトは十中八九才能の無いヤツが関わっている。
プロジェクトは十中八九才能の無いヤツが関わっている。
君のレスなんて読まないよ
>>567 > constが正しく設定されてないソースを組み込むと、プロジェクト全体に波及してぐちゃぐちゃになる
ソースレビューでしょんべんちびるくらい厳しく突っ込むといいよ。
それで直らないならリーダに文句言って変えてもらえ。
引数の定義でのconstはちゃんと使おう。 ローカル変数へのconstはそれほどがんばらなくてもよいと思うぞ。
>>572 C++の話だけど、引数だけでなくメンバ関数のconstもちゃんと使うべき。
参照とポインタとメンバ関数にちゃんとついていれば 後はなんとかなりそうな気がする
メンバ関数のvolatileのこと時々でいいから思い出してください
前の会社の課長はconstを使おうという気が全く無かったな。
「メンバ関数にconstが付いてないからconstポインタから呼べないんですけど」
と言ったら、「constにしなきゃいいじゃん」と言われて唖然とした。
その課長のソースは
>>562 のように恐ろしいほど汚かったw
BoundsChecker重いよなー 使ってたのは昔だから、今だとどうなんだろう
volatile コンストラクタや volatile メンバ関数は罠だからなあ。
580 :
デフォルトの名無しさん :2009/01/27(火) 22:05:43
OS:WindowsXP malloc関数を呼び出すといきなりクラッシュします。 引数も間違ってはいません。 どうしてなのか教えてください。
>>580 どっか、よそでヒープを壊してるんじゃね?
583 :
デフォルトの名無しさん :2009/01/27(火) 22:51:24
585 :
デフォルトの名無しさん :2009/01/27(火) 23:00:44
>>584 ,
>>582 ありがとうございます。
この他の可能性は一応無いと考えても良いのでしょうか?
ほぼ100%の確率でヒープを壊している。 しかしその間接的な原因は様々。
>>585 そんな保障はできないけど
とりあえず単体でそのコードを動かして動くかどうかやってみるとか
ソースを全部コメントにしてみてそのコードを入れて動くのを確認してから
徐々にコメントをはずしていってエラー箇所を見つけるとか
エラートラップみたいなのがないなら地道な努力しかないな
そうやって考えうる原因を1つ1つ潰していくしかない
mallocのオーバーライドみたいなのってできたっけ?
自分で malloc の代わりになる関数を作ればいい
でも各所で呼んである関数はmallocなんだなw
#define malloc my_malloc
オーバーライドというかラップになるな メンバ関数じゃないし
インターポジショニング
同じ名前使うなよ。。。 親クラスの関数を任意に呼びだせるわけではないんだし
標準で、ある程度チェックしてくれるのもあるよな。VCのデバッグ版とか。
596 :
デフォルトの名無しさん :2009/01/27(火) 23:59:23
なるほど。 みなさんありがとうございますm(_ _)m 勉強になりました。
俺が大昔組み込み向けに作ったデバッグ用の malloc() はユーザから見える割り当て領域より前に呼び出し元情 報を置いて、領域末尾にアドレスから計算されるチェッ クコード入れて適当なタイミングでチェックしてたな。
kwgt!
kbtms!
600 :
デフォルトの名無しさん :2009/01/28(水) 14:51:59
kgnms!
knbn!
kms!
void CApp::CTestStatic : public CStatic { public : double test[1] = {12}; } これなんでコンパイルできないんですか?
↑これなんでコンパイルエラー読まないんですか?
コンストラクタ初期化子で初期化するようにデザインされた言語だから。
なるほど コンストラクタで一括で初期化する場合はどうかけばいいんですか? test = {12}; とか test[] = {12}; とかやってもコンパイルできません
test[0] = 12;
ようするに、配列の非静的なメンバ変数をコンストラクタで初期化する方法がまだ無いということだ。
そらできんじゃろ。まずコンストラクタ書かないと。 CTestStatic() { test[] = { 12 }; } みたく。そういえば、配列って初期化子使えたっけ?
ちょっとまて ふざけてるのかマジな分かりかねるんだが
>607はマジだな。
あーすまん。 「配列って初期化子使えたっけ?」じゃなくて 「配列って初期化子リスト使えたっけ?」の間違いであります。 つまり CTestStatic() : test[] = { 0, 1, 2 } {} みたいにかけたっけ?
>609も>612もできない。
やっぱできないですよね コンストラクタでまとめて配列初期化するにはどうすればいいんですか?
それってつまり、クラス内では test[] 自体が使えないってことかしらん♥ double *test か double test[0] にしろってこと? っていうか、素直にコンパイラに聞いてみるか…むふん。
>>603 がPODならこれで行けるな
コンストラクタ作っちゃダメだけど
CTestStatic a = {12};
あとC++0xではこう書けるようになる予定
CTestStatic() : test{ 0, 1, 2 } {}
static const な配列を作って、 コンストラクタでそれをコピーすればいい。
急増品だけど動いたよ^o^ #include <iostream> #include <algorithm> #include <iterator> using namespace std; class hoge{ public: hoge() { for ( int i = 0; i != 5; ++i ){ d[ i ] = i; }; } void get() { copy( &d[ 0 ], &d[ 5 ], ostream_iterator< double >( cout, " " ) ); cout << endl; } private: double d[ 5 ]; }; class huga{ public: huga() { d = new double[ 5 ] (); for ( int i = 0; i != 5; ++i ){ d[ i ] = i; }; } void get() { copy( &d[ 0 ], &d[ 5 ], ostream_iterator< double >( cout, " " ) ); cout << endl; } ~huga() { delete [] d; } private: double * d; }; int main(){ hoge h1; h1.get(); huga h2; h2.get(); return 0; }
ありえない・・・・・
なんでnewしてんの?
#include <iostream> class Hoge { public: Hoge() : d0(12), d1(4), d2(40), d(&d0) { } int get(int i) { return d[i]; } private: int d0, d1, d2; int *d; }; int main() { Hoge hoge; for (int i = 0; i < 3; ++i) { std::cout << hoge.get(i) << std::endl; } }
boost assingn使えばいいんじゃない?
クラス内で{ }を使って配列を初期化することはできないんだね^^;
C++標準ライブラリにvectorあるんだから使え
>>624 一時変数使ってもいいならもちろん出来るさ
普通はこうする #include <iostream> class Hoge { public: Hoge() { static const int d[3] = { 12, 4, 40 }; memcpy(&m_d, d, sizeof m_d); } int get(int i) { return d[i]; } private: int m_d[3]; }; int main() { Hoge hoge; for (int i = 0; i < 3; ++i) { std::cout << hoge.get(i) << std::endl; } }
PODじゃないのにmemcpyして大丈夫?
int m_d[3]; はどう見ても POD
でもHogeはPODじゃないだろ 非PODのPOD部分をmemcpyって規格で許されてたっけ 現実的には問題ないことが多いと思うけど
つ[std::copy()]
copyは一個づつ入れるって決まってるじゃん、と思ったけど今は書き方の問題で別に速くしたがってるわけじゃないか
>>633 セキュア関数を使えと文句を言われます!
static const int d[3] = { 12, 4, 40 }; コンストラクタにこれを記述したらコンパイルできたのですが 使おうとするとdはないと言われますどうしてですか?
static constだからグローバル変数だろ::dじゃね?
わかんね もういいや一個一個いれる
>>627 > int get(int i) { return d[i]; }
m_d いらねーじゃん(w
>>642 すまん。ミスだ。
return m_d[i]; が正しい。
>>627 おぉー、{ }を使って初期化できたー★
memcpyの代わりにcopyを使うと
>>636 の言うとおり警告が出たけど、でもちゃんと動いた。
>warning C4996: 'std::copy': Function call with parameters that may be unsafe
VC++ だと stdext::checked_copy か stdext::unchecked_copy を使えと言われるんだよな
std::copyでの警告を消すには_SCL_SECURE_NO_WARNINGSを定義するといい。
移植を考えないなら セキュア関数使った方がいいとは思うけどね
vcは常に移植しづらいcodeを書かせようとするから嫌いだ
MSがWindows以外で動くコードを書くのに協力するわけないだろ
650 :
デフォルトの名無しさん :2009/01/29(木) 01:05:05
WindowsのプログラムでPostQuitMessageを呼び出した後に CreateWindowでもう一度ウィンドウを作成して走らせるのはまずかったりするのでしょうか?
ちゃんとメッセージ処理でそうしても動くようにしてさえいれば問題なし。俺なんかはウィンドウの数だけPostQuitMessageしてる。
.NETもWindows専用のライブラリと化してるもんなw
struct *hogeっていうのがあって char *dataというのもあったとして (char *) hoge = data ってこんな変換おけなの?
memcpy的なことがしたいのか?
656 :
650 :2009/01/29(木) 02:15:08
>651 なるほど、安心しました。 ありがとうございます。
>>645 memcpy() はスルーで std::copy() に警告出すの?ザルすぎる。
if(){ A; C; } else if(){ B; C; } この場合Cのコードがダブってしまうけど, 関数にするほどの処理ではなくて,フラグ設定するのも返って読みづらくなる・・ という場合のうまい書き方って無いですか? Cの処理はA,Bの結果を受け取るので処理の順番を変えることはできません。
こういう風にはできない? hoge x; if() { x = A; } else if() { x = B; } C; //xを使う
>>659 それだと両方の条件が偽になったときにダメだろ。
>>659 レスどうもです。
xをあり得ない値で初期化しておいて
Cを実行する前にxの値をチェックするようにすればうまくいきますね。
がしかし,あり得ない値というのが将来あり得る値になるかもしれず
バグの元になりそうで怖い気がします。。
考え方はフラグと同じなのでおとなしくフラグ設定しておくのが無難なのでしょうか。
A,B,Cを関数にすればそんなにひどいコードの膨らみ方はしないだろ
>>658 最初のifの条件をaa、2番目をbbとしたとき、
if ((aa && A) || (bb && B)) { C; }
ただし、AとBは常に真のときに限る。
または、
if (aa) { A; }
else if (bb) { B; }
else { return; }
C;
ただし、問題の処理後にreturnするだけのときに限る。
まあどっちもアレなので、
>>658 のままでいいと思うが。
もうひとつ if (aa || bb) { if (aa) { A; } else { B; } C; } ただし、aaが副作用を伴わない場合に限る。
クラステンプレートじゃなくて、コンストラクタにテンプレート指定させるにはどうすればいいんでしょうか そもそもそんなこと出来ない?
>>665 std::mem_fun と std::mem_fun_t みたいな関係にすればよかろう
>>665 テンプレートクラスにすればいいんじゃないか?
668 :
665 :2009/01/29(木) 12:42:30
ありがとうございます。 クラステンプレートにしちゃうとそのクラスを引数で渡す関数なんかも テンプレートにしなくちゃいけないからめんどいんですよね^^; 親クラスをテンプレートクラスにして基底クラスを渡せば出来そうですが・・・ コンストラクタ自体にテンプレート指定はできなそうですね^^; mem_fun_tちょっと調べてみます
669 :
デフォルトの名無しさん :2009/01/29(木) 16:17:21
すみません質問です 同じ構造体をそれぞれ別の関数で参照したいのですが、 その時、同じ名前の変数で宣言しても出来ませんでした。おそらくローカル変数になる(?) ので同じ名前でも同じ物を参照できないということだと思うのですが、どうやればいいでしょうか?
>>669 グローバル変数にするか
それぞれの関数の引数に構造体のポインタを渡せばいい
673 :
デフォルトの名無しさん :2009/01/29(木) 16:31:56
>>670 うpしました
No.8779です。
他にも動的変数が〜と指摘されたのですがいまいち・・・
>>671 ,672
やはりそうですか。ありがとうございます
>>673 46行目で引数が無いってエラーはでるけど、変数名がどうのってのは出てないぞ。
Visual C++でビルドした時も、確かにそこしかエラーはでないのですが、これでは動かないと言われたので 自分なりに考えたのですが解らなかったので聞いてみたのですが大丈夫でしょうか? ついでですが、引数無しで別関数に移動ということは出来ないのでしょうか?
>>676 Cはオーバーロード無いんじゃね?
C++ならオーバーロードが使える。
今グローバル変数でやってんだろ? 関数の引数が無しならグローバルにする。 引数有りでいいならポインタ渡しする。 グローバル変数使うのがダメで引数使うのもダメならどうしようもない。
struct kirokutb WRbuff;はグローバルとローカルの二つあるな。 write_tbにあるローカルなWRbuffの宣言は要らなくて グローバルなWRbuffの方に書き込みたいんじゃないのか?
680 :
デフォルトの名無しさん :2009/01/29(木) 17:08:16
ありがとうございます。やはりグローバルで宣言すればOKのようです。 すいません、write_tbにあるWRbuffは消し忘れです。お手数おかけしました。
>653 cast as lvalue とも呼ばれるもので古い gcc では可能だった。
C++なら(char *&)hoge = dataと書けるだろうな。
まあ *(char **)&hoge = data で大抵の環境では動くだろ。 動かないのは sizeof(char *) != sizeof(hoge *) な環境だけだと思う。 バスエラーがどうの、なんてのは、 同サイズならどっちのポインタでも一緒だし。
C++のクラス宣言の中で char* states_[] = {"fine", "nomal", "sick"}; 見たいな感じで、文字列のリストを定義したいんだけど、 そのまま書くとコンパイルエラーになります。 定石みたいのがあれば教えてください。
>>684 staticにしたら、できなかったっけ?
>>684 無理、あきらめてコンストラクタでやるしかない
近いのだと、コンストラクタで
static const char* tmp[] = {"fine", "nomal", "sick"};
を宣言してコピーするという手もある
687 :
684 :2009/01/30(金) 00:12:04
内容変更しないのなら static const メンバ変数にすりゃええんでないの? クラス宣言内で初期化する事はできないけど、 実体定義時に初期化できるよ
>>687 class Hoge
{
public:
static char* states_[];
};
char* Hoge::states_[] = {"fine", "nomal", "sick"};
これでコンパイルできたけど、これじゃいかんの?
690 :
684 :2009/01/30(金) 00:30:06
691 :
デフォルトの名無しさん :2009/01/30(金) 00:30:25
char *str = L"hahaha"; という定義のLってなんですか?このLが無くても別に問題ないと思うんですけど。。
Lがあったらコンパイルできないと思うんだが。 L付きの文字列はワイド文字列だ。 const wchar_t *str = L"hahaha"; が正しい。
694 :
デフォルトの名無しさん :2009/01/30(金) 00:45:31
Lついてたらコンパイルできてませんでした。 wchar_tにしたらコンパイルできました。しかも出力するには std::wcoutとかを使わないといけないなんて、 こんな変なの用途があるんですか?
695 :
デフォルトの名無しさん :2009/01/30(金) 00:46:12
charとwchar_tは別物だ
ユニコード対応に使う
charだと256種類しか文字表せないから日本語とか入れられないだろ? そのためのcharのでっかい版がwchar_t まあwchar_tに日本語が入れられるとは限らないんだけどな
charと違って、大抵wchar 1つに漢字も仮名も収まるのが便利。 Windowsみたいにそうでならない可能性が高いやつもあるけど。
サロゲートペアの罠
701 :
デフォルトの名無しさん :2009/01/30(金) 03:09:53
リストコントロールでアイテムを選択するにはどうするの? 1 aaa.txt 2 bbb.txt 3 ccc.txt 上で2を選択して削除→3を自動的に選択にしたいんだが、 2を削除するとどのアイテムも選択してない状態になる…。 リストボックスのSetCurSelみたいなのがあればいいんだけど。
>>701 環境を書かないってことはどうせドザなんだろうけど、APIスレかMFCスレにでも隔離されててくれと思ってしまうな。
現在、開発中のプログラム(C++)がメモリフラグメンテーションして、 freeなメモリは結構あるのに、allocationに失敗する(Out of Memory)現象に遭遇しています。 プロセスのメモリの使用状況を確認できるようなツール・コマンドはlinuxにありますでしょうか? 今は、googleperftoolsなどを使ってますが、フラグメンテーションしてるかどうかはわからない(?) ので困っております。 どなたかわかりますでしょうか?
・フラグメンテーションが原因であることは確定してるの? 本当に「freeなメモリは結構ある」の?どうやって調べたの? ・本当にアロケーションに失敗してるの?mallocの引数がでかすぎになってないか ちゃんと確認したの? ・どのタイミングで失敗してるの?プログラムの起動直後?時間がたってから? 起動直後に多めに確保して使い回すとかを考える方が先じゃないの? ・フラグメンテーションの発生を確認したとして、それからどうすんの?カーネル改造するの? ・なんでUNIXスレやLinux板じゃなくてここで聞くの?ばかなの?死ぬの?
>>704 つっこみありがとうございます。
・フラグメンテーションが原因であることは確定してるの?
確定はしてないですが、たぶんそうです。valgrindをとおしてもリークはないですし、
top上のvirtualもrssも実メモリサイズに対してかなり余裕があります。(実メモリ4G、top上の表示は1Gぐらい)
・本当にアロケーションに失敗してるの?mallocの引数がでかすぎになってないか
ちゃんと確認したの?
確認しました。
・どのタイミングで失敗してるの?プログラムの起動直後?時間がたってから?
起動直後に多めに確保して使い回すとかを考える方が先じゃないの?
大きめのバッチで、起動後3時間ぐらいした後です。
mmap時にENOMEMが返ってきます。
・フラグメンテーションの発生を確認したとして、それからどうすんの?カーネル改造するの?
C++のSTLをかなり使っているためメモリ管理が不透明(自分があまりわかってないだけ)な部分がありますが、
メモリをpoolするallocatorを自作するなりして、フラグメンテーションが起きにくくなるように調整します。
・なんでUNIXスレやLinux板じゃなくてここで聞くの?ばかなの?死ぬの?
Linux板も見ましたがあまりいいのが見つからなかったので、ここで質問させてもらいました。
まあ、あとlinux上の話ですが、プログラムに関係するので。
いい板があったら教えてください。
>mmap時にENOMEMが返ってきます。 あのー、これって要はアドレス空間が足りないってことだよね。 確かにフラグメントでもアドレス空間不足は起きるけどさ munmapをちゃんとやってるか確認するほうがずっと先決だと思うんだけど。
>>706 普通にSTL(vector, set)で大量(512Mぐらい)のメモリを確保してはclearして、
というのを繰り返してます。
mmapは領域拡大の時にmunmapして、領域拡大して、mmapするという動作をします。
munmapした後に拡大した領域をmmapする際に出ます。
(大きな連続領域がなくなっていると予測)
フラグメントを見るコマンドとかってないんですかね?
pmapで見れるメモリマップっていまいち見方がわからないのですが、
pmapでもわかりますか?
vectorはclearしてもメモリ確保しっぱなしだけどそこは大丈夫なの?
swapでClear-and-minimizesしてます。 いや、フラグメントを減らす方法もいくつかわかりますが、 それを確認する方法がないので困っています。
64bitマシンでやる?
>>707 メモリを効率的に使う技術を持っていないなら、64bitOSに助けてもらうこと
めんどうだから別プロセスに確保して貰っちゃえ。
32bitで512Mを取ったり貼ったりしてたら確かに辛いだろうなぁ 512Mの領域って普通の設定だと6枚しか取れないぞ
むしろ512Mを解放して再確保するからフラグメントになるんだろ。 取ってそのまま再利用すればアドレスが足りなくなることはない。 複数確保なら知らんが。
データ構造を見直して分割確保したら?
つうか自作なら、自分で領域のアドレスをログれば良くね? 3時間で何回取り直してるのか知らないけど、最悪グラフ化すれば判るっしょ。 更にlifegame風に表示させたら面白そうだね。というよりdeflagツール風か。
>>707 > munmapした後に拡大した領域をmmapする際に出ます。
vector の話だとすると、拡大した領域の mmap を先にしないと要素のコピーができないよ。
このとき瞬間的にメモリ使用量は倍近くになるよ。 top で見えるサイズが 1 G あるなら、
この瞬間に 2 G 近くになってアドレススペースが不足する可能性が十分考えられるよ。
オープニングでアムロがコアファイターに乗るところなんだけど なんでノーマルスーツの色が青いんだ?
なんで最後アスラン自爆したのに生きてんの?
神龍に頼んで不老不死にしてもらったから。
CDXDevice *device; CDXDevice* device; この2つはどう違うのですか?
見た目
C言語よこんにちは的な初心者が出会っておくと得な C言語独習参考書と無料の統合開発環境を教えてください。
CDXDevice *device1, device2; CDXDevice* device1, device2; この2つはどう違うのですか? ><
見た目
>>724 参考書=K&R
IDE
windows=VS EE、QtCreator、Code::Blocks、DialogBlocks、DevC++
Linux=Code::Blocks、emacs、…monoとかも?
macは知らん
勧めてないけど、borlandが初心者にはやさしいかもな
>>725 *の回りにはいくら空白があってもいいんだってさ。
だから
CDXDevice * device1, device2;
こんな風に書いても一緒。見た目、掛け算と混同しちゃうけど。
この手の話題は結論出ないからなぁw そんなに答えが欲しいならスレ総力を挙げて本を作るのだ
お前らの方が良い本作れそうだなw あくまでも初心者対象としてだが
それは2chねらーに夢見すぎだw いかにも有能そうに、自分以上の存在を小馬鹿にする技術が 発達してるだけだよ、2chねらーなんてw
735 :
724 :2009/01/31(土) 23:33:52
結局独習Cにした。糞たかいが仕方ない。未来への投資と考えて・・・orz
Cの本かあ。 C++の本読めばCの内容も内包してるようなもんだから C++の本読めばいいと思うのは俺だけ?
そんなこと言ってるとC++の常識がCに通じないから危険だぞw 初心者向けの本って掴みから、読者が学習する路線やら基本知識まで掌握しないといけないから、 多人数の意見が混じり合うと、頭がおかしくなって死にそうだ
>>736 C++の勉強がしたいのならC++の本を読めばよいし
Cの勉強がしたいのならCの本を読めばいい
と俺は思います
「C++/CLIはC++を内包しているようなもんだから、全てのC++の学習者は
C++/CLIを学ぶべきだ」と考えますか?
考えないでしょう
継承を勉強する手前までの知識なら それほど大きな差はないと思うけど、 C不便って思われる点は大量にあるな。
>>738 C++/CLIは標準化を蹴られた実質窓依存の言語だし
比較として適当ではない気が・・・
C++は覚えておいて損はないと思うよ
>>740 ええと、「Cを学びたい」という学習者の意向や前提は無視するわけですか?
そうですね、Haskellは覚えて損は無いでしょう
HaskellでCは学べんだろう・・・
C++でもCは学べませんね 特にC99は
C99なんて誰も使ってないし…
でも、C++だけじゃないが、オブジェクト指向系の言語を勉強するなら 先にGoFあたりをガッツリ理解していた方が、クラスを変な解釈したりしないから良いと感じたことはある まぁ、実際にコード書いて動いた方が楽しいし、独習ならそっちの方がモチベーションは確実に上になるだろうな
で!俺のチョイスは間違ってるの!? おまえらだけで楽しそうに議論しないでおくれよ!
CとC++の違いを解説してるC++の入門書もあるし、 C使いづれえええええええ!!!!となる可能性はあるけど 大は小を兼ねるを期待するのも1つの道だ。 別にCの入門書を買ってもいいけどさ。
無難なところじゃないか
なるほど、自分の身勝手な決め付けを相手に強要する訳ですね Cではmalloc()の戻り値をキャストする必要は無いし main()はただの関数で再帰可能だし C++とCは結局のところ違う言語ですが、 Cを学びたいと言っている人間に、 「似たようなもんだからこっちにしとけ」とC++を無理やり教え込むのですか
選択肢を提示しただけでこれだけ文句言われるとはなあ。 強要なんてした覚えないしw
>>750 いやごめん
ちょっとヒステリックなおばさnごっこを
してみたくなったんだ
モンスターペアレンツ恐いです><
>>751 自意識ばっか膨れ上がった能無しのオタ男丸出しで、
ちっともおばさnごっこになってないよ。ただ誤読しただけでしょ。
>>753 あらら、おこっちゃったの?
ごめんなさいねぇププ
騙りって楽しいのかなあ
>>755 さっきまでは楽しかったけど、不出来を指摘されてムカついちゃったらしい。
たまにやると楽しいよ 君もやってごらん
よく知らない人はC++が「最新のC」で、Cを「機能制限版の古いC++」だと思ってたりするからな 完全に名前のせいだが そうじゃないことだけ理解してれば勉強する順番は自由
ある程度わかったら、MSDNの仕様書で十分だけど。
MSDN便利だよな VC6くらいのchmが軽くて良い ANSI C言語辞典は持ってるけど、こいつをchmファイル化して持っておきたいとはよく思う
>>760 むしろANSI C言語辞典のノリで現代版ANSI C++辞典がほしい。
英数編と五十音編の2冊くらいでそこそこの厚さに収まってくれないかな。
ANSI C言語辞典であの厚さだから ANSI C++辞典だとどのくらいのページ数になるんだろうか 流石に2冊には納まるか?
764 :
デフォルトの名無しさん :2009/02/01(日) 01:29:52
この商品に興味がある人は、こんな商品にも興味をもっています。 ガラスの仮面(43巻) チャンネルはそのまま!(1) 黒執事(6) オバマ大統領就任演説 ジェネラル・ルージュの凱旋(上) やだ・・・なにこれ・・・('Д')
上の3つを持ってる俺に謝れ
何でプログラムの本がないんだよw
以前何かの本で、エロゲーが結構長いこと表示され続けたのがあったなぁ。
vcprojっていう拡張子のファイルって何をするものですか?
VC++ のプロジェクトに関する情報を記述したファイル
>>768 Visual C++のプロジェクト。
どのファイルをどうコンパイルするかなどと言ったことが書かれている。
どうやれば使えるんですか?
vcbuildとmsbuildでぐぐれ
>>771 Visual C++をインストールすれば、ダブルクリックして開けるようになる。
>>772 調べてもよくわからなくて・・・無知ですいません
>>773 分かりました!ありがとうございます!
辞典と言えば、Wikipediaももう少し何とかなってほしいな。 現状だと事典ではなく辞典レベルだ。 それ以前にスカスカだけど。
お前が書けばいいじゃないか
wikiはユーザーが育てるものだろ 文句あるなら自分で補完しろ
日本は、声優とかビデオ女優の情報量だけは豊富だからな
wikipediaはCとかに偏った解説書くと「中立じゃないw」って言われて消されるからな あらゆる言語を満遍なく知ってる人しか書けないから敷居が高い
具体的にどの記事のこと?
>>775-776 やっているよ。でも今のペースじゃ英語版に追いつけるわけがない。
Java関係は日本語版でも記事の数は多くて羨ましい(中身の量はともかく)。
>>780 過疎すぎて消す人すら来ないように自分は思っているんだけどな。
constとか共用体とか、C特有の重要な概念の記事が抜けてるから書こうと思ったことはある でもC/C++以外にも一応あるからそれも織り交ぜないと行けないのが面倒で面倒で諦めた Dのinvariantとの違いとか調べたくねえよ
そんなものこうしておけばいい。 ==D言語== {{節stub}}
最終兵器スタブ
誰でも編集可能なのだから、知っていることを書けばいい。 Cに偏ったことであればCと書いておけばいい。 Javaではそうならない!という人がJavaについて追加すればいい。 それだけのことなのにね。
技術情報なんて日本語じゃなくてもいいじゃん。 英語編集に参加して後で翻訳すればいい。
ようするに語弊は有るが、英語版Wikipediaをパクって翻訳すれば
いつの間にか、翻訳記事の投稿時に、翻訳元の履歴から5人名前を拾って 要約欄に記載するという条件が無くなったので、前より少し楽になった。
Javaを勉強したのはもう15年くらい前の話だけど どの本もCまたはC++を知っていること前提に書かれていて 当時せいぜいVBしか使えなかった自分は面食らった記憶が…。
TalesWeaverのチートツール? ここじゃ鼬害だからMMOsaloonで聞けば?
まぁ何のツールかは言語の知識には関係ないんじゃないか?
>>791 何をお願いしたいのか分からん。
VC2008入れてビルドしたら良いんじゃない?
>>791 それでは私がmmosaloonの該当スレで質問してきましょうw
クラスや関数にもstaticは可能な限りつけた方がいいんでしょうか? 違うクラスで使う同じ関数がダブらないから効率がよくなるって解釈でいいんでしょうか?
そりゃ効率のいいコードにはなると思うけど、 コードの形だけでは実行速度はわからない。
メンバ変数を操作しないユーティリティ系のメンバ関数には付けるべき
thx。やっぱつけた方がいいのか。一度も使ったことなかった どのクラスのなかで宣言してようがstaticをつければグローバルになってどこからでも宣言なしで使えるようになるの?
言いたいことはなんとなくわかるが、グローバルかどうかはpublicかどうかが基準だ public staticであれば、クラスのインスタンスを作らなくても関数にアクセス出来るというだけ
staticメンバ関数とstaticメンバ変数はただクラス名の名前空間に、関数と変数を宣言してるだけ。 アクセスできるかはアクセス修飾子によって決まる。 クラス内部で使うとかグローバルとか関係ない。
thx!完全に理解しました。スコープがいらなくなるのかと思いました。 クラスのインスタンスを作っても、たとえばstatic関数だと、その部分の関数だけインスタンスが作られなくなるというだけですね。
>>803 C++でコンパイルする
ppm.h および関連ライブラリを探す
>>803 エラーが出たならエラーメッセージを晒すのは基本。
今回の場合はソースをアップローダに上げるのは必須ではないが、
もし資料をそのままコピーしていないのなら上げた方が話が早い。
まぁ、今回は恐らく>804だろうな。
806 :
デフォルトの名無しさん :2009/02/02(月) 23:59:46
質問させていただきます。 プログラムの中で class Object があった場合(メンバ関数に void func() を持つとします) Objectクラスを使うときに Object obj; obj.func(); とするのと Object* obj; obj = new Object(); obj->func(); とするのとの違いは何でしょうか? Object* で定義した場合はポインタなのでまだ実体が作られていないから obj = new Object(); が必要なのがわかりますが、違いが今ひとつわからず質問させていただきました。
mallocの必要性からやってきなさい。
Object objは一時オブジェクトだから、定義したスコープから抜けると消える。 newしたのはfreeするまで残る。
>>807 ,808 さん
返信ありがとうございます。
つまり特定のスコープの中だけで使う場合には new する必要はないということですね。
ありがとうございました。
>>808 free じゃなくて delete な
下記のソースで i = 0;の行を削除すると100が表示されず -8589.... といったようなでたらめな数値になります。 何か値を代入しないと変数の領域が取られないのでしょうか? 環境はVC++6.0です。 #include <stdio.h> int main() { int i; int *p; i = 0; /* この行を取ると結果が100にならない */ p = &i; __asm { mov ebx, p mov [ebx], 100 } printf("%d\n", i); return 0; }
>>812 アセンブリ出力を読め。納得したら、最適化オプションを変更しろ。
>>812 コンパイラの生成したアセンブリリストを比べるんだ。
「リストファイルの生成」とかそんなコンパイルオプションでいけるはず。
アセンブリ出力というのはどこにあるのでしょう?
何この間抜け。
そもそもデバッグビルドなんですけど最適化とか されちゃうんでしょうか?
なんか /FAっていうオプションつけたら出ました。
アセンブリを比較してみたんだけど ; Line 8 mov DWORD PTR _i$[ebp], 0 しか違わないです。なぜだー
VC のインラインアセンブラって自動でレジスタ保存してくれる・・・んだよな?
ごめんなさい。アセンブリが間違ってました。 下記のようにしたら100が出ました。 __asm { mov ebx, p mov DWORD PTR [ebx], 100 }
int* a; int *a; どっちのほうが見やすいですか?
Cではint *a;で、C++ではint* a;と書いている。
>>822 その違いで ポインタの複数宣言を分けるべきかどうか悩んだことがある。
レスありがとうです int *aにします
ポインタは int *a; なのに 参照は int& a = b; な俺
俺も俺もw
俺はint* a;派
俺はカンペキにint *a;派だなぁ。 キャストも(int *)pって1マス開けちゃう。 もう癖だな。
int* a;派だな。 int* a, b;でaもbもポインタになる言語出身なので。 とはいっても普段は複数行に分けて書いてるんだけどね。
char* func( int num ){ static char *p =NULL; static const char *pp = "ok"; if( num == 0 ){ p = "ng"; } else{ p = pp; } return p; } 怪しいコードなのですが、 "ng"と"ok"のアドレスはいつ無効になるのでしょうか? 両方とも関数を出ると無効になるのでしょうか。
データセグメントに置かれるから、"ng""ok"は関数を出ても残る。 なのでpを返しても大丈夫。
>>834 どっちの言語でも問題が起きないからじゃないかな
int *a; って書いてる人は ポインタへの参照は int *&a; とかって書いてるのかな。
ポインタの参照なんて書く機会がない。
840 :
833 :2009/02/04(水) 00:13:06
>> 835 836 ありがとうございます。 下記の場合 char *test2( ) { //static char *p = "a....."; //←aを*1024*1024*50 char *p = "a....."; //←aを*1024*1024*50//変数pはなくなるが、参照していた所はのこるのでOK return p; } ってやったらアプリを消すまで、そのメモリは残るということですね。 char *test3( char *temp ) { char a[256]; strcpy( a , temp ) return a;//ちなみにこれはだめ }
ですよ
>>838 ただの参照をint &r;のように書く人も周りにいる。
int *a; は分かる int **a; は分かる int &a; もまあ分かる int *&a; は少し分かり辛い int **&a; は少し分かり辛い
int *a;だな。言語仕様上可能な変数の複数宣言を、表記法で間違えさせる時点で、int* a;は誤っている。 これは間違いなくバカの仕業だ。
複数宣言なんてまずしないし
複数宣言はやめてコメントしっかり入れようぜ
変なこだわり持ってると const 入れる時に挙動が変わって 面倒っしょ?
俺は複数宣言は滅多にしないけど それでも int *& i; なんて変数を使う回数より複数宣言する回数のほうがずっと多いな。
あ、メンバは複数にはしないよ。 ただ、メンバに *& なんて、一度も使ったことないけどね。
よく考えたら for (XXX::iterator it = x.begin(), end = x.end(); it != end; ++it) なんてのは最近結構使ってるな。 この手のはfor_eachとかにするのが読み手にも実行効率的にも良いのかもしれないが 現状、ローカルで宣言した関数オブジェクトが使えないのがすごく嫌なんだよな。
メンバじゃなかろうが複数宣言なんて稀だな。 double x, y, z; (座標)みたいなのならなくはないが。
俺は絶対にやらない主義 初期化も必ずするしなぁ
いや、複数同時と初期化の有無は別よ。 >851だって、複数だけど両方初期化してるでしょ。
>>851 ああ、そう書けるんだ。
気づかなかった。
(double,int,string( foo::(x,y,z) = (0.5,1,"abc") みたいなのは欲しい fooで組全体として参照、foo::xとスコープ付きでアクセスできて さらに多重代入、初期化も可能でさらに最適化で単品と同じになる でこれをforeach内で使うの
括弧開きと閉じが対応してないからわかりにくい
boostにそんなのなかったっけ?
もちろん、言ってる内容全部満たしてるわきゃないが
>>857 バカかおまえ
話混ぜてんのはその前の奴だろ
1行で複数宣言と初期化とか、読みにくいって言うレベルじゃないんだが
慣れの問題 LL言語じゃ普通に使われてるし、多値って概念で関数型言語では割と古くからあるもの RAIIとかの方が遥かに複雑
ポインタ操作を無理矢理に一行の式にまとめた C のコードに比べれば おこちゃま
int *a, *b; と書くくらいなら、 int* a; int* b; と書く。
俺は、場合によっては前者を書く「こともある」な。 まぁ、少なくともこうは書かないw int* a, *b;
どうでもいい
char hako[] = "aishite"; printf("%s", hako + 1);が`i`になるけど、&hako[0]と&hako[1]のアドレスを見ると 4bit?ずつ増えていますが、+1というのは自動的に宣言した型のサイズになるのでしょうか?
>>871 ありがとうございます
決まりごとのアドレスが連続している意味がわかりました
関係ないけど"ishite"になりそうな。
8bitじゃね?
おっと sではなくcですね
>>870 自動的に、ポイントしている型の分アドレスは増えるはずです。つまり、あなたは何か勘違いをしています。
hako + 1は、aの次のiを指している筈ですね。
gamemain.h(14) : error C2143: 構文エラー : ';' が 'enum [tag]' の前にありません。 このエラーを治す方法が分かりません;; アドバイスください 1//========================================== 2// CGameMain・各種クラスの定義 // 定義されているクラス // CModel, CCollision //========================================== #ifndef _GameMain_h_ #define _GameMain_h_ //========================================== // キーボード入力を受け取る変数 //========================================== enum DIRECTION 14{ FOR, // 前に移動 BACK, // 後ろに移動 RIGHT, // 右に移動 LEFT, // 左に移動 STOP };
そのちょいちょい混ざる数字は行数をやさしく書いてくれたのか、それとも元のソースに含まれているのか
879 :
877 :2009/02/04(水) 21:10:32
行数を分かりやすいように書きました
>>879 14行目じゃなくて、1行目と二行目も?
>>880 そうです 元のソースです ↓
//==========================================
// CGameMain・各種クラスの定義
// 定義されているクラス
// CModel, CCollision
//==========================================
#ifndef _GameMain_h_
#define _GameMain_h_
//==========================================
// キーボード入力を受け取る変数
//==========================================
enum DIRECTION
{
FOR, // 前に移動
BACK, // 後ろに移動
RIGHT, // 右に移動
LEFT, // 左に移動
STOP
};
#ifndefはどこで閉じてるの?
GameMain.h の一番最後の行です
int* a, * b;
そんじゃあGameMain.hの直前にインクルードしているヘッダになんか問題があるのかな。 問題とは全然関係ないけどFOR→FOREの方がいいと思う
FORE BACK RGHT LEFT STOP
>> 885 ありがとうございます 見直してみます
>>877 gamemain.hの直前にincludeしているヘッダの一番最後のセミコロンが無いのでは?
ヘッダなんて、所詮Cファイル内に展開してコンパイルしてるだけだからな 単体だけじゃ分からないかも
>>888 そのようでした・・・・
#ifndef _Frame_cpp_
extern CFrame *_Frame;
extern HINSTANCE _hInstance;
extern CGameMain *_gamemain;
extern CGameTitle *_gametitle
#endif
#endif
セミコロンがなかったです。
ありがとうございました!
void Foo::reset() { this->~Foo(); new (const_cast<Foo*>(this)) Foo(); } これは偶然動いているだけですか?
switch(m_sequence) { case TITLE : if(_gametitle) { hr = _gametitle->Idle(m_device); m_sequence = _gametitle->GetSeq(); } break; case GAME : if(_gamemain) { hr = _gamemain->Idle(m_device); m_sequence = _gamemain->GetSeq(); } default: break; } キーを押してタイトルをゲームを切り替えるプログラムを作りました m_sequence = _gametitle->GetSeq(); これでタイトルかゲームかの変数を取得して切り替えています 切り替えに成功するのですが一度切り替えるとボタンを押さないでずっと切り替えが続いてしまいます 対処方法教えていただけませんか;; GetSeq()はgametitleクラスの入力処理で特定のボタンが押された瞬間にGAMEを返します ボタンが押されなければTITLEを返します
>>891 完全に合法
でも危ないからオススメしない
基本クラスを継承クラスにキャストはできるんですが、 (継承クラス)基本クラス 継承クラスを基本クラスにキャストするにはどうすればいいんですか? (基本クラス)継承クラス インテリセンスが機能しないんです
ポインタなら、動こうか壊れようが可能だろ? インスタンスなら、子クラスレベルにはキャスト無理
898 :
892 :2009/02/04(水) 23:21:07
昔適当に書いたファイルを分割するコンソールプログラムなのですが、処理速度が非常に遅いです。 恐らく、ソースが汚いせいもあるかと思うのですが、どうすれば高速に動作するようになるのでしょうか? VC++2008EXPRESS EDITIONを使ってます。 ↓ソース kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/8818.cpp ファイルを高速に扱える関数とかライブラリとか用意されてないのでしょうか?
>>900 どれだけのサイズを何分割して何秒かかったのか示そう。
もしかしたらそれは遅くないかもしれない。
>>900 長いんでよく見てないけど。
ReadFile/WriteFileじかに使ってるが読み書きの単位はどのくらい?
IOバッファが小さいとか無いかな?
>>901 さん、
>>902 さんレスありがとうございます。
977008640バイトのファイルを250MBづつ4つのファイルに分割するのに約2分半かかります。
一度に確保するメモリー領域は50MB程度でループ内部で確保→解放を繰り返してます。
非同期IOにしてみたこともありますが、処理速度は同じぐらいか、かえって遅くなったように思います。
正直、手詰まり感が否めません orz
>>903 プログラム的に改善点はあるものの、ネックはHDDのアクセス速度だろう。
約900MBをreadしてwriteするのに150秒なので、転送速度は平均で約12MB/秒。
同一ドライブ間での転送なら、こんなものかもしれない。
別ドライブにwriteしたり、HDDがIDEならSATAにしたりすれば早くなるだろう。
もしメモリが少ない環境なら、バッファサイズを減らしたほうがいいだろう。
>>903 これを動かすとどの程度時間がかかりますか?
動作としてはコマンドライン引数で与えられたファイルを 256MB 毎に hoge%04d.dat の名前で分割します
#include<stdio.h>
#include<stdlib.h>
#define BUFSIZE (1<<20) // 1MB
#define FILESIZE (1<<28) // 256MB
int main(int argc, char *argv[]){
FILE *fp_in, *fp_out;
char *filename_in="noname", filename_out[MAX_PATH], *buf;
long i, filesize, filesize_max=FILESIZE, readsize, writesize;
if(argc==2) filename_in=argv[1];
buf=malloc(BUFSIZE);
fp_in=fopen(filename_in, "rb");
if(fp_in==NULL) fprintf(stderr, "\nError : %s cannot open.\n", filename_in), exit(1);
for(i=1;;i++){
sprintf(filename_out, "hoge%04ld.dat", i);
fp_out=fopen(filename_out, "wb");
if(fp_out==NULL) fprintf(stderr, "\nError : %s cannot open.\n", filename_out), exit(2);
for(filesize=0,readsize=BUFSIZE;filesize<filesize_max;filesize+=readsize){
if(readsize>filesize_max-filesize) readsize=filesize_max-filesize;
writesize=fread(buf, 1, readsize, fp_in);
if(writesize<=0) break;
fwrite(buf, 1, writesize, fp_out);
}
fclose(fp_out);
if(writesize<=0) break;
}
fclose(fp_in);
return 0;
}
906 :
905 :2009/02/05(木) 01:16:21
>>905 のコードでは問題ないだろうけど
free 忘れてる orz
同一ドライブ間でのREAD/WRITEです。
色々調べてみましたが、CFileクラスを用いた読み書きとかメモリーマップドファイルとか意味がわかりません。
ファイル破談+とかいうソフトを使ってみましたが、同程度の速度でした。
こんなもんかもしれませんねぇ。
>>904 さんがおっしゃるように最終的にはHDDのアクセス速度がボトルネックになるのでしょうね。
初心者なりにですがもう少し頑張ってみます。レスくださった方々、ありがとうございました。
プログラムでのコピーの場合、エクスプローラでのコピーの 2倍程度の時間で収まってれば合格なんじゃないの。
>>903 非同期IOって何使った。
IO完了ポートは使った?
>>905 2分50秒程かかりました。
これって何をテストするプログラムなんでしょうか?
>>910 PATA 2.5" HDD で 700MB のファイルが一分程度だったので
ディスクIOが本当にネックになってるのかな?と確認して欲しかった次第です
>>905 900MBのファイルで40秒弱だったよ。
HDDは今話題のSeagate1T(ST31000333AS)
あるぇ? いまプログラムをコンパイル&実行し直したら、30秒程早くなった。 ソースは手直ししてないのに。 その時のHDDの使用状況にもよるんだろうけど、こんなに差がでるもんか? ますます訳がわからん。
914 :
912 :2009/02/05(木) 02:47:48
同じファイルでやったんじゃなくて? ちなみに同じファイルの2回目は15秒強で終わったよ
TCHAR a[256]; これに””の空を設定するにはどう書けばいいんですか? a = _T(""); とかだめなんですが
TCHAR a[256] = {_T("")}; とか _tcscpy_s(a,256,_T("")); で。
できました どうもです。
一度書いたプログラムは二度と書かないぐらいの意識でどんどんパッキングしていくのが普通なんでしょうか? そんな徹底するようなものじゃないですか? なんか自分しかわからないコードというか、一人一人が独自路線でいくのって空しくないですか?
>>919 なるべく直さなくて済むように書くのがスタンダードなんじゃないの。
何れにしろ、初心者が心配することではないのでは?
>>919 >一度書いたプログラムは二度と書かない
その方針は正しいから、それを目指すのはいいことだ。
空しいならオープンソースにすればいいんじゃないか。だけど、誰でも使えるライブラリを作るのは想像以上に難しい
だから自分の用途に応じた自分用のライブラリを作って二度書きを防ぐようにする。そしてそのライブラリは君の財産になる。
後々微妙に共通化しづらいと分かる事もあるから とりあえずコピペで作って後から共通化した方がいいこともある
その理屈ならTipsとかをドキュメントで蓄積してるのって利口じゃないのかな
記憶を頼りに全 grep 掛けるのが漢スペック。
俺も良くそうするけど、上の奴が知識を共有できないからって怒るんだよw あと、自分の手から離れたソースが見れないことがあるし
LPTSTR string; UINT code = (UINT)*string; DWORD size = GetGlyphOutline(m_hdc, code, GGO_GRAY4_BITMAP, &GM, 0, NULL, &Mat); このキャストは問題ないですか?
LPTSTR、UINT、GetGlyphOutline()のそれぞれがどう宣言されている川からないから問題あるかどうか判断できない。
Win32APIスレで。 多分 LPTSTR string = "abcdefg"; とかやるとわけのわからないことになりそう。
>>926-928 ここは環境依存OKなスレだよ。Win32APIと言いさえすれば、だけどね。
どちらかというと、(UINT)*stringよりは、(TBYTE)*stringまたは(UINT)(TBYTE)*stringのほうがお勧め。
というのは、LPTSTRがchar*で、かつcharが符号付きのとき、\x80から\xFFな文字が符号拡張されてしまうのを防ぐため。
それには、一旦unsigned charでキャストすればいいんだけど、TCHARがwchar_tの場合を考慮しないといけない。
ゆえに、wchar_t/unsigned charで切り替わるTBYTE型でキャストするのがいいということになる。
まぁ、変数名にstringなんて付けるのはやめとけw 暗黙的に予約語だから
文字列を表示するクラスがあるとします そのクラスは表示したい文字を数えてその分だけメモリを確保します 例えばメンバ関数で宣言したクラスをほしい分だけnewで取得したいのですが privateで CModel *m_model; と宣言して コンストラクタで m_model = NULL; 初期化する関数で m_model = new CModel(); と言う感じにすることはできたのですが ほしい分だけ確保する場合は CModel *m_model[100]; と多めに宣言しておいて コンストラクタで forループで全部初期化 初期化する関数で表示したい文字分だけ数えてnewするやり方でいいのでしょうか? 他にいいやり方があったら教えてください 長文失礼しました 読みにくいと思いますがすいません
整理して書くと CMyClass() : m_model(NULL) {} ~CMyClass() { if (m_model!=null) { delete m_model; m_model = NULL; } } void initialize() { m_model = new CModel(); } これだけなら有りがちなクラスだと思うけど、配列にするのは微妙かな 固定長でいいならそれもあるけど、どういう風な用途かも知らないから、何とも言えないが
>>933 レスありがとうございます
質問が分かりにくくてすいません
最初から100個の配列を確保するのはメモリに負担がかかると思うので
初期化する前に何個確保すればいいか計算します
7個確保すればいい場合は
for(int i = 0; i < 7; i++) {
m_model[i] = new CModel();
}
でいいと思うのですが
宣言するときはどうすればベストですか?
用途は表示したい文字の数だけプリミティブとテクスチャを作り表示するクラスです
mapとか使えばよさそうな気が
>>934 CModel* m_model[100];とかではだめか?
あるいは、std::vectorの利用も検討するといいと思う。
>>935 >>936 レスありがとうございます
とりあえずは100個領域確保してやってみます
処理に支障が出たらstd::vectorやmap?に変更してみます
CModel **m_model;
でいいんじゃね?
>>935-936 の通りSTLのコンテナの方がいいと思うけど
std::vector< CModel > v;
for( int i = 0; i < 7; ++i )
{
CModel * temp = new CModel();
temp->init();
v.push_back( *temp );
}
vの宣言のスコープを抜けたら自動的にデストラクタが呼ばれる
ポインタの配列を動的に確保する。 std::vectorを使う。 boost::ptr_vectorを使う。
そういやクラス名がモデルか DBみたいなクラスでも作るのか?
>>938 >>939 なるほど!その方法がありましたか
>>940 クラス名は適当につけただけです
ゲームに使おうと思っているクラスで
指定した文字列を1文字づつテクスチャに書き込んで板ポリで表示するクラスです
>>938 このコードメモリリークしない?
for文の中でちゃんとdeleteしないと
確実にリークするなw
ループの1段階展開とか2段階展開ってどうやるんですか? コードを見比べても何をしてるのかさっぱりわからないんですが
例えばどんなコード?
アンロールのことかな?
>>944 その見比べていると言うソースを提示してみてくれ。
再帰のことか?
>>944 for (i=0; i< end; ++i){
s[i] = f[i+1];
}
↓
i = 4;
if (end > 4)
for (i = 0; i < end; i += 4){
s[i] = f[i+1];
s[i+1] = f[i+2];
s[i+2] = f[i+3];
s[i+3] = f[i+4];
}
for (i -= 4 ; i < end; ++i)
s[i] = f[i+1];
>>949 ちょっとやり方がキモイけど、endに適当な数字を入れて自分で処理を手書きしてみな
endが5のときの動きをトレースすれば一目瞭然だな。 つーか、ループアンロールなんかコンパイラに任せておけばいいじゃん。
どんな end が来るかはコンパイラには 100 か 10 かも判らん場合が多いから 展開前をコメントアウトし、ばらしたコードで記述する意味はある。
endが4の倍数なら後段のforも要らないしな そこまでカツカツの速度が要る場面も珍しいだろうけど
ループの中に if文が挟まって毎回評価してるのを 大加算ループの中でswitch に置き換えるとか色々。
>>949 展開ってそういうことか
ありがとう。
それは4段階展開ってことだよね
確かに読みにくくなるね・・・
アンロールするかどうかのコンパイルオプションがあることもあるよ
手作業でアンロールを始めるとvtuneが欲しくなるな。
VSにはアンロールなんて無くね?
iccなら>952のendをヒントとしてコンパイラに与えることもできる。
アンロールってはじめてしった
>>949 for (i = 0; i < end + 4 ; i += 4){
ですな・・
それじゃ台無しだ。
>>961 for (i = 0; i < end − 4 ; i += 4){
にはw
whileの展開はどうなるの? でも制御文事態のコストがforより軽いからやる意味ないのかな?
whileでも同じ
展開可能な文を while に詰め込むのは クソプログラム だと思うがね。
アンロールもいいけどチョコロールもね
>>968 do と while どういう使い分けしてるの?
数値を変更もしないし、わかりやすく別名を付ける場合は const int MAXDATA = 123; #define MAXDATA 123 この2つはどっちが正しいんでしょうか? なにか決定的な違いはありますか?どうでもいいですか?
Cでは後者。 C++ではどちらも正しいが、前者が望ましい。 名前空間やスコープを無視するマクロはできるだけ無い方が良い。
どうしても、処理が遅い場合、最後の手段はアセンブラを書きなおすっていうのをやってみたいんですが、 アセンブラの命令一覧はなにを参考にすればいいんですか?どこにあるんでしょうか? CPUによってかわるんですか?
>>973 命令一覧みたからって即できるようなもんじゃないとだけ言っておく
アセンブラはマイコンで慣れてるのでたぶんできると思います。 物によって命令が違うのでWindowsで使える?VSで使える命令を知りたいんです
>>975 ほぼ確実に遅くなるからやめておいたほうがいい。
パイプラインを阻害しないような命令配置とか人間が考えるよりコンパイラにやらせたほうがマシ。
SSEとか使うなら今のところコンパイラまかせよりは人間のほうがいいかも知れんけど。
Windowsと言えば、x86だからIntelのウェブサイトにPDFが転がっている。まあAMDにもあるだろうけど。
http://www.intel.co.jp/jp/download/ この中でも、命令が載っているのは
32ビット(と16ビット)はIA-32 インテル
アーキテクチャー・ソフトウェア・デベロッパーズ・マニュアル。
上・中A・中B・下があって中2つが命令一覧。
大体同じだけど、64ビットがインテル エクステンデッド・メモリー 64
テクノロジー・ソフトウェア・デベロッパーズ・ガイドの1巻・2巻。
適当にググって予備知識を付けてから見たほうがいい気もするけど。
命令だけ見てもダメじゃん。 Cの変数とやりとりする規約をコンパイラのマニュアルから探さないと。
>>979 そんなのサンプルみて体で感じ取るぐらいじゃないと駄目
if( a == b && a == c ) これは問題ないですか? if( (a == b) && (a == c) ) こう書かないと結果がおかしくなる場合ってあるんですか? あと、&&と書きさえすればショートサーキットになるんでしょうか? コンパイラによって変わってきちゃいますか?VSなんですが
インテルで調べればよかったんですね。 Windowsはハードの互換性がメリットだと思ったので 仮想アセンブラのようなものでCPUを統一しているのかと思いました。 ありがとうございました。
>>982 > 仮想アセンブラのようなものでCPUを統一
うまいなあ。それは.NET Frameworkというやつだ。
規約や引数その他はコンパイラにアセンブラの出力をさせりゃそれで充分。 問題は、 玄人のアセンブラ>>コンパイラの最適化>>>>素人のアセンブラ なことだ。 確かIntelのpdf群の中に最適化マニュアルもあっただろ。 どんな命令がストールを起こすとかマイクロコードだから遅いとか 互換性を維持しながら最大限速度を取るにはとか、そんなのが載ってるはず。たぶん。 ただね、SIMDのような特殊な命令を利用して特定部分を、というのでない限り 普通は「分岐予測ミス」「メモリアクセス」によって、CPU時間のかなりの部分を食われるのよ。 Pen4とかと比べれば、最近のはそれでもマシになったけど、おそらく半分程度は浪費されるはず。 だから、いかに分岐を減らしてキャッシュミスを無くすか そういうのをC/C++のレベルで考えながらコードを書いたほうが意味があったりするわけよ。
ほう。今ならコンパイラの最適化が人間が扱うのは無理なレベルに達してると思ってたんだが、 玄人ががんばれば勝てるものなのか。
>>985 コンパイラに勝つには、コンパイラの使わないSIMD命令を使い倒さないとだめだな。
でも、ほどほどの速さで良ければ、アセンブリ言語を使わなくても
コンパイラ組込関数を使えばいいという状況になりつつある。
マルチスレッドで変数を同時にアクセスするのが危険な気がするので確実に安全をつくりたいんですが ここからここまでの処理はこのスレッドに変数アクセス優先権をあたえて、 他のスレッドがアクセスしに来たらそのスレッドは変数を使い終わるまでそこでストップ というような処理はできるんでしょうか?
988 :
デフォルトの名無しさん :2009/02/09(月) 04:05:58
できるよ。一度に、あるコードに入れる回数を制限できる
989 :
デフォルトの名無しさん :2009/02/09(月) 04:21:10
難し・・・がんばる ありがとう!
マルチスレッドで変数のアクセスって 書き換えがメインスレッドだけでサブスレッドは 読み込みだけだったら問題ないですか?
中途半端な状態ってのがないならそれでいいけど、 volatile はつけとけよ。
994 :
デフォルトの名無しさん :2009/02/09(月) 09:06:55
まるで初心者だが、borlandC++5.5を使ってて、 Windows関数をつかって軽いアプリケーションを作りたいのだが win関数を使うとコンパイルでエラーが出てしまう・・・ "外部シンボル 'WinMain' が未解決" これはどういうことなのでしょうか・・・?おしえてくだしあ><
"外部シンボル 'WinMain' が未解決" でぐぐれ
996 :
デフォルトの名無しさん :2009/02/09(月) 09:11:16
-W をつける。
>>985 > ほう。今ならコンパイラの最適化が人間が扱うのは無理なレベルに達してると思ってたんだが、
> 玄人ががんばれば勝てるものなのか。
勝てるけどコストが合わない事が多い。
>>993 volatile じゃ解決しねーよ。同期オブジェクト使わないと。
んなこたぁない状況による
どこくらいの移植性を考えるかで変わってくるな。 メモリモデルをx86系Windowsに限定するならセーフ。 C/C++の言語的にはアウト。 専門的な話をしたいならマルチスレッドスレに行ったほうがいい。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。