【初心者歓迎】C/C++室 Ver.16【環境依存OK】
1 :
デフォルトの名無しさん:
>前スレ992
Windowsなら
SendMessage(処理させたいWindowのハンドル, WM_KEYDOWN, VK_RETURN, 0);
>1乙
新スレ乙です!質問があるのですが、
STLのmapの内部では、キーの値をもとにツリー構造を構成しているとのことですが
そうするとmapに要素を挿入するときに、0からインクリメントした値のキーを使った場合は、
検索のオーダーは最悪になってしまうのでしょうか・・?
>>4 実装によるけど、まぁ大抵は心配無用じゃないかな。
>>5-6 お返事ありがとうございます。
それほど酷くないとのことで安心しました。
>>6氏のページは今からJavaをインスコして遊んでみますヽ(´∇`)ノ
>>6 面白いな。0から順に昇べきでノードを追加していくと、左右の木の深さが
4段階以上になると、ずるっと回転操作が行われるのな。
回転操作のプログラムを組んでみた事はあるが、実際にこうして視覚的に
見れるとよく理解できるもんだ。
c言語初心者です。
コマンドの結果を変数に入れたいのですが、わかりません。
例えば system("echo hello"); の結果を変数に入れる事を考えた場合
どのような方法がありますか。
>>9 質問するときの「自分は初心者です。」って言うのは嫌われるぞ?
>>9 system()を使うならファイル経由。
直接得たいならFILE * fp = popen("echo hello", "r");して後はファイルと同じ要領で入力。
>>10 確かにそうですね。気をつけます。
>>11 回答ありがとうございました。
popen関数を使えばいいのですね大変参考になりました。
初心者歓迎スレなのに・・・
>>13 その初心者歓迎スレで「自分は初心者です」ってバカみたいじゃない。
ぬるぽ
ある型Tのポインタと値nを渡し、そのポインタからnバイト先を指したポインタをT型で返す。
という関数かマクロは標準にはあるのでしょうか?
boostにあるのならそれでもかまいません。
自分で作っちゃってもいいんですが、既にあるのならそれを使いたいなと。
>>16 渡したポインタ(仮にp)からn要素先ではなく、nバイト先なのかな?
ってことは、p+nではなくて((char*)p)+nか。
型を戻さないといけないから、(T*)((char*)p+n)だね。
C++ならreinterpret_cast<T*>(reinterpret_cast<char*>(p)+n)か。
18 :
16:2005/04/12(火) 14:14:09
>>17 そうです。でもreinterpret_castを長々と書くことになり見づらくなるので
それをやってくれるものがないかと。
template<class T> T* foo(T* p, int n) {return reinterpret_cast<T*>(reinterpret_cast<char*>(p)+n);}
20 :
16:2005/04/12(火) 15:34:40
やっぱり自分で作るしかないですか。
>>21 てめえは何が言いたいんだ?標準でそんなマクロがあるとでも?
まぁ「あるかないか」って聞いてるんだから、YES or NO で答えるべきだよな。
標準でないから
>>17,
>>19 のように親切で答えてるんだろうに…
そんなことすら理解できないのか?
やり方わからないわけじゃなさそうだし、余計なお世話って気がしないでもない。
少なくとも>17、>19は>21-26と違って参考になるだけまし。
あるかどうか訊いてるのに、こうやるんだよと言われて参考になるか?
だから少なくとも下らん議論よりはましだって。
妙なところで突っかかる人いるのな
妙なところで悪あがきする人がいる以上は仕方ないな
32 :
デフォルトの名無しさん:2005/04/13(水) 12:49:21
デリゲートと関数ポインタって使い方は同じものですか?
デリゲートって便利ですか?
>>32 似てはいる、C++でのメンバ関数ポインタとthisポインタのペアの型のコンテナだ
一長一短。
>>16 なんでそんな謎の操作が必要なのか非常に気になる
>>34 struct HOGE {
int size; // この構造体とその後に続くデータの合計サイズ
:
};
こんなのが連なったデータ列を操作しなきゃならんのです。
>>33 ありがとうございます。
なんとなく理解できました。
37 :
デフォルトの名無しさん:2005/04/13(水) 16:30:40
大学の研究室でC++を使って計算物理みたいな事をすることになりました。
今いる研究室ではC++ですが、来年から違う研究室に移る予定です。
その研究室ではCを使ってるみたいです。
現在私はCもC++もその他のプログラムも未経験です。
Cから勉強すべきかC++から勉強すべきか迷ってます。
どっちから始めたほうがとっつきやすいでしょうか?
そしてお勧めの参考書などはあるでしょうか?
Cで余計なクセつけるとC++をちゃんと使えるようになるのが遅くなる。
C++からCへの移行の方が無難ってことですか?
40 :
デフォルトの名無しさん:2005/04/13(水) 17:07:31
学校の授業でCをやらなきゃいけなくなり、とりあえずPCにコンパイラを用意しろと言われたのですが
一杯ありすぎてよく分かりません。どなたかこれを入れたらいいよっていうの無いでしょうか。
>>40 Debian Linux + gcc + Emacsを入れとけ。
Debian薦めるのはSargeがリリースされてからにしとくれ。
gccだけじゃだめなのかw
>>42 別になんだっていいよ、kernel2.4以上を採用しているLinuxなら。
Fedora coreでもいいし。
45 :
デフォルトの名無しさん:2005/04/13(水) 17:26:14
Borlandのフリーコンパイラでいいんじゃない?タダだし。
Windowsはプログラミングするには不向き。
47 :
37:2005/04/13(水) 17:42:16
私はBorlandのフリーコンパイラにしました。
結局、先にC++学んでおいて、
研究室変わる頃にCの勉強始めればおkですか?
>>47 研究室変わる頃に、その研究室でもC++に移行しているかも知らん。
>>47 あのさ、君、プログラミングする研究室は辞めた方がいいわ。
どうもスキルも無さそうだし、興味も無さそうだし、どうかんがえてもうまくやっていけないな。
プログラミングに興味があるならすでにC/C++ぐらい知っていてもおかしくない。
51 :
37:2005/04/13(水) 18:16:12
まぁ確かに2年の頃にC++勉強して挫折してるんですけどね。
その後やりたい研究分野を扱っている研究室でCが必須である事を知り
そのため計算物理のためにCかC++を勉強しないといけなくなった。
そういうことで今度は挫折は許されないわけです。
まぁここで叩かれようと頑張りますとも。
アドバイスくれた方ありがとうございました。
mathematicaとかは知ってるの?
安すぎ
一般の方が高すぎのような気もするが
確かに一般用のは高い気がする。学生時代にこんなもんがあったら喜んで買ったのにな。
息子/娘にでも買ってもらえ。
#ifndef とかのプリプロセッサって字下げしないのが普通なんですか?
普通の人はc-modeを使うから字下げはしない。
VCユーザもしない。(VCユーザは普通の人ではなく、厨房なので当てにはならないが。)
勉強用にIDEはイラネ
とりあえずcygwinでもつっこんどけば?
こういうところで聞いてくるようなアホにCUIベースのツールを薦めるとセットアップから質問しまくってウザいだけなので素直にVC++買わせとけ。
懐が痛むのは質問者であってこっちじゃねーし。
まぁVC++買ったら買ったで
「コンソールで色出したいんですが・・」
とかアホな質問がくるけどな
const char* hoge()
{
const char* p = "Hoge";
return p;
}
hoge()から帰ってくるポインタを使って
文字を表示したりするのは違法ですか?
>>63 合法だけど
return "Hoge";
でいいやん。
>>63 どうせなら
inline const char * hoge() {return "Hoge";}
で。
67 :
デフォルトの名無しさん:2005/04/14(木) 01:53:17
>>63 それが合法なのは、プログラム領域に確保された
文字列定数"Hoge"へのポインタを返してるからだ。
const char* hoge()
{
const char p[5] = "Hoge";
return p;
}
こんな感じの実装は文句なしに違法。
偉そうに
エロそうに
>>67 そこでマジックナンバーを書いている辺りが情けない。
初心者ならではの煽り方だなぁ ;-)
じゃぁ、もっとあり得る、こんなシチュエーションで。
char buffer[ 1024 ];
...
strcpy( buffer, "Hoge" );
...
char* p = strstr( buffer, "Hoge" );
return p;
> char* p = strstr( buffer, "Hoge" );
> return p;
あり得ねえ
あり得るって言う香具師はプログラムするな
>>37 いまさらだがアドバイス。
言語なんかどうでもいいんだよ。どうせどれも文法がちょっとずつ違うだけだろ。
わかんなくなったらネットにいくらでも資料が転がっている。
必要なのは、プログラムを作るための考え方。それが身についてないと
どんな言語を使ってもろくに動かない糞ソースを生み出すだけ。
78 :
デフォルトの名無しさん:2005/04/14(木) 17:15:59
すいません、realloc関数の第二引数はunsigned int型だと思うんですけど、
それだと最大64KBまでしかメモリを割り当てれない気がするんですが、
それ以上割り当てるにはどうしたら良いのでしょう?
80 :
デフォルトの名無しさん:2005/04/14(木) 17:26:16
>>79 はいそうです
諸事情でWinAPIは使えません
コンパイラはBCC5.5です
>>80 BCC 5.5ってWin32アプリしか作れないだろ。
DOSアプリとコンソールアプリを勘違いしていないか?
82 :
デフォルトの名無しさん:2005/04/14(木) 17:30:13
すみません勘違いしてるっていうか細かい事は分かりません
OSはWinXPです・・
まずその細かいが重要なところを理解してこい
84 :
デフォルトの名無しさん:2005/04/14(木) 17:39:59
そんな事言わずにお願いします・・なるべく早く知りたいのです
コマンドプロンプトに出力するアプリケーション=DOSアプリケーションじゃない。
Win32アプリケーションの場合もある。BCC 5.5自体もそうだし。
main()から始まるプログラムでもCreateWindowはできるし、
逆にWinMainからでもRead/WriteConsoleでコマンドプロンプトを使う入出力ができる。
とりあえずprintf("%u", sizeof (size_t));をやってみろ。
reallocの2番目の引数はsize_t。大抵unsigned intのtypedefだが。
86 :
デフォルトの名無しさん:2005/04/14(木) 17:44:13
>>85 ありがとうございます。
4って出ました。
unsigned longなんですね。
>>82 unsigned intの最大値を調べてから質問し直してください。
printf("%u", sizeof (int));
ってやってみろ。
>>86 Win32ではint/unsigned intも32bit化されて4Byteになっている。
90 :
デフォルトの名無しさん:2005/04/14(木) 17:50:09
>>89 そ、そうだったんですか・・・詳しい情報感謝します
そしてポインタも32bit化されている。
ただしアプリケーション(1プロセス)が使用できるアドレス空間は2GB。
2GB以上(〜4GBの)メモリを確保するのは難しい。
92 :
デフォルトの名無しさん:2005/04/14(木) 17:55:52
どうもです
Windows2000 AdvancedServer / WindowsServer2003 Enterprise以上なら3GBまで使えるよ
95 :
デフォルトの名無しさん:2005/04/14(木) 19:31:15
#include <stdio.h>
struct stack_type{
intdata;
struct stack_type *p;
};
struct stack_type *talloc(void);
int main(void)
{
printf("******");
struct stack_type *stack, *temp;
stack = talloc();
stack->p = 0;
while(1){
scanf("%d", stack->data);
temp = stack;
stack = talloc();
stack->p = temp;
}
return 0;
}
struct stack_type *talloc(void)
{
return (struct stack_type *)talloc(sizeof(struct stack_type));
}
以上のようなプログラムで、「構文エラー : ';' が 'type' の前に必要です。」
というエラーが出ます。場所はmain関数の中で一番最初に宣言している、
struct stack_type *stack, *temp;です。
96 :
95:2005/04/14(木) 19:32:41
間違いはほかにたくさんあるのですが、
これの意味がわかりません。
ちなみに直前のprintfをはずすとなぜかコンパイルエラーも起こらずに、
実行されてしまいます。
どの部分が影響されてこのようなエラーが出るのでしょうか?
とりあえず一番最初のprintf()消せ。
98 :
96:2005/04/14(木) 19:43:47
>>97 最初は書いていなかったんです。
しかし、コンパイラがエラーをはかずに実行まで行ってしまい、
その後のwhileループも実行されずに無事に?終わってしまいました。
そのため、printfを追加したら、上記のようなエラーが帰ってきました。
Cでは関数の最初でしか変数宣言できなかった希ガス。
途中に書けるようになったのはC++からだっけ?
古いCでは変数宣言はブロックの先頭にある必要がある。
変数宣言より前に普通の文を書いてはいけない。
対策はC99対応コンパイラを使う、もしくはC++としてコンパイルするなど。
101 :
96:2005/04/14(木) 19:50:02
char *buf;
buf = (char *)malloc(1024);
こんな風にした場合、bufのサイズ(ポインタのではない)
を求めるスマートな方法を教えて下さい
>>102 もっともスマートにして唯一採りうる手法として、malloc関数を呼んだ時点での領域確保のサイズを記録しておく。
つまり、
int a;
char* buf;
a = 1024;
buf = (char*) malloc (a * sizeof (char)); /* <- 必ずsizeof演算子でサイズを計算しておくこと。環境対策。*/
>>103 出来ればそれはしたくなかったのですが、それしか無いですか・・・
>>104 他にも方法があった。
自分でメモリ周りのライブラリを作る。そしてサイズを返す関数もつくればいい。
>>103 sizeof (char) はどんな環境でも1を返すことは知ってるか?
>>105 勘弁して下さいorz
ありがとうございました
>>100>>108 WindowsならHeapAlloc()を使えば、HeapSize()でサイズを取得できる。
Windowsは非標準だしぃ。
>>115 sizeof(char)が1を返すかどうかを決めているのはコンパイラだ。
それが正しいCコンパイラかどうかは決まっていない。
ISOに従っていないC/C++コンパイラはC/C++コンパイラとは言えん。
C/C++コンパイラではないコンパイラのことまで心配する義理などどこにもない。
っていうと少々語弊があるけど。
正しいCコンパイラでないものを想定したらどんなコードでも安全ではないと思うが。
アホ?
>>118 極端な奴だな。
おおよそC言語っていうのがほとんどなんだよ。
A型なんだね。
sizeof演算子でサイズを計算しておかないとあんた死ぬわよ
>>114 ここは初心者歓迎なんで、あなたみたいな人は大歓迎ですよ。
でも、もともと組み込み屋ってことは今は違う仕事してるんですよね?
もしかして無職ですか?
>>122 たぶん、俺は君より社会的地位が上だと思うよ。
>>123 後輩に「sizeof(char)ってした方が移植が楽だろ」とかえらそうに言ってるんですか?
これ以上話題を伸ばす必要は無いと思うが、
sizeofしておいたほうが統一性があってよい。
つーかいまどきmallocなんか使うな。いじょ。
つまりCを使うなという事ですね!
callocを使えと
#define char wchar_t
とかされる可能性も考えたら?w
>>131 その無駄に豊かな想像力を生かして、あなたは
#define sizeof(t) 3
の可能性も考えた方がいいですね。
callocと、
malloc+memset
ではどっちが速い?
>>137 実装によるべ。calloc()の方が遅いことは余りないと思うけど。
>>135 想定すべきは、そうすればなんらかのメリットがある、という行為であって、
全ての場合を想定するなら、定理証明支援システムでも使えばいい。
メリットがない想定はあまり意味がない。
いい加減消えてくれないか。
C言語自体が矛盾を持っているんだから、君の発言は無意味な事が多いんだよ。
#include <stdio.h>
#include <windows.h>
int main(void)
{
HANDLEhHeap;
LPTSTRlpFilename;
SIZE_TdwBytes = 1024;
hHeap = HeapCreate(0, dwBytes + 1, dwBytes + 1);
lpFilename = (LPTSTR)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwBytes + 1);
GetModuleFileName(NULL, lpFilename, dwBytes);
printf("%s", lpFilename);
HeapFree(hHeap, 0, (LPTSTR)lpFilename);
return 0;
}
Heap関数を勉強しようと思って、自分のフルパスを表示するコードを書いたんですが、
(例外処理を除き)このままではヤバイって所はありますか?
ググってもドキュメントが見つからないのでMSDNだけ見てやったんですが・・
環境依存のスレいきなよ。
>>141 HeapCreate()が返したハンドルはHeapDestroy()すべき。
そもそもGetProcessHeap()を使えばその手間は省ける。
ヒープから外れるけどprintfの%sが受け付けるのはマルチバイト文字列。(const char *とかPCSTR)
UNICODEビルドしたらアウト。tchar.hの_tprintf使え。
>>143 ありがとうございます。
助かりました。
>>142 おまいはスレタイが読めんのかと小一時間(ry
>>145 ボクの目を覚まさせてくれてありがとう!
愛してるよ…
>>140 #define char wchar_t
に意味があると考える知的障害者なら
ナニをやるか解ったモンじゃないだろに。
つかネタだったんだが。
>君の発言は無意味な事が多いんだよ。
俺が誰だか解るとは、君はもしや…ノイローゼ?
>#define char wchar_t
>>140 おまえが消えろよ
あのさあ、そんな不毛な話をしてるくらいなら、
void*p = malloc(sizeof(size_t) + size);
*(size_t*)p = size;
return (void*)((size_t*)p +1);
とか質問者に教えた方がまだましだったと思うんだけど。
GYAaaaaaaaahhhhhh━━━━━━(゚Д゚;;)━━━━━━!!!!!!
すマアんごばっくっった
Win32APIでファイルをコピーする奴ください
教えることはできるが、あげることはできんな。
WriteConsoleとかその辺のAPI使えばたいていの事はできる
>>155 某のコンパイラの場合はWindows98上でコンパイルするとWindows2000でもエスケープシーケンスが効いてたと思う。
Windows2000上でコンパイルすると何やってもダメだった。
>>156-157 レス、ありがとうございますた。
>>156 APIって見たときは「初心者の私には難しそう_| ̄|○」
って感じましたが、ググってみたらいろいろと情報が出てきました。
もう少しいろいろと勉強して、がんばってみたいと思います。
ありがとうございました。
>>155 RSXNTにVT100/ANSI端末シミュレーションライブラリが同梱されていて
それをリンクすればprintfなどのIO周りをエスケープシーケンス対応
のものに入れ替えることが出来る。VC6とリンクできるライブラリも
入ってたと思う。
160 :
デフォルトの名無しさん:2005/04/17(日) 18:38:59
wifstreamにパスとしてwchar_t*型を渡したいのですが
char*型でないとコンパイラに怒られてしまいます
wchar_tとcharの変換もしくはwifsreamにwchar_t*型を渡す方法を
どなたか伝授してください
>>160 cstdlibのstd::wcstombs()
あるいはWinAPIのWideCharToMultiByte()
162 :
160:2005/04/17(日) 19:05:10
>>161 隊長!wcstombsを使ったらリンカのやつ
basic_stringが既に定義されていますとか言いやがります
どうしたらいいですか?
>>162 ここで教えて欲しいなら、
エラーメッセージをそのままコピペしろ。
環境もなるべく詳しく書け。
164 :
デフォルトの名無しさん:2005/04/17(日) 20:57:22
すみませんが教えてください。
クラスのconstメンバ関数が例外を投げるときは、
どのように宣言すればいいのでしょうか?
e.g.
int SetDetails(int d)const, throw(const char*) ;・・・??
165 :
デフォルトの名無しさん:2005/04/17(日) 21:03:15
関数名間違いました(セットするのにconstか?・・って突っ込まないで)
int GetDetails(int d)const, throw(const char*) ;・・・です。
>>164 例外 hoge を投げるなら
int GetDetails( int d ) const throw( hoge );
例外を投げないなら
int GetDetails( int d ) const throw();
別に指定しなくても例外は使える。
というか、指定したら、もしGetDatails内で呼び出した別の関数が
hoge以外の例外を送ってきたら、それを再送出しないですむように
実装しないとあかんぞ。
167 :
デフォルトの名無しさん:2005/04/17(日) 22:01:32
ありがとうございました m(_"_)m
> hoge以外の例外を送ってきたら、それを再送出しないですむように
>実装しないとあかんぞ。
了解です。
#include<iostream.h>
intx = 555 ;
int main( void )
{
cout << "x = " << x << '\n' ;
intx = 333 ;// @
cout << "x = " << x << '\n' ;
for( int i = 0 ; i < 3 ; i ++ ) {
int x = i * 100 ;
cout << "x = " << x << '\n' ;
//★cout << "::x = " << ::x << '\n' ; //ここで@を参照するには??
}
cout << "x = " << x << '\n' ;
cout << "::x = " << ::x << '\n' ;
return 0 ;
}
例えばこの時、コメント部分でも書いているのですが、for文の中で、
//@を参照するにはどのように記述すればいいのですか?
>>168 ツッコミどころはたくさんあるが、とりあえず質問の答えは、無理。
>>168 その変数を参照することを指定する記法はない。
だから、ポインタか参照で介さない限り無理。も
171 :
170:2005/04/17(日) 22:23:24
「ポインタか参照でも介さない限り無理」ね。
そうでしたか。
ご教授、ありがとうございます。
173 :
デフォルトの名無しさん:2005/04/17(日) 23:10:13
cout.width(10) は printf の %10d とかに相当すると学びました。
しかし、こうやると、イチイチ cout を使うたびもう一度設定しなければ
なりません。
一回設定したら、ずっと有効になるようにしたいのですが、どのようにすれば
よろしいですか?
>>173 幅は出力のたびに指定するしかない。
ただ、普通はwidth()を使わずマニピュレータを使う。
#include <iomanip>
cout << setw(10) << 10 << endl
<< setw(20) << 20 << endl
<< setw(30) << 30 << endl;
みたいな感じにずらずら続けて出力できる。
なるほど。これからはそちらを使うことにします。
どうもです。
176 :
デフォルトの名無しさん:2005/04/18(月) 00:48:15
C++で、あるクラスxがあって
printf("%d", x);
とすると、クラスxのメンバのa(x.a)が表示されるようにするには
どのように記述すればよろしいですか?
printf("%d", x.a);
>>176 仮にクラスxにoperator int()があったとしても、printf()ではPOD型以外は渡せないので
printf("%d", x);
と言うわけには行かない。
operator int() 作って
printf("%d", ( (int)x ) );
でもダメなんでつか?
>>179 それなら大丈夫。
だが、printf("%d", static_cast<int>(x));推奨。
つーか、括弧多過ぎ。
printfで指定した個数の空白などを表示する方法ってありませんか?
ループ
>>181 printf("%*s",空白の数," ");
>>183 おーーありがとうございます!ずっと思い出せなかったのでかなりうれしいです!!
初心者すぎますが、C++ってなんて読むんですか
シープラスプラス??激しくアレな人教えてください
はじめからここで聞くべきでしたね ごめんなさい
>>189 どこがマルチなんだ?wキチガイか 氏ね房うざすぎ おまえが氏ね
もういいや
>>189は消防からやり直して氏ねよ
2chのルールだけ気にしすぎて通常の人間の会話が理解できない房決定
193 :
デフォルトの名無しさん:2005/04/19(火) 13:08:56
ストリームを途中から
バイナリ<-->アスキー
変換てどうやるんですか
初期化時にはできるんですが途中からしたいのでお願いします
>>188 char answer = c++;
std::cout << answer << std::endl;
>>183 最後の引数が違うなあ。" " じゃなくて "" だ。
Cについて質問です。
ある関数の中で例えば int i; と変数定義した場合、
他の関数の中で i=0; などと代入はできませんよね?
でも、他の関数の中でも int i; i=0; とやるとコンパイルできるみたいですが、
この場合、最初に出てきた int i; と他の関数で出てきた int i; は別物と考えればいいんでしょうか?
スコープでぐぐれ
ブロックが異なれば同じ変数名でも使えるんですね。
ありがとうございました。
ちなみにVC6のコンパイラはfor文のスコープがおかしかったりするから注意な。
おかしいか?
どう考えても明らかにおかしいだろ
おかしいのは(現在の仕様から見た)当時の仕様だね。
寧ろVC7のディフォルトがVC6と同じなのが気にイラン。
203 :
デフォルトの名無しさん:2005/04/19(火) 17:14:33
for( int i = 0 ; i < 10 ; i+++ ){
}
確かにデフォルトでは規格通りにして欲しかったな
テンプレートクラスはnewで動的に作成するのは無理ですか?
無理だとしたら何故でしょうか?
>>206 インスタンスの作成は、テンプレートの特殊化版であっても
通常のクラスと同様に動的生成可能
特殊化版の具現化は、newを使おうが何をしようが
動的には無理。全てコンパイル時に解決されなくてはならない。
意味が分からん
std::vector<int>* p = new std::vector<int>;
209 :
206:2005/04/19(火) 18:57:35
>>207 >>208 すいません、根本的に間違ってました。
クラスの宣言部と実装部をファイル分けしていたのが原因でした。
ごめんなさい。
>>188 スィープラスプラス。一部でシープラプラ。
シータスタス
>>188 折りよく「C++の設計と進化」を読んでたんだが、「シープラスプラス」って書いてあった。
VC6インスコしたときのビデオ見れば何て言うのかわかるやん
214 :
デフォルトの名無しさん:2005/04/19(火) 21:39:25
ってここはVCスレじゃなかったな。
ビデオなんかあったか?
なんで
char str1[80]="こんにちわ";
char str2[80]="8等身です";
とやって、strcpy(str1,str2)に突っ込むと大丈夫なの?
配列を表す名前、str1はstr1の始まるアドレスをさすが、
ポインタではない
という説明をいたるところで見るんだけどstrcpyはchar型配列への
ポインタを引数にとると書いてあるから、配列名じゃだめだろうと
思ってたんだ。
試しに
char *pst1,*pst2;
pst1=str1;
pst2=str2;
とやってstrcpy(pst1,pst2)
とやってみたらstrcpy(str1,str2)と同じ動作をした。
つまり配列の名前はその配列へのポインタとおなじ振る舞いをすると
俺の中で間違った認識が生まれようとしている
おまいらつД`) タスケテクレ !!
#include <stdio.h>
#include <string.h>
void main(void)
{
char *str1="こんにちわ";
char *str2="8等身です";
strcpy(str1,str2);
printf("%s",str1);
}
216のが動いて、
これが動かない原因が超絶にわからないのですが…
ポインタも理解できないんだったら素直にJavaでもやっとけよ
だれか193に答えて…
>>216 配列の名前から値を取り出すと先頭要素ポインタになる
あと、
>>217は文字列リテラルに上書きできないという別の問題だね
正確なこと忘れちゃったから微妙に間違っている可能性大w
>>216-217 > char str1[80]="こんにちわ";
> char str2[80]="8等身です";
char型の変数80個分の配列を確保し、その個々の変数に文字列「こんにちわ」の各文字を格納する。
char型の変数80個分の配列を確保し、その個々の変数に文字列「8等身です」の各文字を格納する。
>char *str1="こんにちわ";
>char *str2="8等身です";
char型の変数を指すためのポインタ変数を確保し、どこかに確保されている文字列リテラル「こんにちわ」の先頭ポインタ値を入れる。
char型の変数を指すためのポインタ変数を確保し、どこかに確保されている文字列リテラル「8等身です」の先頭ポインタ値を入れる。
これらの処理の、どこに共通性があるんだ?
>>216 >つまり配列の名前はその配列へのポインタとおなじ振る舞いをすると
>俺の中で間違った認識が生まれようとしている
正しくは
「式の中に現れた配列名はその配列の先頭要素へのポインタとして評価される」
ただし例外もあるのでややこしい。
詳しくはCFAQでも読め。
218,220,221,223
回答どうもです
回答とCFAQを読んで
配列名は先頭要素のポインタへと成り下がるから
strcpy(配列名,配列名)
が動くことはわかりました。
しかし221さんの仰せられることは理解できますが
char *str1="こんにちわ";
char *str2="8等身です";
strcpy(str1,str2);
としたとき、
str1,str2ははそれぞれ"こんにちは","8等身です"
の先頭を指すポインタとなるから、やはり
strcpy(str1,str2);
は動かないとおかしいと思うのです。
配列名のstr1も後者の文字列リテラルへのポインタとして宣言したstr1
もどちらもポインタで、strcpy()にとられる引数として
文句ないように見えるのですが…
char str1[80]="こんにちわ";
の場合は、”こんにちわ”の文字の後ろに70char分空きがあるだけ
>>224 文字列リテラルはCではchar*, C++ではconst char*
strcpyが通らないのはC++でコンパイルしてるんじゃ?
Cなら通るはずだぞ。
>>226の言ってることに正しいことがただの一つもない件について
>226
c++でコンパイルしていますが、イマイチよくわかりません
ただ、
char str1[]="こんにちわ";
char *str2="8等身です";
strcpy(str1,str2);
printf("%s\n",str1);
これは通りました
constcharについてすこし調べてみます
引き続き224についてなにか情報がありましたら、よろしくお願いします
>>228 正しくは「C++ではconst 文字の配列」
ところがCとの互換のため char* への代入が認められている。
で、char* str = "hoge"; としたとき、strを介して文字列リテラルを
書き換えようとしたときの動作は未定義。
実装によってはstrcpyが通るかもしれん。
↑「文字列リテラルはC++では…」ね。
>>224 > しかし221さんの仰せられることは理解できますが
できてないよ。
char* str = "hoge"; としたとき、strを介して文字列リテラルを
書き換えようとしたときの動作は未定義。
ということは、書き換えられる方は、素直に配列として宣言しておけ
と言うことなのでしょうかね…
結果としてよくわかりませんでしたが次に進んでみることにします
教えてくださった皆さんありがとございました
>232さん
理解できてないでしょうか?
char *str="こんにちわ";
printf("%x\n",str);
も
char str[]="こんにちわ";
printf("%x\n",str);
も、割り当てられているメモリのアドレスにかなり距離がありますが、
どちらもアドレスが出力されるのですが…
>>234 同じ内容の文字列リテラルは記憶領域を共有する可能性があるから、
文字列リテラルを書き換えるとロクなことにならない。
C では、おそらくこれくらいの曖昧な理由しかないが、 C++ では、
const なオブジェクトを書き換えることになり、明確に未定義動作となる。
プログラムの動作を保証したいのであれば、
同じ型のポインタでも、指している先の記憶領域が
リテラルであるかどうかは意識する必要がある。
理解できてないことすらも理解できないのか
どうやらそのようです
出直してきます
どっちが理解できてないのか…
>>234氏はたぶん理解してるでしょ。
ちなみに、
char *str1="こんにちわ";
char *str2="8等身です";
strcpy(str1,str2);
printf("%s",str1);
BCCはこれを通すな。いいんかw
240 :
193:2005/04/20(水) 11:24:03
>>222 FILEでなくストリーム(fstream)なんです…
ストリームにされてるファイル名を意識しないようにしたいので
開きなおすことはできないんです
あとモードを変更した後もファイルポインタは開きなおす前と
同じ位置をポイントしている必要があるんですが
開きなおしによってバイナリ/アスキー変更した場合だと
ファイルポインタの位置を復元することができません('\n'の関係で)
241 :
234:2005/04/20(水) 11:31:11
>235,238
未定義のことはさせないほうが良いという結論に達しました
int i = 3;
i = i++;
が7になることもあるんですね
ありがとうございます
させない方がいいじゃなくてしちゃいけないの
>>234 出来てない。
一番の違いは、そのポインタ値が示す先にあるオブジェクト。
配列の中身は書き換える事が可能だが、
文字列リテラルは書き換えが出来ないオブジェクト。
ちなみに、リテラルは「定数」の事。
1 = 2;
が出来ないのと、根本的な理由は一緒。
>>234 char a[80]="文字列";
は aに "文字列" がコピーされるの
つまり
char a[80];
strcpy(a,"文字列");
と等価
char* b="文字列";
とはぜんぜん違う。
おい!鼻から悪魔出てるぞ!!
248 :
234:2005/04/20(水) 18:01:18
>244
なるほどでも
char a[80];
strcpy(a,"文字列");
char* b="文字列";
としたあとにaもb同様にアドレスをさすじゃないですか
char *a="あああ"
char *b="いいい"
この場合もaもbもアドレスをさしますよね
その結果何故strcpy(a,b)として領域破壊が起こるのか未だに
理解できません、、、
定義されていない動作かとおもいましたが
aもbもポインタそのもののはずです
この流れで何で分かんねーの?池沼じゃあるまいし。
ちゃんと嫁よマジで
250 :
234:2005/04/20(水) 18:03:14
それともchar *a="あああ" の用に宣言したときは
自動的に文字列リテラルとなり、書き換え不能となるのでしょうか?
それなら納得がいくのですが…
251 :
234:2005/04/20(水) 18:14:17
どうも人一倍理解が遅いようです
すみません
さらに調べてみると
ポインタで宣言したchar *b="いいい"は静的記憶領域に
記憶されることがわかりました。
たぶんwindowsのメモリ領域のヒープとなんかのことだと思いますが、
つまり書き換え不可能で、書き換えようものならばセグメンテーション
フォールトを起こして落ちてしまうようです。
char a[]="あああ";
の場合は書き換え可能な領域(0x4000番地?)に確保されるため、
書き換え可能なので、strcpyの第一引数としてokで
ファイナルアンサーでしょうか
コンパイラがエラー出さないなら全部安全だと思うなよ
254 :
234:2005/04/20(水) 18:24:13
あ、すいませんa[]をさすポインタのaのことです
つまりstrcpy(a[],b)じゃなくてstrcpy(a,b)です。
腕たて臥せ10回分ぐらい危険
256 :
234:2005/04/20(水) 18:25:45
>253
未定義のもの、意図しない動作ではあるが論理的に正しいモノは
通ることがわかりました。
今後アプリを作っていく上で意識しながらやっていこうと思っています。
char a[] = "あああ";
┌─┬─┬─┬─┬─┬─┬─┐
│ あ │ あ │ あ. │\0│
└─┴─┴─┴─┴─┴─┴─┘
↑
「確保」 されるのはこの領域
char *b = "いいい";
┌─┬─┬─┬─┐ ┌─┬─┬─┬─┬─┬─┬─┐
│ ========================>※│ い │ い │ い. │\0│
└─┴─┴─┴─┘ 参照 └─┴─┴─┴─┴─┴─┴─┘
↑
「確保」 されるのはこの領域
char *b = "いいい"; の時点で※の領域が確保されるわけではない。
確保されるのは char *b 分の領域のみ。
※の領域はプログラム起動時にメモリ上のどこかに配置される。
どこに配置されるかは処理系依存。
ちなみに変数のアドレスを printf("%p\n", b); で表示するのは間違い。
正しくは & 演算子を使う。
printf("%p, %d\n", &a, sizeof(a));
printf("%p, %d\n", &b, sizeof(b));
>>257 ポインタに変換されるんだから&なしでも%pは平気だと思うが。
>>258 printf("%p %p\n", b, &b);
260 :
デフォルトの名無しさん:2005/04/20(水) 19:49:16
>>234 あんたがぐだぐだ言ってるからおれまで混乱してきた
謝罪と賠償を求める
愛国無罪!!
>>259 スマソ
bはchar配列だと思っていた。
任意の文字を任意の回数だけ連続させる簡単な方法ってありますか?
perlなら「'-' x 20」って一発で書けちゃうような処理ですけど
char c='-';
string s;
while (cnt--)
s += c;
return s;
仕方なくこんな関数書いたんですけど、
標準ライブラリにこんな処理する関数無かったっけ?
std::string s(20, '-');
これだけでいいだろ
油断すると忘れるよな、そのコンストラクタ。
>>263 std::string hoge( 20, '-' );
または
std::string hoge;
hoge.assign( 20, '-' );
267 :
213:2005/04/20(水) 22:27:14
>>215 VC6かVC4か忘れた。はっきりと「びじゅある しー ぷらすぷらす」と言ってた。
しかもスゲー早口で
>>264 266
うげー…、そんなのあったのか、サンクス…
char s[20];
memset(s, 20, '-');
>>263 size_t len = 20;
char c = '-';
string s;
s.insert(s.begin(), len, c);
return s;
C言語によるプログラミング基礎編で
int a[ 4 ];
int *b;
とした時、b=a, b++, b+1, はOKでa=b, a++はエラーとなる。
ここまでは良いんですが、
a + 1 がOKと書いてあり、その理由が分かりません。
配列aに1を加えると言うのもどう言う事なのか…
どなたが教えてください。
c が '\r' か '\n' の時に真を返す述語ってctypeあたりにないですか?
述語・・・
ctype にあるわけなかろ
274 :
デフォルトの名無しさん:2005/04/21(木) 01:12:43
配列全体のアドレスと配列の先頭要素のアドレスってどう違うんですか?
>>274 質問の意味がわからんのだが、
例えば
int a[3]
があった場合、aと&a[0]の違いか?
値は一緒。でも型が違うので動作が違う。
int a[3];
printf("%p %p\n", a, a + 1);
printf("%p %p\n", &a, &a + 1);
277 :
デフォルトの名無しさん:2005/04/21(木) 01:38:38
>>275 レスどうも。
>>でも型が違うので動作が違う。
ここのところをもう少し詳しくご教授いただけますか。
278 :
277:2005/04/21(木) 01:42:51
すみません。
>>276見てわかりました。どうもありがとうございました。
>>277 275と276は流れが違うけど。
どうせなら、
printf("%d %p %p\n", sizeof(&a[0]),&a[0], &a[0]+1);
printf("%d %p %p\n", sizeof(a),a, a + 1);
printf("%d %p %p\n", sizeof(&a),&a, &a + 1);
を動かしてみな。
280 :
デフォルトの名無しさん:2005/04/21(木) 06:42:41
csvもしくはタブ区切りファイルを読み込む関数もしくはクラスはありませんか?
出来るだけ移植性の高いものがいいですが、gccだけで使えるものでもかまいません。
自分で作るのが基本です
ifstream で開いたファイルのテキストを
char*とstringに入れるにはどうすればいいのですか?
ifstream hoge;
string moge;
copy(hoge.begin(), hoge.end(), inserter(moge, moge.end());
>>284 ifstream input;
vector<char> v((istreambuf_iterator<char>(input)),istreambuf_iterator<char>());
char* p = &v[0];
string s(v.begin(),v.end());
v.push_back('\0');
287 :
286:2005/04/21(木) 10:51:21
ゴメン
ifstream input;
vector<char> v((istreambuf_iterator<char>(input)),istreambuf_iterator<char>());
v.push_back('\0');
char* p = &v[0];
string s(v.begin(),v.end()-1);
288 :
284:2005/04/21(木) 11:54:03
char*はよくわからないことになったのでstringで統一することにしました。
返答ありがとうございます。
public宣言イクナイ!ということでprivate宣言するようにしたのですが、
private変数の数だけpublic関数が増えてしまいます。↓こんな感じ。
class foo {
int a;
int b;
public:
int GetA(); //private変数の数だけpublic関数を用意する
int SetA();
int GetB();
int SetB();
};
これでいいんですか? もしくは、漏れは次にどんな本を読めばいいんでしょうか。
C++の文法自体は一通り覚えました。
>C++の文法自体は一通り覚えました。
ならば次は本ではなく実践、足りないと思ったらまた本読む
実装丸見えじゃん
>>289 設計を見直せ。
クラスの内部だけで必要な情報ならパブリックなセッタゲッタは必要ないはずだ。
仮にパブリックなセッタゲッタが必要だとしても、メンバ変数の数だけ作るというのが理解できん・・・
294 :
デフォルトの名無しさん:2005/04/21(木) 16:33:32
try文が認識されないので教えてください。
コードは長いので2回に分けて書きます
void mo12(void){
char str12[5]={0};/*結果を入れてもらう変数*/
int strbl;/*strlenghtの結果を入れる為の変数*/
putchar('\n');
for(;1;){
printf("\t文字を入力してください(zで終了):");
try{
gets(str12);/*値を取得してstr12に格納*/
}catch(...){
printf("エラー");
break;
}
295 :
デフォルトの名無しさん:2005/04/21(木) 16:34:25
>>294の続きです
//str12[0]='z';
strbl=strlen(str12);//文字の最大数を測定
//元の値の表示
if(strbl>5){er=-3;error1(&er);break;}
putchar('\t');
for(i=0;i<strbl;i++){printf("%X ",str12[i]);}
printf("が入力されました\n\t");
for(count=0;count<strbl;count++){
er=mondai12(str12,count);/*文字をHEXコードに変換し、上位ビットと下位ビットを入れ替える関数*/
if(er<0){/*エラー処理*/error1(&er);}else{
//結果の表示
if(count==0){/*最初のみ表示*/printf("上位ビットと下位ビットを入れ替えると");}
printf("%X ",er);
}
}
printf("\n\n");
for(count=0;count<strbl;count++){/*大文字か小文字のzを検索該当する値があれば-5をerに代入*/
if(str12[count]==0x7a||str12[count]==0x5a){
er=-5;}
}
if(er==-5){break;}
}
}
>>295 おーい、向こうのスレに書かれていたレスは読んだのか?
297 :
デフォルトの名無しさん:2005/04/21(木) 16:42:42
つーか、gets()をtryで囲って何がしたいのだろう。
そんなことするより素直にgets()を捨てればいいのに。
char *str;
str = "(0,1,2,3,4,5)";
int ParseStart = strcspn(str,"(");
int ParseEnd = strcspn(str,")");
char *p = strchr(str,'(') + 1;
char *q = new char[ParseEnd-ParseStart-1];
strncpy(q,p,ParseEnd-ParseStart-1);
strの[(]と[)]に挟まれた部分[0,1,2,3,4,5]を抜き出したいのですが、
上記のような記述でもうまくいかないので、やり方があれば教えてください。
>>299 char * str = "(0,1,2,3,4,5)":
char * buf = new char[strlen(str)];
sscanf(str, "(%[^)])", buf);
printf("%s\n", buf);
delete[] buf;
// C++ならC++らしく書くべきだとは思うのだけど。
>>299 #include <stdio.h>
int main()
{
char *str = "(0,1,2,3,4,5)";
char r[32];
sscanf(str,"(%[^)]s)",r);
printf("%s\n",r);
return 0;
}
インラインアセンブラを行いたいのですが、
C言語でのインラインアセンブラ用の命令を解説しているHP、
またはweb, VCのMSDNライブラリ用の検索語を教えてもらえませんか?
アセンブラは環境によって違うが?
"inline assembler"
みなさんありがとうございます。
>>303の紹介してくださったページを読んできます。
308 :
デフォルトの名無しさん:2005/04/22(金) 00:28:59
new で領域確保が失敗した場合、
xalloc で例外処理をキャッチするみたいな事が本に載っていたのですが、
new.h をインクルードしてやってみても、xalloc の部分でエラーが出ます。
except.h exception.h 、共にありませんでした。
ちょっと、わかりにくいかもしれませんが、どうすればいいんでしょうか?
ご存知の方 Help !!
>>308 それは昔のコムパイラかと
今はstd::bad_alloc(だっけ)
ありがとうございます。なんとかコンパイルは通ったので、
これから色々テストしてみたいと思います。
311 :
デフォルトの名無しさん:2005/04/22(金) 01:54:17
初心者で関数がわからないので教えてください。
下のプログラムを考えたときに、aaaでprintfで答えが出るのに
main関数では答えは 2 3 とならずに 1 1 に戻ってしまいます。
どうすればmain関数で 2 3 となるんですか?
#include<stdio.h>
void aaa(int a,int b)
{
a=a*2;
b=a*3;
printf("%d %d\n",a,b);
}
int main(void)
{
int a=1;
int b=1;
aaa(a,b);
printf("%d %d",a,b);
return 0;
}
1.aaa()を直せ
2.aaa()を呼び出しているところを直せ
以上
>>311 Cの関数は値渡し。
aaa()の引数をポインタにすればいい。
以上の話がわからなかったら入門書をよく読め。
314 :
デフォルトの名無しさん:2005/04/22(金) 01:59:34
>312
すみません。どのように直せばいいのでしょうか?
>>311 aaa関数の関数定義は引数が値渡しになっているのでmain関数のa,bとaaa関数でのa,bは別のメモリ領域を指していることになるからです。
>>311 アセンブリ言語を調べてみなさい。
Cソースをコンパイルすると、どのようなアセンブリソースになるのかということを知りなさい。
関数呼び出しの仕組みだけでなく、Cの理解がより深まることでしょう。
317 :
デフォルトの名無しさん:2005/04/22(金) 02:06:54
311ですけど、全くわからないです。
できれば直していただきたいのですが。
アセンブリ言語はともかく、
まともな入門書なら「値渡し」とは何か
しっかり解説してるはずだが。
void aaa(int *a,int *b)
{
*a=*a*2;
*b=*a*3;
printf("%d %d\n",*a,*b);
}
aaa(&a,&b);
>>317 ま、直してみたところで「2 6」と出力されるわけだが。
#include<stdio.h>
void aaa(int *a, int *b) {
*a = *a * 2;
*b = *a * 3;
printf("%d %d\n", *a, *b);
}
int main(void) {
int a = 1, b = 1;
aaa(&a, &b);
printf("%d %d", a, b);
return 0;
}
321 :
デフォルトの名無しさん:2005/04/22(金) 02:11:25
>319
ありがとうございます。
>318
入門書持ってません。今度買ってみます。
322 :
デフォルトの名無しさん:2005/04/22(金) 02:12:12
>320
ありがとうございます。
323 :
デフォルトの名無しさん:2005/04/22(金) 05:54:19
クラスの宣言の時に
private:
〜
public:
〜
private:
〜
のようにprivateが2回出てきたりしてるソースがあるのですが、
これって別にc++の文法的とか構文的な意味があるわけではなくて、
ただメンバの役割的に見た目上でグループ分けしたかったりしたいだけですよね?
(また、自分がそうしたいなら別にどこにどんな順序で何回書いてもいいんですよね?)
>>321 入門書も持たんと何をやろうってんだ愚か者が・・・
>>323 private、protected、publicはそれ以後別の指定が出るまではそのレベルのメンバだって示すだけだし、
一つのクラス宣言中に一回しか書いちゃいけないなんて決まりも無いから何回書こうが勝手
まぁ、あまり何度も出ると見難いけどな
>>316 なさいじゃねーよ。何勘違いしてんだよ偉そうに。
たまにいるんだよなーこういう勘違い野郎。
教える教えられるという関係性以前に
他人様と話をしてる事を忘れてんじゃねーよバカが。
君が一番忘れてるっていうオチなの?
328 :
デフォルトの名無しさん:2005/04/22(金) 09:51:20
超初心者な質問だと思うのですが、
この!=の使い方はどういうことでしょうか。
if文でもないのに比較演算子が…教えてくださいお願いします。
例として簡単な他の使用例なんかも教えていただけると助かります。
ちなみにこの関数は
・成功すると、要求したデータ (32 ビット値) が返ります。
・失敗すると、0 が返ります。
だそうです。
hoge = (GetWindowLong(hWnd, DWL_DLGPROC) != 0);
ここで俺がプギャーという。
330 :
328:2005/04/22(金) 09:57:00
あ、比較演算子って真偽値を返すんですね。
何か今まで無意識に使ってました。
331 :
デフォルトの名無しさん:2005/04/22(金) 10:49:49
VCでBCBの__propertyキーワードみたいな機能はないのですかね?
__property int A = {read = GetA, write = SetA};
みたいな書き方ができると便利なんですが・・・。
>>331 __declspec( property(ほげほげ))
コンストラクタをprivate に入れることってあるんですか?
また、そのメリットって何なのでしょうか?
>>335 勝手に生成されないようにできる。
例えばSingletonではインスタンスが勝手に作られては困るのでコンストラクタをprivateにし
インスタンス取得用のstaticメンバ関数を用意するとか。
Effective C++の46項に
ちょっとした例があるな。
滅多に無いと思うがな
そうですか。レス遅れて申し訳ないです。
ご教授ありがとうございました。
どれに対するレスだよ
WinSock2のrawモードを細かく日本語で解説した物ってありますか
342 :
デフォルトの名無しさん:2005/04/23(土) 00:25:26
void swap(int *a, int *b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
void swap(int *a, int *b)
{
int *t;
t = a;
a = b;
b = t;
}
上の関数だと引数の値が入れ替わるのに、
下の関数だと入れ替わらないのはなぜですか?
>>342 上はポインタじゃなくて値そのものを代入しているから。
>>342 void swap(int **a, int **b)
にして、ポインタを入れ替えれば変わるぞ。
夜釣り禁止
346 :
342:2005/04/23(土) 00:37:37
>>344 具体的に関数の中にどうかけば良いか教えてください。
最近の奴は考える力がないな。
ええ、ついでですから利用できるところまで利用してやろうかと。
349 :
341:2005/04/23(土) 00:44:29
忘れないでー
350 :
342:2005/04/23(土) 00:45:45
ポインタは入れ替えられないってことですか?
急速にスレの質が低下してまいりました
>>342 とりあえずメモリの状態を図に書いて一つ一つ追っていくとか
そういうとこから始めてみるのがいいと思うんだ
VC++で.NETを使わずに正規表現を利用したいのですが、
何か良い方法はないでしょうか
boostでいいだろPerl互換の正規表現も使えるし
⊂二二二( ^ω^)二⊃ブーンスト
>>353 COMのVBScript.RegExpとか
>>346 うわっ、本当にレス返してやがった。
#include <stdio.h>
void swap(int **a, int **b)
{
int *t;
t = *a;
*a = *b;
*b = t;
}
int main(void)
{
int i = 123, j = 456, *a = &i, *b = &j;
printf("交換前 i = %d, j = %d\n", *a, *b);
swap(&a, &b);
printf("交換前 i = %d, j = %d\n", *a, *b);
return 0;
}
360 :
目の前は壁だらけ・・:2005/04/23(土) 06:51:31
ただいまCを勉強中なんですが。
どうしても気持ち悪くて前に進めないので誰か助けてください。
ファイル入出力で
if(NULL == (fp = fopen("ファイル名","r")){
printf("オープンエラー\n");
return EXET_FAILURE;
}
と普通にソースコードが書かれている参考書しか見当たらないのですが
条件式を書く部分にファイルオープンの関数が入っていて
条件式としてだけでなくその関数が動いている??
文法的に理屈を説明できる人がいれば、ずっと気持ちが悪いので助けてください・・
>>360 まずfp = fopen("ファイル名","r")の式が実行される。
つまりfopenの戻り値をfpに代入しているわけだな。
= (代入演算子)は代入した値(この場合fopenの戻り値)が演算子の結果となるので、それをNULLと比較している。
その書き方は真似するな。せめてif ((fp = fopen("ファイル名", "r") == NULL) {にしろ。
俺はこうしているが好きにしろ。
FILE *fp = fopen();
if (!fp)
>>350 ポインタも入れ替えできるよ
実際それも入れ替わってる
値が入れ替わらないのはあたりまえ
名刺を交換しても人が入れ替わらないのと同じだな。
違うだろ。仮引数を入れ替えても呼び出し元のポインタには影響しないだけ。
遊びで作ってみた以下のコードが期待したとおりの動作をしないのですが
なにが原因なのか教えていただけると助かります。
gccとvcでやってみたのですがどちらも期待どおりの動作をしませんでした
// printf("%s\n", (itostr(10)).str);
itostrの引数を定数にするとvcでは期待した結果が得られました
#include <stdio.h>
typedef struct {
char str[20];
} ITOSTR ;
ITOSTR itostr(int i) {
ITOSTR its;
sprintf(its.str, "%d", i);
return its;
}
int main()
{
int i;
for (i = 0; i < 10; i++)
printf("%s\n", (itostr(i)).str);
return 0;
}
366 :
365:2005/04/23(土) 11:19:34
gcc3.3.3
vc7.1
です、よろしくお願いします
>>365 漏れの VC6、VC7.1、VC8β、BCC 5.5.1 では動くよ
>>367 拡張子は .c でよろしくお願いします。
すみません実行できました!
vc7.1でコンパイルする時に/O2オプションをつけていたのが原因でした
gccのほうはMinGWを使ってるのが原因なのから不明です・・・
一時オブジェクトはひとつの式が終わったところで破棄されるんじゃなかったっけ?
だとしたらオプションしだいで想定どおり動いたとしても間違ったプログラムということになる。
ま、このスレは環境依存OKだからそれでもいいのかもしれんけど。
>>371 一時オブジェクトの寿命は完全式(だったかな?名前忘れた)の終わりまで。
つまりこの場合はprintf()の呼び出しが終わった後に破壊される。
>360
a == (b = c)
の形の比較は、>361の言う通り。
(b = c)ではまず代入が処理され、代入後のbが値として返る。
それとaとを比較する事になる。
(b = c)は、bにcを代入し、bの値を返す式、なわけ。
fopenは、ファイルを開き、開いたファイルへのポインタを返す。
書かれたのがどこであろうと、fopenは常にこの両方を行なう。
a == (b = c)で、比較だけでなく代入操作も行なわれるのと理屈は同じ。
ちなみに、a = ++b;とか書くと、aへの代入とbのインクリメントが両方行なわれたりもする。
「期待したとおりの動作をしない」が具体的にどうなったのかくらい書けよ
と言いたい。
>>360 そんな本捨てろ。
文脈として、
if ((fp = fopen(...)) == NULL) {
...;
}
の方が読み易いだろ?
まぁ私は
fp = fopen(...);
if (fp == NULL) {
...;
}
とするが。
>>375 > if ((fp = fopen(...)) == NULL) {
> ...;
> }
> の方が読み易いだろ?
主観的な事だからなんとも言えないww
> まぁ私は
> fp = fopen(...);
> if (fp == NULL) {
> ...;
> }
> とするが。
無駄に冗長。短いほうが良い。
>無駄に冗長
冗長
頭痛が痛い
頭痛が痛いの何がいけないんだよ
>>374 vc7.1では空の文字列が表示されて
gcc3.3.3では意味不明文字が表示されました、これであなたから納得できる回答がえられるのかな?
(゚∀゚;)
確かにC++としてコンパイルすると問題ないけどCとしてコンパイルするとダメだね。
>>375 比較するときに定数の方を左に書くと間違って代入してしまうことがなくてよいという説もある。
見易さに対する意見としては同意だし、この場合には==と=を間違っても代入にはならんけど。
確かgccだとifとかwhileの条件の中で代入すると警告でなかったっけ?(オプションかも)
出るよ。VC7でも確か出たと思う。
>>360のような書き方って醜いだけで全然意味がないと思う。
gcc で以下の警告が出た。
17: warning: format argument is not a pointer (arg 2)
g++ なら出ない。
関数から構造体を返したときの扱いが C と C++ で違うみたいだな。
ちょっと調べてみよう。
>>386 それじゃ意味が変わっちゃってるな。
「"=="と間違えて"="と入力するのを防ぐために定数を比較演算子の右側に
置く意義は、両辺が変数のときに破綻する。」
また始まったよ
>>386 頭悪いなお前。単にURI貼ればボロも出なかったのに。
両辺が変数ならそもそも定数は存在しないじゃないか・・・
391 :
385:2005/04/23(土) 19:25:28
392 :
365:2005/04/23(土) 19:39:30
>>391 お疲れ様です。
詳しく調べてくださってありがとうございます
>>389 URIIIIIIIIIIIIIIIII
Uniform Resource Identifier
Uniform Resource Locator
初心者歓迎スレだからね
IN_ADDR構造体に直接値を書き込んで、たとえばffffffにして
inet_ntoa(inaddr)で変換したときに、255.255.255.255って表示させて
みたいんですけど、うまくいきません。
ためしたのは
IN_ADDR inaddr;
u_long sss=(u_long)0xffffff;
strcpy(&inaddr.S_un.S_addr,(char)sss);
です。
よろしくお願いします。
エラーはstrcpyの一番目の引数をulong*_W64からcharに変換できません
とでます。
ちゃんとキャストしてるつもりなのですが…
>>398 memcpy(&inaddr.S_un.S_addr, &sss, sizeof (u_long));
ウホッ できました
>400
char型にしてstrcpyで無理矢理入れてしまえるかと浅はかな考えで
思いつきました。
>401
ネットワーク関連では構造体がいろいろでてきて卒倒しそうでしたが
一つ一つ地道に理解してゆく上での手助けとなりました。
ありがとう
煽るわけじゃないけど、そのレベルでネットワークはキツイかと
誰が何やろうが勝手。たまーにこういう奴いるんだよなー
言わなくていいことをわざわざ口に出さないではいられない奴って。
死ねばいいのに。
だが自分のレベルを知ることは必要だ
それも知らず下手に作るとデータ壊れるぞ
壊して良いじゃない。
403みたいなデリカシーのない奴によって傷つけられてきた被害者として、
発見次第これからも仕返しとして言わなくていいことを言わせてもらおうと思う。
403みたいな糞は、頭に浮かんでしまった言葉が
人を傷つける言葉だと分かっているのに
自分の中にとどめておくことがストレスになるから
口に出さずにはいられなくなってしまうという、
アナル小さい病と潔癖症の合併症。
他にここでよく見かけるのは、
「プログラマー向いてないと思う」とか言ってしまう糞バカ。
質問スレなのに。
こういうバカはプログラマーの前に人間に向いてないから死ねばいいと思う。
>>407 先を越されるのが怖いから他人の勉強に足止めを食らわせたいって
素直に言えよバカ。
急速にスレの質が低下してまいりました
>>409 だからぁ、2chでその程度で一々傷つく方がどうかしているって事実に気付けよ。
ここはそう言う乗りの場所。被害者面して荒らして回る方がよっぽど迷惑だぞ。
そうだな、他人を糞呼ばわりしたかどであんたも人間止めてみたらどうだ?
2CHなんだからどうとかいうバカは死んで欲しいと思う。
「乗り」とか「空気」とかいうアホ理論を信じて疑わず
いつも自分がそれにあわせることに汲々として
それが絶対だと信じて疑わない、おてて繋いで一斉ゴール教育の被害者。
2chだから何でもありって思ってる奴まだいたのか。貴重な化石だ。
409みたいなのもどうかと
なんか必死なのが一匹いるな
必死とか言い出したな。
「必死だな」「空気読め」
バカの常套句。
もまえらおちけつ
今時「おちけつ」ですか……
You is a big fool man. Hahahaha.
はははははははっはははっはは
あっはっはっはっはっはっは
うわっはっはっはっはっはっは
ケケケケケケケケケ
うけけけけけけけけけけk
彼の帰った後、部屋の雰囲気が何か違うことに気づいた。違和感がある。
テーブルだ。いつの間にかテーブルの上に見慣れた花瓶が置いてあった。
チッ チッ チッ ゴォーン 柱時計が午後4時を告げる。
はっ・・・・・・・・・その時 私は気づいた。
彼の話はすべて事実だったのだ・・と。
いや、だからさ、おちけつだとか必死だとか言ってる奴は、騙されたと思って、豆類、ちりめんじゃこなどの小魚、レバー、乳製品、卵黄、カシューナッツ、ごま、そば、たけのこ、ブロッコリー、バナナなどにも多く含まれています。
ごめんなさい。
何一人で暴れてんの?
どのへんが?
↓ここいら変
m9(^Д^)プギャー
本に載っていたx!を求める関数をいじって
int kaijo( int n)
{
int ans;
ans = 1;
for( ; n > 0; n--)
{ ans *= n;}
return ans;
}
と、しても上手く行ったのですが繰り返し部分を
while( n-- > 0)
{ ans *= n}
に変えるとコンパイルはできますが実行するとエラーとなります。
ためしにwhile(n-->1)にするとあり得ない答えが出てきました。
これはfor文ではans*=nの計算を行い、その後n--されるためOK
while文はans*=n--と言う定義されてない?計算のためおかしな動作となる。
と言う解釈であってますか?
while文の方は
nが評価された後nを-1してそれから
ans*=nを行っているんじゃないの
そういうのは{}の中でn--するもの
>>431 while(n-->1)とした時は確かにnに5を入れて計算したら24でした。
(n-->0)の時は最後に0をかけて答えが0になってしまう。
メイン関数の中で分母としてこの値を使ったためにエラーとなったと。
ありがとうございます。
>>432 x^pを求める関数本で
int aaa(int x, int y)
{
int z = 1;
while(y-->0)
{ z *= x}
return z;
}
と言った感じになっていたんで、試しにやってみたいんです。
この場合はyが計算に使われないからうまく行ってたんですね。
>>433 知恵をあげよう
do
{
ans *= n;
} while(--n>0)
なるほど。do-while文を使えば問題は解消できるんですね。
今回の場合は0が渡された場合の処置も必要になりますが。
だからこそwhileにする意味が無い
>>435 do-whileにするだけじゃなくて、--nになってんのも忘れんなよ
経験と知識とセンス
QueryPerformanceCounterを使って処理時間の計測をしているんですが、
実行のたびに計測値が大きくばらついてしまいます(100ms〜180ms)。
これはマルチプロセッサが原因なんでしょうか?
それとも他に理由があるのでしょうか?
どなたかご教授ください。ちなみにw2k、Pen4-3GHzです。
想定の範囲内です
Pen4-3GHzがいくつも搭載されているんだろうか
こんにちわ
地方から出稼ぎに来ている44歳の無職です。先日都内のハロワの
トイレに入ってウンコをしようと思ったのですが、
「トイレットペーパー以外の物は流さないで下さい」と張り紙がしてあっ
たのでウンコをビニール袋に入れて持って来ました。
非常に不便さを感じました。皆さんはどのようにしているのでしょうか
参考に聞かせてくれませんか?
>非常に不便さを感じました
いや、便があったんだろ?
出稼ぎに来て無職ですってよ奥さん
448 :
デフォルトの名無しさん:2005/04/25(月) 14:28:18
質問です。
プリプロセッサの話なので微妙にCとは違うかもしれませんが…。
#define str.substring(x) MySubString(x)
という風に . を含む置換マクロは組めないのでしょうか。
'.' : マクロ定義内で指定された文字の使い方が間違っています。
と出てエラーになってしまします。
ご教授よろしくお願いいたします。
マクロ名にできるシンボルは変数名と同じです。
"."など変数名に使用できない文字はマクロ名にも使用できません。
>>448 エラーのとおり。つーか、一体全体藻前は何がしたいのだ?
ありがとうございました。
>>450 JAVAのソースを、プリプロセッサでごにょごにょしてC++のソースに変換したかったのです。
素直にStringクラスつくってソースエミュレーションします。
つーか、エディタで置換すればいいだけのような飢餓。
もちろんその通りなのですがw
なるべくなら同じソースファイルから、#ifdefの切り替えによってソース互換性を保ちたかったのです。
違う言語同士でソース互換はかなり無茶だと思うが。
というかバグの温床になりそうだ
(((( ;゚Д゚)))ガクガクブルブル
N行L列の行列ととL行M列の行列の積Cを求めるプログラムの一部です。
for( i=0; i<N; i++){
for( j=0; j<M; j++){
for( k=0; k<L; k++){
c[i][j] += a[i][k] * b[k][j];
}
}
}
参考書では2つ目と3つ目のfor文の間に c[i][j]=0; が入ってますが、
自分で作った時には初期化を忘れて上記のように組みました。
このプログラムでは初期化してないのでc[i][j]の値が不定のはずなのに
何故か正しい値が求められました。何故なんでしょうか?
配列も初期化しないと不定の値になると本に書いてあるのですが…
運良く0が入ってたんだろ
やはり運よく0が入っていたんですかね。
ありがとうございます。
BCC5.5で最新のWin32SDKを使いたいんですけど、
可能ですか?
PlatformSDK
つかBCC5.5.1の同梱SDKは最低でもWindows2000まではサポート済みだから困ることあるか?
463 :
デフォルトの名無しさん:2005/04/26(火) 03:59:15
ソースファイルAのグローバルで、
CHoge *hoge;
という感じにクラスhogeのポインタを生成し、ファイルAの関数内で
hoge=new CHoge(hwnd,100,100);
と、インスタンスを生成します。
ソースファイルBの先頭で
extern CHoge *hoge;
として、こちらのファイルB内の関数内などでhogeを使いたいのですが、
どうも上手くいってないようです。
ポインタの使い方が間違ってるでしょうか?
間違えてなければ別の部分にに問題があると分かるので、
教えて下さい。お願いします。
>>463 毎度毎度同じ事を書かないとならない。
それだけの情報では誰も判断できないよ。
上手くいってないと判断した理由はなに?
あてずっぽうに言えばインスタンスを生成するタイミングと
B内の関数が参照するタイミングが前後してるんじゃないかと
思うけど、分からない。
まともな回答がほしかったらソース晒せ。
>>463 それだけの情報ではなんともいえないが、
例えばファイルB内でhogeを参照する段階で生成済みであることが保証されているなら問題ないかと。
グローバル変数だとその辺が厄介だから、避けた方がいいと思うんだけどね。
>>464>>465 ファイルBとその中の関数というのは、CHogeを定義(実装)しているものです。
で、ファイルBでhogeを使おうとしていた所を、思いついてthisとしたら
上手くいきました。
どちらにしろそのインスタンス自身のポインタをさしていると思うのですが、
なぜhogeではいけないのでしょうか?
仮にもう一つ別のインスタンスを作ったとして、
クラス定義のなかでhogeと書いていたらおかしくなりそうな感じはしますが、
インスタンスはhoge一つしか作ってません。
>>466 グローバルインスタンスの初期化のタイミングの問題。
恐らくは、コンストラクタ内でhogeを参照しているのではないか?
hoge = new CHoge(...)
としているのなら、コンストラクタが呼ばれたときには未だhogeには代入されていないぞ。
>>466 をいをい、無茶苦茶なことしてるな。
どこがおかしいかいちいち指摘する元気も出ないわ。
一から勉強しなおせ。
じゃあ黙ってろよ
オマエモナー
(・∀・)
Mac OS X、XCode1.5でC++を使ってるのですが、
バイナリの読み書きをリトルエンディアンで行うにはどうすればいいですか?
それとBIG_ENDIAN LITTLE_ENDIANが両方defineしてあるみたいですが、
場合分けはどうすればいいですか?
>>472 後者は知らんが前者はマクロ書けばいいだけじゃ?
>>473 ifstream.read で読み込んだ時点でエンディアンを変換させることはできませんか?
むり。
gccでコンパイルしているんですが
printf文に日本語が入っているとエラーとなることがあります。
キルケ・ unknown escape sequence:'\214'
などと表示されます。
日本語を削るとコンパイルできるんですが。
何故でしょうか?
日本語が使えない環境で作ってるから。
一応日本語を入れても問題なく動く事も多いです。
コンパイルできなくて悩んでると、大抵の場合日本語を削除すると上手くいったり…
日本語が使えない環境だと完全にコンパイルできないんじゃないんですか?
SJISでソース書いてて0x5cが含まれているに1.5カノッサ
C-x RET f euc-jp-unix
ってやって保存してからコンパイルして味噌
だからエラーが出るんだろ?
日本語使うことを想定してない環境といえば通じるのか
エラーは日本語の文字コードがエスケープシーケンスと被ってるんじゃね?
では、どうすれば同じソースコードで違うコンピュータでも動作しますか?
いろいろ調べてみたんですが、よくわかりませんでしたのでご教授お願いします
1、日本語を使わない
2、日本語も通るコンパイラを使う
3、もっと勉強する
文字コードを変えれば手っ取り早いのに。
皆さんありがとうございます。
>>480を実行してからコンパイルしたら上手くいきました。
SJIS通るgccもあるけどな
>>487 とりあえずおめでとう
レスはちゃんと読もうな
>>483 streamのラッパクラス作って、内部でエンディアン判定、変換させればいいべ。
>>487 0x5cを含む漢字の前に'\'を足してもいいね。
>>491 なるほど、ありがとうございます。とりあえず試してみます。
VC++6,0でやり始めたんだけど、よくわからないので教えてくれ
例えばprintfって打ち込むところを間違ってpintfって打ち込んだとする
直そうと思ってpの次にrを入れるわけなんだが、入れると
iが上書きされてprntfって感じになっちゃう
こんな感じでなにをしても文字が全部上書きされちゃう状態
上書きされちゃうから一文字間違ったらその一行やり直しになってしまう
オプションとか見てもどれいじればいいのかわからないぽ
かなりめんどくさいので上書きされないようにする方法おしーて
>>494 Insertキー。普通は刻印が「INS」となっていると思われる。
キーボードのInsもしくはInsertキーを優しく愛撫しる。
>>495,496
おお、上書きされないようにできたー
ありがとう〜〜
あっ・・・ふあっ・あんっ・・ああっ・・・
499 :
476:2005/04/26(火) 21:42:54
たびたび申し訳ありません。
>>480の方法でコンパイルは出来ましたが実効すると文字化けするようになりました。
>>492 どういうことでしょうか?
ox5cとは\記号のことではないのでしょうか?
Meadowを使ってるためバックスラッシュが表示されますが。
>>497 BackSpaceやHome押すときに間違えて押したりして上書きモードになることがよくある
VCのウィンドウの、ステータスバーの右端の方に「上書」って書いてあるとこがあるから
そこの文字がグレイだったら挿入モード、黒だったら上書きモード
>>499 おまいはエスケープシーケンスを知らんのかと
あとox5cじゃなくて0x5c
無駄に優しいと、質問者がつけあがって
更に言語と関係ないこと訊いてくるよ。
>>499 492は間違っている。問題の字の後ろにバックスラッシュを付けるのが正しい。
Shift JISだと'表'は95 5cになる。2バイト目だけを見てコンパイラがバックスラッシュと解釈してしまう。
Cではバックスラッシュを2つ並べるとバックスラッシュを表すエスケープシーケンスになるから、
'表\'とすると95 5c 5cとなり、コンパイラが\\のエスケープシーケンスとして認識し95 5cを出力させるのがこの対策。
504 :
476:2005/04/26(火) 22:13:18
文字コード適当に変えつつやってみます。
だめだったら日本語使わずにやります。
色々とご迷惑かけました。
505 :
476:2005/04/26(火) 22:23:54
>>503 ありがとうございます。
確かに「表」と使ってました。
それに今までコンパイル出来なかった日本語の後に
バックスラッシュ付けたらコンパイルできるようになりました。
本当に皆さんご迷惑をおかけしました。
506 :
492:2005/04/26(火) 22:23:55
つうか
L"だめぽ"
510 :
デフォルトの名無しさん:2005/04/27(水) 09:59:44
質問です。
基底クラスから、派生クラスの関数を呼ぶ方法はありませんでしょうか。
以下ことの発端です。
JAVAのObjectのように、自滅してくれるクラスを作ろうと試してみました。
Objectクラスに参照カウンターを持たせ、デストラクタにて参照カウントを-1します。
カウントが0になってしまったのなら責任を持って参照先をdeleteします。
参照先は「ObjectData構造体」です。
この実装自体はうまくいき、きちんと自滅してくれます。
次にObjectを継承して、Stringクラスというものを作ってみました。
参照先は「StringData構造体」です。
デストラクタで参照カウントが0になった場合、「ObjectData」ではなく今度は「StringData」を消さなければなりません。
void* m_pDataというポインタを持っているため、指しているアドレスは同じですが
delete (ObjectData*)m_pData とすると正しく解放されません。
もちろんObjectクラスはStringクラスなんぞ知らないし、どう派生されるかもわからないので
delete (StringData*)m_Data と書くわけにもいきません。
ここで考えました。
「String::release()を呼び出せれば正しく解放できるんだけどなぁ…。
releaseはオーバーライド必須にすればいい」
ですがObjectのデストラクタでreleaseを呼ぶと、Object::releaseを呼んでしまいます。
releaseを純粋仮想関数にすると「純粋仮想関数を呼び出してますよエラー」になってしまいます。
>>510 仮想デストラクタでぐぐれ、というかその前に仮想関数でぐぐれ、というかboost::shared_ptrあたりでぐぐったほうがいいかも
template
>>511 お返事ありがとうございます。
仮想関数については、
「基底クラスポインタから呼び出しても、派生クラスのものが呼ばれるようにする」
と解釈いたしました。
これですと
class Object{
public:
~Object(){
//ここで派生先の関数を呼びたい
}
};
という目的とは合致しないように思えますが、私の解釈が検討はずれなのでしょうか。
virtual ~Object();
for(i=0; i<NUM; i++)
{
for(j=0; j<NUM-i; j++)
{
nCount++;
}
}
nCount を NUM使って数式にしたい。
>>512 ありがとうございます。
template<T> として delete T とするのでしょうか。
Objectクラスの中でそうしようと思っても、ObjectはStringDataを知らないので目的通りの使い方はできないように思えます。
templateについては自信がないため、もしかすると超突拍子のない返事となっているかもしれません。
その際はご容赦ください。
>>513 これで何が起こるか確認した方がいいよ。
#include <iostream>
class A
{
public:
virtual ~A() { std::cout << "A::~A()" << std::endl; }
};
class B: public A
{
public:
~B() { std::cout << "B::~B()" << std::endl; }
};
int main(int argc, char *argv[])
{
A *a = new B();
delete a;
return 0;
}
>>514 デストラクタが仮想かどうかが問題になるのでしょうか?
基底クラスのポインタに、派生クラスのアドレスを代入して使っている場合
解放したときにきちんと派生デストラクタが呼ばれないのを防ぐため
というのが仮想デストラクタの意義だと解釈しておりましたが…。
現状 String::~String() → Object::~Object() の順で呼ばれております。
もちろん~String()で参照カウンターを参照し、StringDataの削除を行なえばいいのですが、
カウンターの管理はObjectにまかせたいのです。
>>518 カウンターの管理はObjectで行ない、削除の必要の有無を返してStringで削除汁。
> もちろん~String()で参照カウンターを参照し、StringDataの削除を行なえばいいのですが、
> カウンターの管理はObjectにまかせたいのです。
設計がクソな気がしてきた。
String::~String() で削除できないような StringData って一体何なの?
>>519 カウンターの管理のうちの一つとして「Objectのデストラクタにて参照カウンタを減算」があります。
Objectのデストラクタが実行された後に、Stringに依頼を出す手段を探しています。
そもそもすでにStringはデストラクタで解体されてしまっているのに、
そこに命令を送ることは無理な気もしています。
>>520もおっしゃっているとおり、設計がクソというか、言語の概念自体誤認識しているのかもしれません。
Objectのデストラクタに減算をいれず、継承先で減算を入れるようにしたら?
>>522 そうしてしまいますと、Stringを継承したクラスを作るときに困ってしまいます。
「 カウンターが1のときは、Objectのデストラクタで0になる。
つまりObjectのメソッドに bool checkRelease(){ return (1 == m_nCnt) } でも作って
派生クラスはこれを参照することを義務付ける」
とするのが正しい実装なのかもしれません。
というか、基底クラスのデストラクタから派生クラスのメソッドを呼ぶ方法がなければこれを使うしかないわけですが…。
StringDataをObjectDataから派生させりゃいいんじゃないの?
つーかObjectとかStringって何者なん?
>Objectクラスに参照カウンターを持たせ、デストラクタにて参照カウントを-1します。
>カウントが0になってしまったのなら責任を持って参照先をdeleteします。
これだけならboost::shared_ptrがそのまんまの機能を持ってるんだけど。
realloc でメモリを拡張すると、新しいメモリが今までと
違うメモリブロックに確保された時に以前に取得していた
ポインタが無効になってしまうのですが、それを
int* p = malloc(10 * sizeof(int));
int* hoge = &p[5];
int* newP = realloc(p, 100 * sizeof(int));
if (newP != p) {
hoge += newP - p;
}
と hoge を補正しても大丈夫でしょうか?
>>526 hoge = &newP[5];
の何が不満だ?
>>527 void f(int* p, int* hoge)
{
p = realloc(p, 100 * sizeof(int));
}
f(p, &p[5]);
のように、関数にポインタを渡さなければならないときに困るんです
>>526 >hoge += newP - p;
うまくいきそうな気がするけど、厳密には未定義。
安全を期すなら、こう。
hoge = newP+(hoge-p);
>>528 >p = realloc(p, 100 * sizeof(int));
メモリが確保できなかったときにメモリリークする。
>>524 STLに素晴らしい機能があるのは存じております。
私もC++だけでの開発となれば絶対そっちを使うのですが…。色々と事情がありまして。
>StringDataをObjectDataから派生させりゃいいんじゃないの?
>つーかObjectとかStringって何者なん?
データを参照するポインタみたいなものです。
参照カウンターを共有しており、デストラクタが動作した際に参照カウンターを減算。
0に達した場合はデータの破棄を行います。
JAVAのStringと記述的にもほぼ同等になることを目指しています。
>>532 ObjectData自体に参照カウンタを持たせて、COMみたいにAddRef, Releaseで参照カウンタを増減させ
参照カウンタが0になったら自殺(delete this)。StringDataはObjectDataから派生。
ObjectはObjectDataをAddRef, Releaseで管理。(ObjectDataのdeleteはObjectData自身に任せる)
でいいんじゃないの?
>>533 お返事ありがとうございます。
ObjectData側が自滅できるのならば私の望んでいる実装が可能そうです。
delete thisというのができるのを正直知りませんでした。
これで実装をためしてみようかと思います。
ObjectData側にreleaseを作り、それを仮想クラスとして扱えば
常に正しい型のreleaseが呼べますね。
これからすぐにでも試してみます。
>>533 正しく解放されました!
delete this という知識が無かったので深みにはまってしまったわけですね。
的確なアドバイスに大変感謝いたします。
WTLのCFileDialog関連の質問です。
OFN_ALLOWMULTISELECT | OFN_EXPLORERを指定して、複数ファイルの選択を取得したいんですが、パース部分のコードがどうにも、冗長になってしまいます。
MFCの場合、GetNext〜等あるようですが・・・・
(CodeProjectにあったCFileDialog(MFC)の機能を移植したCFileDialog(WTL)を使えばいいのかなぁ・・・)
スマートなコード見本等、ありませんか?
よろしくお願いします。
そんなの、自分の好き勝手に作れ、お前が普通と思っているのwぷ
wぷ?
WTL
WTL
strstrの逆で、検索文字列の後ろを返すのは?
542 :
540:2005/04/27(水) 19:33:49
ち
>>530 hoge += newP - p;
がダメで
hoge = newP+(hoge-p);
だといいのでしょうか?
544 :
543:2005/04/27(水) 19:41:11
分かりました。
よく考えずに聞いてしまって申し訳ないです。。
char* p = NULL;
の時に、&p[0] ってアドレスを取得してもやっても大丈夫?
p[0]って*(p + 0)のシンタックスシュガーじゃなかったっけ?
キタ━━━━━(゚∀゚)━━━━━!!!!
ぬるぽ〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
ぬるぽぬるぽぬるぽぬるぽ
ぬるぽぬるぽぬるぽぬるぽ
ぬるぽぬるぽぬるぽぬるぽ
ぬるぽぬるぽぬるぽぬるぽ
ぬ・る・ぽーーーーーーーーーーーーーー!!
んじゃあ
&*pってなってぬるぽになっちゃうんじゃ?
その通り
inline を使いたくて、
#ifndef __cplusplus
# if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L) /* c99 */
# define INLINE inline
# else
# define INLINE
# endif /* (__STDC_VERSION__) && (__STDC_VERSION__>=199901L) */
#endif /* __cplusplus */
のようにやっているのですが、他に何かいい方法はないでしょうか?