08/02/23 13:45:44
やっぱりうまくいきませんでした
何が間違っているのか、理解できません
添削をお願いしたいです
c++、Borland C++5.5.1 for win32でやっています
int strch_idx(const char* s, char c)
{
int i = 0;
while(s[i])
{
if(s[i] == 'c') goto end;
else if(s[i] == 0)
{
i = -1;
goto end;
}
i++;
}
end:
return i;
}
272:デフォルトの名無しさん
08/02/23 13:50:02
最近はソフトウェア工学も学ばないのか
273:デフォルトの名無しさん
08/02/23 13:51:13
>>271
>if(s[i] == 'c') goto end;
'c' じゃなくて c では?
あと、else if (s[i] == 0) の判定をする前に while の条件で抜けてしまうかと
274:デフォルトの名無しさん
08/02/23 13:55:02
>>266>>269>>270
そういう不正確な事やってると
>>207 みたいな奴が出てくるんだよ。
275:デフォルトの名無しさん
08/02/23 14:11:18
>>274
俺はCでの話を言ってるんだぞ?
アドレス渡ししかないんだからないんだから、不正確もなにもねぇだろうが
276:デフォルトの名無しさん
08/02/23 14:12:17
Cには参照なんてないんだからそんな言葉つかうなよ。
277:デフォルトの名無しさん
08/02/23 14:13:07
え?マクロは参照じゃないの?
278:デフォルトの名無しさん
08/02/23 14:15:15
C言語は基本的にすべてコピーで渡す
ポインタもコピー
279:デフォルトの名無しさん
08/02/23 14:15:51
>>275
C には参照渡しなんてないんだよ。
280:デフォルトの名無しさん
08/02/23 14:18:09
参照渡しがアドレス渡しの糖衣ってのは正しい
どっちかだけ知らずに語ると馬鹿なことになるけど、どっちもしっかり理解してるなら別に問題ないでしょう
281:デフォルトの名無しさん
08/02/23 14:20:52
static_castと(int)みたいなキャストってなにかなにか違うんですか?
282:デフォルトの名無しさん
08/02/23 14:24:24
>>281
static_castの方が用途が限定される
283:デフォルトの名無しさん
08/02/23 14:24:35
>>280
個人がそう理解するのはかまわんけど、初心者への説明としては不親切じゃね?
284:デフォルトの名無しさん
08/02/23 14:25:07
>>281
Cとの互換性を大事にしたいなら後者、意味をはっきりさせたいのなら前者を使うといいでしょう。
285:デフォルトの名無しさん
08/02/23 14:26:18
>>273
実際やってみると
cuで2が、gguで3が、ijcoで4が返ってきます
これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね?
しかし、while関数自体は終わってるので、s[i]は判定されている
どういうことなんでしょうか?
また、ご指摘を受けて、whileをdo-whileに変更しました、ありがとうございます
286:デフォルトの名無しさん
08/02/23 14:27:11
なんでそんな単純な構造でgotoを使う必要があるのか解らん。
287:デフォルトの名無しさん
08/02/23 14:30:00
gotoは怖くて使えない・・・
てか絶対使わないようにしてるんだが、違うのか
288:デフォルトの名無しさん
08/02/23 14:31:58
>>280
単なる構文糖衣じゃない。
参照の参照というのは存在しないが、
ポインタのポインタというのは存在する。
これは大きな違いで、適当な教え方してると >>207 みたいなやつが出てくる。
289:デフォルトの名無しさん
08/02/23 14:33:55
>>287
むしろ使った方が綺麗になる状況では使う。
でも、上のは break; 使えば解決できることで、
goto を使って解決すべきじゃない。
290:デフォルトの名無しさん
08/02/23 14:37:52
>>282
>>284
当面はあまり気にしなくてよさそうですね
どうもありがとうございました
291:デフォルトの名無しさん
08/02/23 14:39:03
>>290
いいや、気にしろ。
292:デフォルトの名無しさん
08/02/23 14:42:06
普通は C 風のキャストは使うべきじゃない。
せいぜいクラスのテンポラリオブジェクトを作るのに関数風のキャストを使うくらい。
293:デフォルトの名無しさん
08/02/23 14:47:55
>>292
それはキャストよりもコンストラクタ呼び出しのほうがしっくりくる
294:デフォルトの名無しさん
08/02/23 14:49:30
昨日質問したものですが、char * 型とchar []を判別する方法はありませんか?
295:デフォルトの名無しさん
08/02/23 14:52:19
ソースコードを読みましょう。
296:デフォルトの名無しさん
08/02/23 14:54:36
>>291
すいません
気にしろとだけ言われましてもなにに気を使えばいいのかわかりません
まずい点でもでてくるのか
だとかを教えていただけませんか
297:デフォルトの名無しさん
08/02/23 14:58:13
キャストには色々意味があって、C言語風キャストだとそれらをすべて内包してしまって意図が掴みにくい
298:デフォルトの名無しさん
08/02/23 14:58:20
メインウインドウにBUTTONを作成するときなどで使う、
CreateWindowとCreateControlWindowはどう違いますか?
299:デフォルトの名無しさん
08/02/23 15:00:58
>>296
C風のキャストはなんでもかんでもキャストできてしまうので、
プログラマの意図と違ってても警告が出ない
const void *p = ~;
char *q = (char*)p; // charにキャスト・・・あれ? constも外しちゃったよ! でも警告は出ない
char *r = static_cast<char*>(p); // コンパイルエラー: static_castでconstは外せない
char *s = const_cast<char*>(static_cast<const char*>(p)); // constも外したい意図の場合はこう書く
300:デフォルトの名無しさん
08/02/23 15:03:54
>>286-287
gotoのほうが行き先が明確になるので、理解しやすかったので、用いていますが
なぜ怖いのでしょうか
それと、「これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね?
しかし、while関数自体は終わってるので、s[i]は判定されている
どういうことなんでしょうか? 」
これにも答えていただけると非常にありがたいです
301:デフォルトの名無しさん
08/02/23 15:04:05
>>296
キャストというのは基本的にマズい処理。
アップキャストだけは例外的に安全だが、
それ以外は基本的にはあまりやるべきではない。
でも、実際にはどうしてもやる必要が出てくる事もある。
こればっかりは仕方が無い。
そういう時、C 風のキャストを使ってしまうと色々と問題が発生する。
・ 間違って危険なキャストをしてしまうかもしれない。
例えば、const を付けるべきところで const を付け忘れたり。
こういう時、static_cast なら危険な const の付け忘れがあるとコンパイルエラーになる。
C 風キャストだと問答無用でキャストされてしまう。
これが一番の問題。
・ キャストが原因っぽいバグが見つかった時、どこにキャストがあるのか探すのが面倒。
C++ のキャストだと検索でキャストを行っている箇所を簡単に見つけられる。
・ キャストがあまり目立たない。
危険な処理を行っている箇所が目立たないのは危険。
C++ のキャストは非常に目立つ。
・ 打鍵数が少ないので気軽にキャストをしてしまう。
C++ のキャストは打ち込むのが面倒で、キャストを本当に使うべきなのか
立ち止まって考えるよう思考を誘導してくれるかもしれない。
・ 今行おうとしているキャストはどういうものかをあまり意識しないかもしれない。
キャストという処理を軽く見ているのはよろしくない。
302:デフォルトの名無しさん
08/02/23 15:06:01
>>300
gotoが必要になるのは言語の構造化能力を超えた構造が必要になる場合であって、
この場合はそういう場合でない。
303:デフォルトの名無しさん
08/02/23 15:06:12
>>300
論理的に記述しようぜ。
「while を終了する」 と 「指定位置に移動する」 では
前者の方がより論理的だ。
論理的なコードは、一般に変更に強く、バグが出にくい。
まあ、break すらみだりに使うべきじゃないという人もいるけどね。
304:デフォルトの名無しさん
08/02/23 15:07:50
関数の引数で、char * 型とchar []型を判別する方法ありますか?
305:デフォルトの名無しさん
08/02/23 15:09:39
>>304
不可能
306:デフォルトの名無しさん
08/02/23 15:10:05
void foo(char* const& hoge);
template <size_t N> void foo(char (&hoge)[N]);
と区別できなくはない。
307:デフォルトの名無しさん
08/02/23 15:12:02
char[N]とchar[]は別物だと思うよ。
308:デフォルトの名無しさん
08/02/23 15:12:33
void foo(char* hoge, size_t size);
template <size_t N> inline void foo(char (&hoge)[N]) { foo(hoge, N); }
もちろん、こう実装するんだぜ。
309:デフォルトの名無しさん
08/02/23 15:13:12
そう言う意味での char [] 型なんてそもそも存在しないが。
310:デフォルトの名無しさん
08/02/23 15:13:14
>>285
>cuで2が、gguで3が、ijcoで4が返ってきます
その書き方はおかしい
strch_idxには引数が2つあるので、cuとかgguだけでは結果は決まらないはずだ
311:デフォルトの名無しさん
08/02/23 15:13:24
>>300
逆。
gotoの方がどこにでも飛ばせるせいで行き先が不明確になる。
自分の書いたコードを他人に読ませることを想像してごらん。
breakならどこに飛ぶのか一目瞭然だけど、gotoだといちいちラベルを検索しないといけない。
しかもbreakなら「ループの終了」という意図が一目瞭然だけど、
gotoだとどういう意図で飛ばしたのかを考えないといけない。
そういう理由でgotoは避けられるため、安易にgotoが入っているとさらに、
「gotoを使わなければいけないどんな理由があったのか?」と考えさせることになる。
312:デフォルトの名無しさん
08/02/23 15:14:13
int⇔floatの変換だけでも、毎回static_cast使う?
あと、コンテナの最後の要素以外を処理する時、
std::vector<T> container;
for (int n = 0; n < static_cast<int>(container.size()) - 1; ++n) container[n] = ...;
ってやる?
313:デフォルトの名無しさん
08/02/23 15:23:01
>>312
俺はstatic_castを使う
コンテナの方は
for (size_t n = 0; ~
って書けばいいのでは
本当は std::vector<T>::size_type の方が適切なのかもしれんが
314:デフォルトの名無しさん
08/02/23 15:23:54
>>312
>int⇔floatの変換
うん。
>最後の要素以外を処理
unsigned使う。
315:デフォルトの名無しさん
08/02/23 15:31:10
>int⇔floatの変換だけでも、毎回static_cast使う?
使う。
>コンテナの最後の・・・
for (std::vector<T>::size_type n = 0, size = container.size(); n + 1 < size; ++n) container[n] = ...;
ってやると思う。
符号無しの値を符号付きにキャストするのは基本的に危険だと思う。
316:デフォルトの名無しさん
08/02/23 15:32:52
後者の場合、
if( !c.empty() )
for( size_t n=0; n<c.size()-1; ++n)
で何か問題あるのか?
317:デフォルトの名無しさん
08/02/23 15:34:18
>>316
n + 1 < c.size() で判定すれば empty チェックは要らない。
318:デフォルトの名無しさん
08/02/23 15:36:12
typename 忘れてた。
まあ T をそういう意味で使ってるとは限らないが。
319:デフォルトの名無しさん
08/02/23 15:39:01
>>302 >>303
>>311での説明とほぼ同じという理解でよろしいでしょうか
>>311
gotoよりbreakを使うべきというのは、よく理解でき、納得できました
しかし、怖いというのは一体
>>310
すみませんが、もうすこし噛み砕いて説明願えないでしょうか
const char* sには、任意の文字列が入って、char cで、検索する文字を固定という事ではないんですか?
そのconst char* sにcuですとか、gguですとかが入っているので、これで十分だと考えているのですが
320:デフォルトの名無しさん
08/02/23 15:43:08
>>319
goto はまず特定の状況でしか使われない。
それ以外で使われると混乱するし、
何のために使われているかすぐに分からないので不気味で怖い。
321:デフォルトの名無しさん
08/02/23 15:44:11
>>319
goto は意図が不明確。
goto のあるコードを変更することになった場合、
その意図が 100% 分からなければ、
手を加えて変なことになりかねないので怖い。
322:デフォルトの名無しさん
08/02/23 15:44:56
>>319
一番怖いのは、バグの温床になること。
コードの分かりにくさってのはバグに直結する。
323:デフォルトの名無しさん
08/02/23 15:47:14
>>315
イテレータ使うならこうだな。
前進イテレータでさえあれば、これでいけるはず。
if(! container.empty()) {
Iter it_next = container.begin();
++it_next;
for(Iter it = container.begin(), end = container.end(); it_next != end; ++it, ++it_next) *it = ...;
}
324:デフォルトの名無しさん
08/02/23 15:52:18
>>319
const char* s が cu でも c の方は
strch_idx("cu", 'c') とか
strch_idx("cu", 'u') とか
strch_idx("cu", 'x') とか色々指定できるわけで
325:デフォルトの名無しさん
08/02/23 15:53:30
>>320-322
なるほど、よく理解できました
ご親切にありがとうございます
1、意図が不明で不気味で怖い
2、バグを招きやすいから怖い
この二点ですね
そして、本筋のほうもできたら説明していただきたいのですが
326:デフォルトの名無しさん
08/02/23 15:53:54
STLつかうとコンパイルに時間かかりますけど、クラスも多少鈍くなるんですか?
327:デフォルトの名無しさん
08/02/23 15:58:00
そもそも while じゃなくて for 使おうぜ。
328:デフォルトの名無しさん
08/02/23 15:58:55
>>326
一般に、コンパイルに時間がかかる方が、
コンパイル時にある程度処理を行ってくれているため、速くなる。
ただ、コードがあまりにも肥大してくると、
キャッシュの効きが悪くなって遅くなる事もある。
329:デフォルトの名無しさん
08/02/23 16:02:03
>>325
いくつか修正したみたいだけど今はどうなってるの?
330:デフォルトの名無しさん
08/02/23 16:05:44
>>324 >>329
最初から全文現すべきでしたね、申し訳ありません
#include <iostream>
using namespace std;
int strch_idx(const char* s, char c)
{
int i = 0;
do {
if(s[i] == c) goto end;
else if(s[i] == 0)
{
i = -1;
break;
}
i++;
} while(s[i]);
return i;
}
int main()
{
cout << "文字列を入力:"; char p[] = ""; cin >> p;
char c = c; cout << strch_idx(p, c);
return 0;
}
>>327
forだと、終了させるための条件が思いつかなかったので、whileにしましたが、やはりforのほうが良い理由があるのでしょうか
331:デフォルトの名無しさん
08/02/23 16:07:30
>>330
>char c = c;
これはなによ
332:デフォルトの名無しさん
08/02/23 16:08:43
>>330
continue した時でもインデックスが増えてくれるのと、
インデックスをなめていく操作を行っているという意図が伝わりやすいのと。
終了条件は while の時と同じでいいじゃん?
333:デフォルトの名無しさん
08/02/23 16:16:31
>>330
goto end ってどこに飛んでるの?
334:デフォルトの名無しさん
08/02/23 16:17:17
>>330
goto endが一個消し忘れ。
×char c = c;
○char c = 'c';
-1を返したいのは文がヌル文字だけだった場合?それとも文字が見つからなかった場合?
前者ならループのたび判定するのは無駄だから最初に一回だけ判定させたらいい。
後者ならヌルが見つかった時点でループが終わってるから中のlese-if節は判定してくれない。
最初に文字列の長さを測って最後までループが回った場合に-1を返すようにしないと。
335:デフォルトの名無しさん
08/02/23 16:26:11
f(x)のあとでstrlen(ch)が1になることがあります もとのソースを簡略にしました
構造体を参照渡ししてもだめでした 下は期待通りの動作をします 何がいけないのかわかりません
#include <string.h>
#include <stdio.h>
typedef struct STRDATA{ char *start; char *end;}strdata;
f(strdata x){
delete x.start;
x.start = new char [20];
strcpy(x.start,"++++++++++++++"); }
main(){
char *ch=new char [10]; strcpy(ch,"uuuu");
strdata x;
x.start=ch; x.end=ch+strlen(ch);
f(x);
printf("%s",ch);}
336:デフォルトの名無しさん
08/02/23 16:26:35
なんで do-while になってるんだろう。
もっと単純に考えようぜ。
まず、文字を1つずつ取得していくループを書く。
for(i = 0; /* 文字列が終了するまで */; i++) {
/* s[i] で文字を先頭から順番に走査していける */
}
んで次に、c が見つかったらインデックスを返すようにする。
for(i = 0; /* 文字列が終了するまで */; i++) {
/* s[i] が c なら i を返す */
}
そして、検索しても c が見つからなかった場合は -1 を返す。
for(i = 0; /* 文字列が終了するまで */; i++) {
/* s[i] が c なら i を返す */
}
/* -1 を返す */
これでおk。
337:デフォルトの名無しさん
08/02/23 16:29:05
>>304
Cならシーキビだろ
C++か?
template<typename T>
struct IsArray {
enum { value = 0 };
};
template<typename T, size_t N>
struct IsArray<T[N]> {
enum { value = 1 };
};
template<typename T>
bool test(const T&) {
return IsArray<T>::value;
}
template<typename T>
void f(const T& t) {
if(test(t)) cout << "配列だ" << endl;
else cout << "配列じゃない" << endl;
}
338:デフォルトの名無しさん
08/02/23 16:29:46
てか、C++ならブースト使えよか
339:デフォルトの名無しさん
08/02/23 16:30:19
>>335
f の呼び出し後、ch は既に delete された後のアドレスを保持することになるから
絶対にアクセスしちゃダメ。
そもそも生のポインタで確保されたメモリを扱ってるからそういう事が起きる。
コンテナ使え。
340:デフォルトの名無しさん
08/02/23 16:30:21
これだとエラーで止まります どうすればいいですか
f(strdata *x){
delete x->start;
x->start = new char [20];
strcpy(x->start,"++++++++++++++"); }
main(){
char *ch=NULL;
strdata x;
x.start=ch; x.end=ch+strlen(ch);
f(&x);
printf("%s",ch);}
341:デフォルトの名無しさん
08/02/23 16:31:18
>>335
chに割り当てたnew char[10]はfの中でdeleteされてるから、
printf("%s",ch) は違法。
それからnew[]した配列はdeleteではなくdelete[]しないといけない。
342:デフォルトの名無しさん
08/02/23 16:34:08
>>340
char *ch=NULL;
x.end=ch+strlen(ch);
ヌルポインタに整数を足しても有効な値にはならない。
343:デフォルトの名無しさん
08/02/23 16:35:22
バイナリ文字列の始めと終わりを構造体で渡して、内容、サイズを書き換えるには
>>335をどう変更すればできますか?
344:デフォルトの名無しさん
08/02/23 16:37:35
普通に先頭のポインタとstrlen使って適当に操作したらいいんちゃう?
345:デフォルトの名無しさん
08/02/23 16:38:25
バイナリ・・・文字列??
それはともかく、std::string 使え。
#include <string>
void f(string& str) {
str = "++++++++++++++";
}
int main() {
std::string str("++++");
printf("%s\n", str.c_str());
f(str);
printf("%s\n", str.c_str());
}
346:デフォルトの名無しさん
08/02/23 16:38:32
このふたつは動きますが内容が変化しません なぜですか
f(strdata x){
delete x.start; x.start = new char [20];
strcpy(x.start,"++++"); }
main(){
char *ch=NULL;
strdata x;
x.start=ch;
f(x);
printf("%s",ch);}
f(strdata *x){
delete x->start; x->start = new char [20];
strcpy(x->start,"++++"); }
main(){
char *ch=NULL;
strdata x;
x.start=ch;
f(&x);
printf("%s",ch);}
347:デフォルトの名無しさん
08/02/23 16:38:49
1つ目、std:: 忘れた。
348:デフォルトの名無しさん
08/02/23 16:41:16
C言語だけで、0を含む文字列を変化させたいのですが、できないですか?
349:デフォルトの名無しさん
08/02/23 16:42:49
>>346
ポインタが参照渡しでどうのこうの言ってた奴だよな?
頼むからポインタとは何かを一から勉強し直してくれ。
350:デフォルトの名無しさん
08/02/23 16:44:23
>>346
関数に渡された数値は数値がコピーされただけの別物。
だから関数内でx.start = new char [20];とかやっても呼び出し元のxには変化は無い。
351:デフォルトの名無しさん
08/02/23 16:44:32
f(x)で、(バイナリ)文字列を書き換えられるやり方教えてください それみて勉強します
352:デフォルトの名無しさん
08/02/23 16:45:30
>>351
まともな本読め。
そこにいくらでもサンプルは書いてあるし、
詳細な解説も載ってる。
353:デフォルトの名無しさん
08/02/23 16:46:24
>>350
後者はアドレス渡しですけど・・・
354:デフォルトの名無しさん
08/02/23 16:47:42
>>353
後者では x は書き換えられるが ch は書き換えられない。
355:デフォルトの名無しさん
08/02/23 16:47:47
>>353
アドレスの指す先の内容を書き換えると呼び出し元へ反映されるというだけのこと。
356:デフォルトの名無しさん
08/02/23 16:50:34
x->start = ch
ってやっても、ch と x->start がリンクされるわけじゃない
x->start の内容が変化しても、chには関係ない
357:デフォルトの名無しさん
08/02/23 16:52:12
これで正解でしょうか?
#include <string.h>
#include <stdio.h>
typedef struct STRDATA{ char **start; char **end;}strdata;
f(strdata x){
delete *(x.start); *(x.start) = new char [20];
strcpy(*(x.start),"++++++++++++++"); }
main(){
char *ch=NULL;
strdata x;
x.start=&ch;
f(x);
printf("%s",ch);}
358:デフォルトの名無しさん
08/02/23 16:52:50
図を描こうぜ。図を。
ch, x, そして動的に確保されたメモリが
実際にメモリ上でどう置かれていてどう参照していて
何を実行するとどう変化するか。
359:デフォルトの名無しさん
08/02/23 16:54:53
>>357
それでとりあえずまともに動くね。
推奨されるコードかと言うとまたそれは別だが。
new 使ってるから C++ なんでしょ? コンテナ使えば楽だぜ。
360:デフォルトの名無しさん
08/02/23 16:58:05
横から質問で申し訳ないんだけど、
・>357のfに渡す前に、xはいつnewされてるの?
・関数の一行目がdeleteって、ものすごく気持ち悪いんだけど、よくつかう手法なの?
361:デフォルトの名無しさん
08/02/23 17:00:09
>>360
deleteにNULLを渡しても何も起こらないことになっているから、
最初にnewされていないというのは大丈夫。エラーにはならない。
最初にdeleteというのは必要に応じて使えばいいと思うけど、
俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
362:デフォルトの名無しさん
08/02/23 17:03:44
サンクス たびたびどうもありがとうございます
363:デフォルトの名無しさん
08/02/23 17:04:30
俺も横レスだけど、配列なのに delete [] にしてないのは問題ないのか?
364:デフォルトの名無しさん
08/02/23 17:04:41
>>363
大問題。
365:デフォルトの名無しさん
08/02/23 17:05:56
だからコンテナを使おうぜと言ってるのに。
366:デフォルトの名無しさん
08/02/23 17:06:16
いろいろな意味で気持ち悪い。というか何をしたいのかよくわからない。
367:デフォルトの名無しさん
08/02/23 17:07:46
>361
>deleteにNULLを渡しても何も起こらないことになっているから、
>最初にnewされていないというのは大丈夫。エラーにはならない。
なるほど、どうもです。
>最初にdeleteというのは必要に応じて使えばいいと思うけど、
>俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
なるほど。
よく考えたらC++になってからnewなんてほとんど使ったこと無かった気がします。
動的な配列が必要になったらだいたいvectorにつっこんでた。
368:デフォルトの名無しさん
08/02/23 17:10:42
clear はメモリが解放される訳じゃないんだよな。
std::vector<int>().swap(v); みたいにしないとメモリは解放できない。
解放した方がいいかどうかは状況次第だが。
369:デフォルトの名無しさん
08/02/23 17:32:26
>>364
大問題ってことで軽くググってみたら、
・配列に対して、delete [] としなかった場合、1個目の要素のみデストラクタが走り、残りの要素は走らない
・確保された領域(配列)は一応開放される(デストラクタで開放されるべき領域は除く)が、
要素数保持のための隠れた確保領域は開放されずに残る
ってな、感じかな
370:デフォルトの名無しさん
08/02/23 17:37:02
勘違いしてないか?タスクマネージャで確認してみ
#include <stdio.h>
main(){
char *ch=new char[200*1024*1024];
getchar();
printf("delete 実行\n");
delete ch;
getchar();}
371:デフォルトの名無しさん
08/02/23 17:40:15
これでも解放するし
#include <stdio.h>
main(){
int n;
char **ch=new char*[200];
for(n=0;n<200;n++)ch[n]=new char [1024*1024];
getchar();
printf("delete 実行\n");
for(n=0;n<200;n++)delete ch[n];
getchar();}
372:デフォルトの名無しさん
08/02/23 17:42:39
>>331
strch_idx関数に渡すためのcを、main関数のほうで作っておかないとだめかなと考えまして
>>332
あまり理解できませんが、なるべくforを使うようにします
>>333
消し忘れです
ご指摘ありがとうございます
>>334
理屈を丁寧に解説していただきありがとうございました
>>336を参考にやってみて、できました
>>336
ご丁寧にありがとうございました
その指針でできました
最後にご丁寧に、教えるのもわずらわしいような初歩的な愚問に答えていただき、ありがとうございました
373:デフォルトの名無しさん
08/02/23 17:44:35
これが初心者歓迎スレの良心。
374:デフォルトの名無しさん
08/02/23 17:47:40
>>370
>>371
特に勘違いしてるところはないと思うが・・・
要素数を保持する領域はないってことを言いたいのか?
組み込み型にはないけど、クラスにはあるみたいなことが書いてあったんだが
375:デフォルトの名無しさん
08/02/23 17:49:37
これだと解放しないけど・・・ *xと定義されているなら、deleteを使うのでは? []は**xを解放する場合でしょ
#include <stdio.h>
main(){
char **ch=new char*[200];
for(int n=0;n<200;n++)ch[n]=new char [1024*1024];
getchar(); printf("delete 実行\n");
delete[] ch; // delete ch;
getchar();}
376:デフォルトの名無しさん
08/02/23 17:50:41
>>369
そもそもnew[]したものをdeleteするとどうなるかは未定義。
そういう挙動になったという話は、たまたまその実装ではそうだったということでしかない。
377:231
08/02/23 17:51:43
今更ですが>>231のようなことをした時に
MyArrayの方はデフォルトコンストラクタか引数を省略できるコンストラクタを
呼んでいるようなのですが、これのタイミングが分かりません。
コンストラクタを通過するそぶりもないし、一応初期化はされてるっぽいし・・・
特にデストラクタのタイミングも分からないのが心配です。
いつ開放されるんでしょうか?
378:デフォルトの名無しさん
08/02/23 17:54:33
>>377
どこかでnew[]やdelete[]しているだろ?そのときだ。
379:デフォルトの名無しさん
08/02/23 18:04:57
>>375
newで割り当てたものはdelete、new[]で割り当てたものはdelete[]で解放します。参照の深さは関係ありません。
380:デフォルトの名無しさん
08/02/23 18:12:04
終端をセットしたいのですがどうやったらいいですか? コンパイルが通りません
main(){
char *ch=new char [50];
char **start, **end;
start=&ch; //これは成功します
end=&&ch[20];
// end=&(ch+20);
}
381:デフォルトの名無しさん
08/02/23 18:24:57
ch と &ch[0]は同じアドレスを表しますよね 20個目のアドレスは、&ch[20]ですよね
それを参照渡ししようとしたら&&ch[20]のはず・・・
382:デフォルトの名無しさん
08/02/23 18:26:38
char * chend = &ch[20];
end = &chend;
383:デフォルトの名無しさん
08/02/23 18:33:33
>>382
コンパイルはできましたが、startと動作が違うようです
main(){
char *ch=new char [50]; strcpy(ch,"abcdef");
char **start, **end;
start=&ch;
char * chend = &ch[20];
end = &chend;
printf("%c\n", ((*start+1)[2]) );
printf("%c\n", ((*end-5)[2]) );
}
384:デフォルトの名無しさん
08/02/23 18:34:48
間違えました 20個を定義していませんでした
これだとうまくいきました サンクス
char * chend = &ch[6];
end = &chend;
printf("%c\n", ((*start+1)[2]) );
printf("%c\n", ((*end-5)[2]) );
385:デフォルトの名無しさん
08/02/23 18:38:15
なぜ「end = &&ch[20];」というか「end = &(&ch[20]);」ができないかは理解しておいてね。
386:デフォルトの名無しさん
08/02/23 18:41:41
再使用できるように動的確保したら複雑になってきました・・・
main(){
char *ch=new char [50]; strcpy(ch,"abcdef");
char **start, **end;
start=&ch;
char **chend =new char *;
*chend=&ch[6];
end = &(*chend);
printf("%c\n", ((*end-5)[2]) );
}
387:デフォルトの名無しさん
08/02/23 18:43:04
先ずお前はnewを使うのをやめろ。話はそれからだ。
388:デフォルトの名無しさん
08/02/23 19:53:27
これはひどい
389:デフォルトの名無しさん
08/02/23 20:04:00
何がしたのか全然わからない
390:デフォルトの名無しさん
08/02/23 20:04:21
何度基礎をやり直せと言ったことか
391:デフォルトの名無しさん
08/02/23 20:26:55
なぜ、再使用しようとすると動的確保することになるのかもわからない。
文章で理由を説明してほしい。
392:デフォルトの名無しさん
08/02/23 20:36:55
なるほど、stringが出来るわけだ
393:デフォルトの名無しさん
08/02/23 20:53:56
おまえらほんと我慢強いよな。感心するよ
俺は>>386と同レベルのコードを保守する羽目になって殺意を覚えた。
394:デフォルトの名無しさん
08/02/23 21:00:35
我慢強いというか、読んでない
395:デフォルトの名無しさん
08/02/23 21:02:02
C++の授業で先生が、
int main() {
int i;
cin>>i;
double a[i];
...
というコードはC++では出来ない(やりたいならnewでやるべき)と言われたのですが、
g++とiccではできました。これってだめだけど、gccやiccの拡張機能によって
できているのでしょうか?
396:デフォルトの名無しさん
08/02/23 21:04:05
>>395
C++ が変化し続けているだけの話
397:デフォルトの名無しさん
08/02/23 21:09:33
>>395
現状のC++標準規格じゃ無理。C99は可能。
C99サポートしてるコンパイラなら期待してもいい。
398:デフォルトの名無しさん
08/02/23 21:11:02
newも使うべきではないよな。いやnew[]ではなくてstd::vector。
399:デフォルトの名無しさん
08/02/23 21:13:17
C99は正直あんまやらないでほしい
400:デフォルトの名無しさん
08/02/23 21:18:40
可変引数マクロはマジホシス
401:デフォルトの名無しさん
08/02/23 21:24:18
0xでおk
402:デフォルトの名無しさん
08/02/23 21:35:03
おしえてください 下から2行目を動かすとデータが壊れるのですが原因がわかりません
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct STRDATA{ char **st; char **end; }strdata;
f(strdata x){ printf("%s",*(x.st)); }
strconv(strdata *q, char **p){
char **chend =(char **)malloc(sizeof(char **));
q->st=p;
*chend=&(*p)[strlen(*p)];
q->end = &(*chend);}
strconstconv(strdata *q, char *p){
int n=strlen(p);
char *ch=(char *) malloc(n+1);
strcpy(ch,p);
q->st=&ch;
char **chen =(char **)malloc(sizeof(char **));
*chen=&(ch[n]); q->end = &(*chen);}
main(){
strdata str;
#define STR "abcdefgh"
strconstconv(&str, STR); //ここをコメントアウトして一つ下を動かしても平気です
//char *ch=new char [50]; strcpy(ch,STR); strconv(&str,&ch);
//char *x=new char [1]; ここを動かすとおかしくなります
f(str); }
403:デフォルトの名無しさん
08/02/23 21:37:15
もうお前いい加減諦めたら。
ローカル変数のアドレスを関数外に持ち出すな。
404:デフォルトの名無しさん
08/02/23 21:39:05
char *x=new char [1]; が、なぜstrdata strを書き換えられるんでしょうか?
405:デフォルトの名無しさん
08/02/23 21:39:21
なんかまぁ・・・・・・いろいろとおつかれさん
406:402
08/02/23 21:45:20
おなじやつですが短くしました 下から2行目を動かすと壊れるのはなぜでしょうか
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct STRDATA{ char **st; char **end; }strdata;
f(strdata zzz){ printf("%s",*(zzz.st)); }
strconstconv(strdata *q, char *p){
int n=strlen(p);
char *ch=(char *) malloc(n+1);
char **chen =(char **)malloc(sizeof(char **));
strcpy(ch,p);
q->st=&ch;
*chen=&(ch[n]); q->end = &(*chen);}
main(){
strdata str;
strconstconv(&str, "abcdefgh");
// char *test=new char [1];
f(str); }
407:デフォルトの名無しさん
08/02/23 21:46:36
まず変数のスコープを勉強しよう
408:402
08/02/23 21:48:09
なぜコメントアウトを外すとデータがこわれますか?
409:デフォルトの名無しさん
08/02/23 21:53:31
newやmallocの確保は、解放しない限り残るんですよね そのアドレスは参照で受け取っているので問題ないと思うのですが
参照渡しにしてもだめです
f(strdata *zzz){ printf("%s",*(zzz->st)); }
main(){
strdata str;
strconstconv(&str, "abcdefgh");
f(&str); }
410:デフォルトの名無しさん
08/02/23 21:54:33
基礎からやりなおせよ
411:デフォルトの名無しさん
08/02/23 21:56:58
ヒントください
412:デフォルトの名無しさん
08/02/23 21:57:01
いいから基礎からやりなおせって。スタックとヒープの概念すら分かってないだろ。
413:デフォルトの名無しさん
08/02/23 21:57:11
>>409
トリップをつけてくれるとあぼーんしやすいのですがいかがでしょうか
414:デフォルトの名無しさん
08/02/23 22:00:25
スタックとかヒープとか、この際関係ないレベルじゃん
415:デフォルトの名無しさん
08/02/23 22:02:39
より短くしました これでも外すと壊れます なぜですか?
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; char **end; }strdata;
f(strdata *q){
char *ch=(char *) malloc(10);
strcpy(ch,"abcdef");
q->st=&ch; }
g(strdata *zzz){ printf("%s",*(zzz->st)); }
main(){
strdata str; f(&str);
//char *test=new char [1];
g(&str); }
416:デフォルトの名無しさん
08/02/23 22:03:36
>>409
多少手を入れて(int mainとするとか)こっちで動かしてみましたが、ちゃんとabcdefghと表示されました。
でも、newだけc++の機能をつかってるけど、あとは全部(結構年季が入った感じの)cだし、
c++のコンパイラなら、関数の戻り値を指定しないのはダメだと思うし、
mallocとnew は併用したらダメだってどこかで聞いたけどな。
いまいちやろうとしていることの意図がつかめません。
(mallocとnewを併用して、どういう状況でまずいのかしらべようとしているのか)
もしc++を勉強しようとしているなら、なにか適当な本とかで勉強するのを勧めます。
Cを上記くらいご存知なら、すぐにC++も使えるようになりますよ。
417:デフォルトの名無しさん
08/02/23 22:03:53
ヒントもなにも>>403がずばり回答してるんだが。
これでもわからないなら、なんでもいいからポインタの無い言語に行ってくれ。
そして帰ってくんな。
418:デフォルトの名無しさん
08/02/23 22:08:06
>>415
なんでお前は答えを貰っても全くレスポンスを返さずに、
そんなヘドロみたいなコードを貼り続けるんだ。
頭沸いてるのか
419:デフォルトの名無しさん
08/02/23 22:08:35
>>415
これなら動く。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *st;
char *end;
} strdata;
void f(strdata *q) {
char *ch=(char *)malloc(10);
strcpy(ch,"abcdef");
q->st = ch;
}
void g(strdata *zzz) {
printf("%s", zzz->st));
}
int main() {
strdata str;
f(&str);
g(&str);
return 0;
}
420:デフォルトの名無しさん
08/02/23 22:11:12
>>419
おまいやさしいな
421:デフォルトの名無しさん
08/02/23 22:14:15
>>419
それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
削ったのですがこれでも原因が不明です コンパイラはBCC5.5です
#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;
f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }
main(){
strdata str; f(&str);
//char *test=(char *) malloc(1);
printf("%s",*(str.st));}
422:デフォルトの名無しさん
08/02/23 22:17:54
>それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
( ゚д゚) ・・・
(つд⊂)ゴシゴシ
(;゚д゚) ・・・
(つд⊂)ゴシゴシゴシ
_, ._
(;゚ Д゚) …!?
423:デフォルトの名無しさん
08/02/23 22:17:55
419でどこの文字列がどう書き換えられないっていうんだ言ってみろ
424:デフォルトの名無しさん
08/02/23 22:20:55
VCCやGCCやDMCでも実行中にエラーになります
#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;
void f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }
int main(){
strdata str;
char *test;
f(&str);
test=(char *)malloc(1);
printf("%s",*(str.st));
getchar(); return 0;}
425:デフォルトの名無しさん
08/02/23 22:21:34
>>421
>それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります
wwwwwwwwwwwwwwwwwwwwwww
>>419よ、これが現実だwwwwwアホは相手にするなwwwwww
426:デフォルトの名無しさん
08/02/23 22:22:15
ぶっちゃけポインタ全く理解してないだろ。
427:421
08/02/23 22:26:27
誤解していましたすみません
428:デフォルトの名無しさん
08/02/23 22:28:05
さすがに・・・
初心者を抜け出した程度の俺でも酷いと思うw
429:デフォルトの名無しさん
08/02/23 22:28:08
>>424
変数testの用途が不明だったので、削除させてもらった。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *st;
}strdata;
void f(strdata *q) {
char *ch = (char *)malloc(10);
ch[0] = 'X';
ch[1] = 'Y';
ch[2] = 'Z';
ch[3] = '\0'; //まあ0のままでもいいんだけど
q->st = ch;
}
int main() {
strdata str;
f(&str);
printf("%s", str.st);
getchar();
free(str.st);
return 0;
}
430:421
08/02/23 22:28:56
すみません 誤解していませんでした 書き換えられません
#include <string.h>
#include <stdio.h>
typedef struct { char *st; }strdata;
f(strdata *x){
delete x->st;
x->st = new char [9];
strcpy(x->st,"++++++"); }
main(){
char *ch=NULL;
strdata x;
x.st=ch;
f(&x);
printf("%s",ch);}
431:デフォルトの名無しさん
08/02/23 22:34:49
>>430
お前が421や424で書いたコードは
>printf("%s",*(str.st));
だったのになぜ
>printf("%s",ch);
になってるんだ?納得のいく説明を聞こうか?
432:デフォルトの名無しさん
08/02/23 22:34:55
>>429
int main() {
strdata str;
f(&str); ←ここで初期化された文字列の内容、長さを変更したいんです あと変数testほ確保しても落ちないようにしたいんです
printf("%s", str.st);
みなさんは、>>424はまともに動きますか?
433:デフォルトの名無しさん
08/02/23 22:37:26
>>432
動かすまでもなく、まともに動かないのは分かる
434:430
08/02/23 22:37:28
>>335>>343>>348>>351がもともとの質問でこれを実現したいんです
435:デフォルトの名無しさん
08/02/23 22:37:36
>>430
printf("%s",ch);をprintf("%s",x.st);とすればいい。
嫌か?
じゃあこれでどうだ。
#include <string.h>
#include <stdio.h>
typedef struct {
char *st;
} strdata;
void f(strdata *x) {
delete x->st;
x->st = new char[9];
strcpy(x->st,"++++++");
}
int main() {
char *ch = NULL;
strdata x;
x.st = ch;
f(&x);
ch = x.st;
printf("%s",ch);
delete[] ch;
return 0;
}
436:デフォルトの名無しさん
08/02/23 22:39:36
>>433
test=(char *)malloc(1);をはずすと上手くいきます なぜですか
437:デフォルトの名無しさん
08/02/23 22:40:58
>>436
それは上手く動いてるんじゃなくて、たまたま動いてるだけ
438:デフォルトの名無しさん
08/02/23 22:41:46
>>335
をチラ見しかしてないけどそれが動くことがとても不思議。
とりあえず期待する動作はなんなのかを日本語で書いてください。
439:デフォルトの名無しさん
08/02/23 22:42:06
>>435
それだと始めにchが巨大に確保されていたらメモリーリークになると思うのですが
440:デフォルトの名無しさん
08/02/23 22:43:20
>>436
偶然。
あのコードでは、すでになくなったローカル変数を読み取ろうとしている。
運良くメモリ上に残っていれば、一見正しく動いているように見える。
そのtestの行は、残っていた変数の値を破壊する決定打になったのだろう。
441:デフォルトの名無しさん
08/02/23 22:43:21
>>439
思うだけだ
442:デフォルトの名無しさん
08/02/23 22:44:24
見る気もしない。
高速スクロールで華麗にスルー。
違うお題ないの?
443:デフォルトの名無しさん
08/02/23 22:46:11
Perlで言うところの
use LWP::Simple;
sub foo{ return get('URLリンク(hoge.com)'); }
これをVC++で極力シンプルにやるにはどうすればいいでしょうか?
環境は以下のとおりです。
VisualC++.net2003 Standard
managedC++不使用 MFC不使用 ATL/WTL使用 STL/Boost使用
444:デフォルトの名無しさん
08/02/23 22:46:57
>>438
バイナリ文字列 (\0を含む) の初めと終わりを構造体で関数に渡して、バイナリ文字列の内容、長さを書き換えたいんです
445:444
08/02/23 22:48:45
純粋なC言語だけでそれを実現したいんです
446:デフォルトの名無しさん
08/02/23 22:49:59
>>445
…
一般的に知られている C言語の定義とは違うものを扱ってらっしゃるのですね
447:デフォルトの名無しさん
08/02/23 22:50:53
最終的には、C言語のみにしますけど今は実験段階なので・・・
448:デフォルトの名無しさん
08/02/23 22:52:02
>>444
なんでchとかtestとか別の変数が出てくるの?
構造体のまま扱い続ければいいでしょ。
449:443
08/02/23 22:54:26
>>443
単純にC++でネット上のものをダウンロードさせるには
どうすればいいですか?って聞くべきだった orz
450:デフォルトの名無しさん
08/02/23 22:55:14
chは現物の文字列です この初めと終わりのアドレスを構造体で渡して変化させるようにしたいんです
451:デフォルトの名無しさん
08/02/23 22:55:32
本でも読んで出直してこいよ
本格的に他人に頼りたいなら金でも払え
452:デフォルトの名無しさん
08/02/23 22:59:15
現物の文字列ってなんだよ
ただのポインタだろ
str.st と等価だ
453:デフォルトの名無しさん
08/02/23 23:01:55
たとえば、
char *ch=new char [100]; strcpy(ch, "---------");
という文字列に対して、その先頭と後方のアドレスを関数に渡して、関数側で書き換えられるようにしたいんです
454:デフォルトの名無しさん
08/02/23 23:04:50
何にそんなもんをつかうんかわからんが
とりあえずそんなことを考える前に
入門書なりきちんと読め。
たのむから
455:デフォルトの名無しさん
08/02/23 23:09:26
初めの文字列が200M程度確保されていたとして作業領域も200M使うとします
このとき初めの文字列を解放するか、上書きすれば最高でも400Mしかメモリを使いません
しかし、それができずに返却すると最大 200M + 200M + 200M必要になります
456:デフォルトの名無しさん
08/02/23 23:11:03
>>449
ソケット使ってカリカリやるしか思いつかん
457:デフォルトの名無しさん
08/02/23 23:11:12
>>443
手軽さならWinInet
真剣にやるならWinsock
458:デフォルトの名無しさん
08/02/23 23:13:38
>>450
435みたいに、構造体で渡した後、元の変数に代入し直せばいい。
459:デフォルトの名無しさん
08/02/23 23:15:30
もはやポインタいらんがなw
460:デフォルトの名無しさん
08/02/23 23:19:19
文字列ではなく、1byte変数の配列を可変長で扱いたいと。
だったら、
typedef struct {
char *baka;
size_t length;
} aho;
とでもして、構造体をやり取りすればいいだろ。
C++だったら、vector<char>、deque<char>でも使えや。
461:443
08/02/23 23:20:13
WinInetででググったらいっぱい出てきたんで調べてみる。
サンクス
462:デフォルトの名無しさん
08/02/23 23:20:26
>>443
URLDownloadToFile
463:デフォルトの名無しさん
08/02/23 23:26:44
>>458
なぜ直接書き換えられないのかわかりません
464:デフォルトの名無しさん
08/02/23 23:29:10
>>463
こっちからしてみたら、なんで構造体を使いたくないのかわからない。
465:デフォルトの名無しさん
08/02/23 23:29:25
>>463
もっと勉強してから出直せ
466:デフォルトの名無しさん
08/02/23 23:40:17
もともと構造体は使っていますよ あとC言語のみで動かせるようにしたいんです
開始のアドレスと長さを渡しても上と同じだと思います
467:デフォルトの名無しさん
08/02/23 23:41:34
あぼーんしたいからトリップつけてくれ
468:デフォルトの名無しさん
08/02/23 23:44:18
たぶんトリのつけ方を知らない。
「名前欄にレス番つけること」すら今日知ったっぽい
469:デフォルトの名無しさん
08/02/23 23:44:39
釣りだろう
470:デフォルトの名無しさん
08/02/23 23:46:32
文字列を入力して、
表示するとき右から3文字ごとにコンマをつける方法ってどうすれば?
(例:入力>>344fru38fh4tgiur
出力>>3,44f,ru3,8fh,4tg,iur)
この続きお願いします・・
#include <iostream.h>
main()
{
char a[50] ;
cout <<"aに文字を入力してください>>" ;
cin.getline(a, 50) ;
int a_count = 0 ;
while( a[a_count] != '\0'){
a_count++ ;
}
cout <<"aを表示します→" ;
for(int i=0 ; i<a_count ; i++){
cout << a[i] ;
}
}
471:デフォルトの名無しさん
08/02/23 23:48:55
これがたまたまうまく動いたりしますが、実際は間違っているから困っているんです
#include <stdio.h>
#include <string.h>
typedef struct { char *start ; char *end; } bin;
void f(bin *x) {
delete x->start;
x->start = new char [3];
strcpy(x->start,"aa"); }
main() {
char *ch = new char [2];
strcpy(ch,"a");
bin x;
x.start=ch; x.end=ch+strlen(ch);
f(&x);
printf("%s",ch);
}
472:デフォルトの名無しさん
08/02/23 23:50:11
>>470
URLリンク(www.google.co.jp)
473:デフォルトの名無しさん
08/02/23 23:53:13
x.start=ch; とした時点で、数値がコピーされるだけになり、文字列を書き換えられなくなります
だから x.start=&ch;と参照渡しをするために
構造体を { char **start ; char **end; }に変更します
そうすると上記のような現象が出ます
474:デフォルトの名無しさん
08/02/23 23:53:48
>>471
f(&x);
ch=x.start;
printf("%s",ch);
でいいだろ
って・・・釣られちまったよ~~~~ん
475:デフォルトの名無しさん
08/02/23 23:56:53
>>473
fを呼んだあとのchが指す先はfの中でdeleteされていることに気づいているか?
476:475
08/02/23 23:57:42
×>>473
○>>471
477:デフォルトの名無しさん
08/02/24 00:03:07
>>475
>>471ではdeleteやnewが効かない場合があるんです これはちゃんと表示されますか?
#include <stdio.h>
#include <string.h>
typedef struct { char *start ; char *end; } bin;
void f(bin *x) {
delete x->start;
x->start = new char [3];
strcpy(x->start,"aa"); }
main() {
char *ch = NULL;
bin x;
x.start=ch;
f(&x);
printf("%s",ch);}
478:デフォルトの名無しさん
08/02/24 00:06:58
Cで動くようにしたいとかホザいておきながら、new や deleteを使うバカ
しかも、
baka = new aho[shine];
としたら
delete []baka;
とすることしら知らないバカ。
マニュアルでも読め
479:デフォルトの名無しさん
08/02/24 00:07:28
>>477
じゃあもういいから、こうしとけ
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }
void g(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"bb"); }
main() {
char *ch = NULL;
bin x;
x.start=&ch;
f(&x);
printf("%s",ch);
g(&x);
printf("%s",ch);
}
これで終了、もう来るな
480:デフォルトの名無しさん
08/02/24 00:08:23
>>477
deleteもnewも効いているはずだよ?
・chが指す先をdeleteしようが、x->start=new・・・をしようが、chの中身は変わらない。
・deleteしても絶対に書き込めなくなるとは限らない。
これらは理解している?
481:not 477
08/02/24 00:10:08
>>478
あ・・・そういえばdelete []baka;としないといけなかったんだ・・・・
C厨ですまん。
482:デフォルトの名無しさん
08/02/24 00:15:24
構造体はCでないというつもりか?
483:デフォルトの名無しさん
08/02/24 00:17:32
>>477
main関数内、chだけに注目すれば、
chはNULLで初期化された後、一切変更を受けないだろ。
printfにNULLを渡しているので、未定義。
484:デフォルトの名無しさん
08/02/24 00:18:48
>>479
それだと、 bin x;を初期化する関数と、適当な配列を入れるとバグるんです なんでうごかないんですか
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }
void h(bin *x){
char *ch=new char [3];
ch[0]='X';ch[1]=0;
x->start=&ch; }
main() {
bin x;
h(&x);
f(&x);
char *test=new char [1];
printf("%s",*(x.start));
}
485:デフォルトの名無しさん
08/02/24 00:23:27
バグるじゃ分らんだろ。
486:デフォルトの名無しさん
08/02/24 00:24:02
>>484
h内のローカル変数chのアドレスをx->startに格納しているが、
chはhを抜けると無くなるので、x->startは存在しない場所を指している。
487:デフォルトの名無しさん
08/02/24 00:24:26
>>484
じゃあこれでいいだろう
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }
char *ch;
void h(bin *x){
ch=new char [3];
ch[0]='X';ch[1]=0;
x->start=&ch; }
main() {
bin x;
h(&x);
f(&x);
char *test=new char [1];
printf("%s",*(x.start));
}
488:デフォルトの名無しさん
08/02/24 00:25:03
char *test=new char [1];をのぞくと、bcc5.5では動作します
ほかのコンパイラでは、入れなくても実行時に落ちます 原因は何ですか?
489:デフォルトの名無しさん
08/02/24 00:25:46
いいように使われてるぞ、デバッグ隊w
490:デフォルトの名無しさん
08/02/24 00:27:01
>>488
原因はchがローカル変数だからだ
491:デフォルトの名無しさん
08/02/24 00:27:09
>>488
OSが落ちろ!!って指令を下すからじゃないかな?
492:デフォルトの名無しさん
08/02/24 00:27:09
おまいらまだ付き合ってやってんのか
こいつ分かってるけど、分からないフリしてるだけだろ
493:デフォルトの名無しさん
08/02/24 00:28:09
>>492
こっちも暇だからね
494:デフォルトの名無しさん
08/02/24 00:28:54
バカは放置汁。
最初の例から考えると、文字列定数や、文字配列をもdeleteしようとしてるんだから。
495:デフォルトの名無しさん
08/02/24 00:30:19
>>486>>487
しかし、これはどのコンパイラでも正常に動きませんか? C++ですが
#include <stdio.h>
#include <string.h>
void h(char *&x){
char *ch=new char [11];
strcpy(ch,"ABCDEFGHIJ");
x=ch; }
main() {
char *x;
h(x); printf("%s",x); }
496:デフォルトの名無しさん
08/02/24 00:31:31
>>495
それが動くのはchar*&だからだ
497:デフォルトの名無しさん
08/02/24 00:32:23
>>495
うん。それはローカル変数アドレスを取る(ポインタを取る、参照を取る)
ということをやっていないから問題ない。
498:デフォルトの名無しさん
08/02/24 00:33:28
>>495
そのhは、chの「値」をコピーしているので、
chが無くなっても値はxに格納されているから動く。
>>484はchの「アドレス」を格納しているだけ。
499:デフォルトの名無しさん
08/02/24 00:33:34
>>488
プログラミングは諦めたほうがいい
1.簡単な事をややこしくして
2.バグを入れて
3.聞きまくることで他人の邪魔をする
別の仕事探せ
少なくともオレはそれを勉強熱心とはいえない
500:デフォルトの名無しさん
08/02/24 00:41:03
だから、バカは放置だって。
手段に固執して、何の目的でそのイミフな手段をとろうとしているのか自分でわかってない。
501:デフォルトの名無しさん
08/02/24 00:41:58
確認したいのですが、newは、deleteするかプログラムが終了するまで解放されないはずですよね?
タスクマネージャで確認するとf()を抜けてもメモリはそのままです
#include <stdio.h>
f(){
char *x=new char [200*1024*1024]; }
main() {
f();
getchar();
}
502:デフォルトの名無しさん
08/02/24 00:42:13
>>495
ちなみに、それをポインタを使って書き直すとこうなる。
#include <stdio.h>
#include <string.h>
void h(char **x) {
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*x = ch;
}
int main() {
char *x;
h(&x);
printf("%s",x);
return 0;
}
503:デフォルトの名無しさん
08/02/24 00:43:28
だからローカルで定義された変数や配列でも、そのアドレスが判明していれば、main()などで操ったり解放できますよね
504:デフォルトの名無しさん
08/02/24 00:46:04
>>503
マニュアル嫁
ヒープの意味を理解してからnew や delete を使え。
変数の記憶クラスを理解しろ
505:デフォルトの名無しさん
08/02/24 00:47:43
ローカル定義は外に抜けたら、内容が残っている保証はない
allocしたなら残っているけど
506:デフォルトの名無しさん
08/02/24 00:48:18
>>503
だからの前後が繋がってないぞ
newした領域がdeleteされるまで解放されなかったら
なぜローカルで定義された変数や配列をmainから操れることになるんだ
507:デフォルトの名無しさん
08/02/24 00:49:11
なぜですか? 間違っていないと思いますよ これはmain()側で解放してます
#include <stdio.h>
#include <string.h>
void h(char **x) {
char *ch = new char[200*1024*1024];
*x = ch; }
main() {
char *x;
h(&x);
getchar();
delete x;
getchar();}
508:デフォルトの名無しさん
08/02/24 00:52:46
>>507
それはhのローカルで定義された変数chをmainから操ってるわけではないな
単にnewした領域へのポインタchをmainのxにコピーして渡してるだけだ
509:デフォルトの名無しさん
08/02/24 00:54:23
一度目のキー入力で、200M分メモリを解放しますよ タスクマネージャみてください
510:デフォルトの名無しさん
08/02/24 00:54:39
伸びがいいから何かと思ったら未だ相手にしてたのか。
511:デフォルトの名無しさん
08/02/24 00:55:37
>>507
newで確保したメモリへのポインタをmainに連れて行っているだけ。
newやmallocで確保したメモリはソース上のスコープに縛られずに使える。
一方、>>484では、x->start=&ch;というように、
ローカル変数へのポインタをmainへ持って行っている。
しかし、mainに戻ったときには既に変数chそのものが居なくなっているのでうまくいかない。
512:デフォルトの名無しさん
08/02/24 00:56:05
見事な無自覚の自己中心主義だな、早く治せよ
>>507
なにしてるかわかってるならいいけど、ポインタ一回お浚いしたら?
513:デフォルトの名無しさん
08/02/24 00:56:26
>>507
あんたはnewで確保した領域と、それを指すポインタ変数を、同一のものであると勘違いしてないか?
>>507のコードでも、ポインタ変数chはhを抜ける時に消滅するのは分かるか?
514:デフォルトの名無しさん
08/02/24 01:00:53
まずchar *x の xは、int xや float xと同じで、ただのローカル変数であることを覚えとけ
515:デフォルトの名無しさん
08/02/24 01:04:18
しかしこれは動きません
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void h(bin *x){
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*(x->start)=ch; }
main() {
bin x;
h(&x);
printf("%s",*(x.start));
}
516:デフォルトの名無しさん
08/02/24 01:04:59
>
517:デフォルトの名無しさん
08/02/24 01:05:04
free(p)ってやるとpがNULLになるとか思っちゃう人なのかな。
518:デフォルトの名無しさん
08/02/24 01:05:45
お前らバカの相手すんなって。つけあがるから。
519:デフォルトの名無しさん
08/02/24 01:06:51
>>515
x->startをまったく初期化しないまま、*(x->start)なんかに代入しているのが間違い。
>>513に答えろ
520:デフォルトの名無しさん
08/02/24 01:08:18
俺結構ポインタの理解があやふやで、だからなるべくポインタのややこしい部分には触れないプログラム今までしてきたんだけど、
このスレ読んだらなんとなく理解できてきた気がする。
C言語でnewとdeleteを使い続けてる人ありがとう!
あと、もちろん解説してくれてるみんなもありがとう!
明日からもstringばりばり使っていこうと思います。
521:デフォルトの名無しさん
08/02/24 01:09:24
>>515
そうだね、それは動かないね
だから?
何を聞きたいのか明確に
522:デフォルトの名無しさん
08/02/24 01:09:53
ポインタ変数が消滅するのはわかります
関数での、初期化と書き換えをする方法がわかりたいです
523:デフォルトの名無しさん
08/02/24 01:10:25
>>515
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;
void h(bin *x) {
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*(x->start)=ch; }
int main() {
bin x;
char *p;
x.start = &p;
h(&x);
printf("%s", p);
delete[] p;
}
524:デフォルトの名無しさん
08/02/24 01:10:30
new/deleteを使うということは当然C++だよな?
じゃあ、なんでメモリ操作を隠蔽するクラスを作ろうとしないの?
IQ低いから?
525:デフォルトの名無しさん
08/02/24 01:10:53
>>522
みんなが何回も例を出しているのに・・・(T_T)
526:デフォルトの名無しさん
08/02/24 01:12:15
>>524
上のほうで最終的にCで書くと言っていたはず。
俺にはなんで今はnew[]使ってC++にするのか理解できないけど。
527:デフォルトの名無しさん
08/02/24 01:12:50
>>522
おまいがポインタについて知っている知識をすべて述べよ
528:デフォルトの名無しさん
08/02/24 01:12:53
>>522
何度か出てる正しく動く例が気に入らない理由はなぜかね
529:デフォルトの名無しさん
08/02/24 01:18:03
仮に、彼へC言語ポインタ完全制覇を与えたとしても、
それでわかってくれるかどうか不安になる。
530:デフォルトの名無しさん
08/02/24 01:19:41
>>522
皆が何言ってるかほとんど分からないC++素人だけど
一日ぐらい気分変えて犬の散歩にでも行ったら?
まあ、犬のウンコの処理しながら考えたりさ
その後で、また一から作ってみる
以外とできるかもよ
531:デフォルトの名無しさん
08/02/24 01:21:40
>>523
それだとうごきました サンクス
x.start = &p;
h(&x);
printf("%s", *x.start);
初めにメモリ上にchar*型が確保されないと受け取れないって事か
532:デフォルトの名無しさん
08/02/24 01:23:55
>>530
犬のウンコの処理を考えたり に見えて
delete unko;とか脳内で実行しそうになった
533:デフォルトの名無しさん
08/02/24 01:28:09
>>523
pを確保しなくても、これでもいいはずですよね
int main() {
bin x;
x.start = new char *;
h(&x);
printf("%s", *x.start);
}
534:デフォルトの名無しさん
08/02/24 01:28:52
newしたらdeleteしとけよ
535:デフォルトの名無しさん
08/02/24 01:35:57
>>533
newしたものはdeleteしないといけないのが面倒だから、
使わずに済むなら避けるべき。
536:デフォルトの名無しさん
08/02/24 01:48:50
だから、newを捨てるところからはじめろって。
537:デフォルトの名無しさん
08/02/24 01:53:19
C及びC++を使いゲームを作成された方へ質問です。
再帰関数って便利ですか?
もしよろしければ、メリットとデメリットを教えていただけないでしょうか?
自分の考えでは、 goto と同じ用に無理に使う必要はない機能だと思ってます。
538:デフォルトの名無しさん
08/02/24 01:54:37
再帰関数については色々思うところがあるのだが、ゲームを作っているわけではないからなぁ。
539:デフォルトの名無しさん
08/02/24 01:58:18
無理に使う必要は無いなぁ
メリットデメリットという問題でもない気がする
540:デフォルトの名無しさん
08/02/24 01:58:23
>>537
ポリゴン(ボーン)の操作で便利
でも、無理して使わなくてもおk
541:デフォルトの名無しさん
08/02/24 02:03:16
ボーン操作ってことは、データの読み込み時に便利ってことでしょうか?
542:デフォルトの名無しさん
08/02/24 02:09:18
【環境】 MS WinXP/gcc 3.4.4 on cygwin
【ソース】 URLリンク(kansai2channeler.hp.infoseek.co.jp)
【用途】 IRCクライアント(bot)
【起動方法】 $ ./a irc.tokyo.wide.ad.jp 6664
【動作の現状】
1.コマンドラインからサーバ名とポートを受け取り、ソケット作成、コネクション確立
2.サーバからのコネクションメッセージ受け取り
3.USER/NICKコマンドの送信
4.ウェルカムメッセージ、MOTDの受け取り
5.半角英数のチャンネル名へのJOIN ←ここで停止する
【質問】
・Telnetで同じように接続すると問題なく接続→終了することができる(ISO-2022-JPだから文字化けするが正常)
・送受信周りがかなりいい加減なのでJOIN出来ないのはそこに問題があるのではないか?
イレギュラーなことをやってますが、IRC板orスレというよりCネットワークプログラミング自体の問題かと考え
こちらに質問させていただきました。よろしくお願いいたします。
543:デフォルトの名無しさん
08/02/24 02:13:01
>>541
typedef struct _D3DXFRAME {
LPSTR Name;
D3DXMATRIX TransformationMatrix;
LPD3DXMESHCONTAINER pMeshContainer;
struct _D3DXFRAME *pFrameSibling;
struct _D3DXFRAME *pFrameFirstChild;
} D3DXFRAME, *LPD3DXFRAME;
座標系の上に座標系があって、
さらにその座標系の上に座標系が…
と繰り返すので、スタックを自前で管理するより
再帰処理にしたほうが楽というだけ
(体-上腕-腕-手-指 のように繋がっていくので)
544:デフォルトの名無しさん
08/02/24 02:17:35
>>542
カンなので外してたら無視してくれ
>for(i=0;i<=strlen(p);i++){
\0も送信してるが、いいのか?
i<strlen(p) なんじゃない?
545:デフォルトの名無しさん
08/02/24 02:37:36
>>543
for分で体のパーツ数回してデータを読み取ってるんですが、
今は無理してそれを崩してまで使う機能ではないってことですね。
よく機能を理解して使えば楽になる物、ということですね。
答えてくれた方ありがとうございました。
546:デフォルトの名無しさん
08/02/24 03:26:15
>>542
メッセージの終わりを\n → \r\n に変えてみたらいけるかも
547:デフォルトの名無しさん
08/02/24 03:33:50
>>530
俺はオナニーして発射した後、ティッシュで拭いてる時にコードが閃くよ。
548:546
08/02/24 03:56:01
あと、>>544と同じく\0の送信は不味いんでは?
\nでメッセージの終わりを判断してるとすると、サーバは次のメッセージの受信で
先頭に\0が入ってしまうんではないかと思う
(2回目のメッセージが、"\0JOIN #ircclidev\n"になるんじゃないかな)
549:デフォルトの名無しさん
08/02/24 04:06:10
>>544,>>548
i<strlen(p)で解決しました。初歩的ミスもいいところだ・・・。
もう一つ質問があるのですが、(どちらかというとこちらが本題ですが)
ISO-2022-JP(いわゆるJISコード)とShiftJISを相互変換するライブラリorサンプルを探しています。
検索してもなかなかしっくり来るものがなく、nkf経由だと上手くISO-2022-JPの制御コード
(KI/KO=0x1B 0x24 0x42/0x1B 0x28 0x42)を取ることが出来ません。
RFCには、特にマルチバイト環境の規定は定められていませんが、日本語IRCサーバは
ISO-2022-JPを使っているところが主流のようです。
550:デフォルトの名無しさん
08/02/24 04:12:53
>>542の修正版ソースです。一応日本語以外はちゃんと動く・・・はず
URLリンク(kansai2channeler.hp.infoseek.co.jp)
551:デフォルトの名無しさん
08/02/24 05:11:02
>>549
iconvじゃだめかい?
552:デフォルトの名無しさん
08/02/24 05:52:14
すんません。
VC++6.0からVisualStudio2008に移ったんですが、外観が変わりすぎててチンプンカンプン・・・
どこかVisualStudio2008 Exp の解説やってるページとかありませんか?
dllすら読み込めぬ・・・。orz
553:デフォルトの名無しさん
08/02/24 06:11:51
Visual Studio2008スレにGO
554:デフォルトの名無しさん
08/02/24 10:24:08
自分でクラスを定義するときに、ポインタに対する演算は、定義しなくてもよいのでしょうか?
つまり、ポインタでも、int*とか、char*とかの型がありますが、例えば
myclass*==int*
とかやるとコンパイルエラーになります。でも、myclass1*==myclass2*は、==演算子も
定義してないのに、コンパイルできるし、ちゃんと動きます。
これは、どういう理由でできるんですか?というか、ポインタの比較をする演算子って
どこで定義してるんでしょうか?
変な質問ですいません。
555:デフォルトの名無しさん
08/02/24 10:27:06
継承関係があるんじゃない?
556:デフォルトの名無しさん
08/02/24 10:54:10
>554
規格上で「できる」と決められている処理ははコンパイラが勝手に処理してくれる、というだけ。
myclass1*==myclass2* は >555 の言うとおり myclass1 と myclass2 に継承関係があるんだろう。
この場合、暗黙の型変換が発生して同じ型になり比較できる、と決まっている。
で、規格で決められている以上のポインタに対する演算を、自前で定義する必要があるケースはまずない。
557:デフォルトの名無しさん
08/02/24 10:55:39
>>554
違う型のポインタの比較はダメ
int* a;
double* b;
a == b
をやってみれば意味がわかるんじゃないかな?
558:デフォルトの名無しさん
08/02/24 12:50:04
C++で配列を関数の引数にできますか?
559:デフォルトの名無しさん
08/02/24 12:52:24
配列の参照か、配列のポインタか、配列要素のポインタならできます
配列自体は無理
560:デフォルトの名無しさん
08/02/24 12:52:27
ポインタじゃダメなのか?
561:デフォルトの名無しさん
08/02/24 12:53:21
>>558
できる
template <size_t n>
void func((&a)[n]) のように
562:デフォルトの名無しさん
08/02/24 12:53:39
型がねえ
563:デフォルトの名無しさん
08/02/24 12:58:42
すまん忘れた
564:デフォルトの名無しさん
08/02/24 13:14:21
>>559-563
ありがとうございます。
たしかにできませんでした。でも、
template <class T, int N>
int func(T a[N])
{
...
}
こういう様に書いても(func()の引数に&を付けても付けなくても)、aは参照扱いになるようです。
aに対して変更を加えると、func()の呼び出し側の元配列にも変更が反映されました。
565:デフォルトの名無しさん
08/02/24 13:20:12
そりゃaはポインタなんだから。
566:デフォルトの名無しさん
08/02/24 13:32:04
>>564
aは参照でなくてdecayされるからポインタだろ
567:デフォルトの名無しさん
08/02/24 13:36:59
>>565-566
そうか。ポインタですよね。
ポインタをコピーして、その先まで複製してくれるのはありえないですよね。
ありがとうございました。
568:デフォルトの名無しさん
08/02/24 13:50:24
構造体かクラスでラップしとけばいい。
boost::array を使うとか。
569:デフォルトの名無しさん
08/02/24 16:28:53
C++で乱数を扱う為のクラスとか関数はありますか?
rand/srand使うしかないですか?
rand/srand使うとしたら、シードによく現在時刻使いますが
現在時刻を取得する方法はtimeしかないですか?
++らしい方法があれば教えてください。
570:デフォルトの名無しさん
08/02/24 16:30:06
MT法のインラインアセンブラ版がどっかにころがってたきがする
571:デフォルトの名無しさん
08/02/24 16:31:57
boost使うか
URLリンク(www.math.sci.hiroshima-u.ac.jp)
ここから持っていけばいいんじゃね
572:デフォルトの名無しさん
08/02/24 16:32:08
>>569
Boost.Random
573:デフォルトの名無しさん
08/02/24 17:06:58
javascriptではalert("文字列"+123)
という風に文字列と数字を一緒にメッセージ表示出来ましたが、
C++で文字列と数字を一緒にメッセージ表示させるにはどうしたらいいでしょうか?
MessageBox(NULL, "文字列"+123, "test", NULL)
というのは出来ませんでした。
574:デフォルトの名無しさん
08/02/24 17:09:11
>>573
JavaScript同様、文字列を連結してから表示すればいい。
575:デフォルトの名無しさん
08/02/24 17:19:27
>>574
char msg[20] = "文字列";
char tmp[10];
itoa(123, tmp, 10);
strcat(msg, tmp);
MessageBox(NULL, msg, "test", NULL);
こんな感じですか?
メッセージ毎にこのコードを書くのも面倒臭いのと、
いつも "文字列"+数字 の組み合わせと言うわけでもなく
数字+"文字列"+数字+"文字列" という事もあるため
自作関数でmsgbox(char*, int){}という決め撃ちではやく、
文字列や数字を混同で表示できる方法はないかと考えています。
576:デフォルトの名無しさん
08/02/24 17:20:07
お願いします。C言語初心者なんですが、
ソース内に日本語を入れるとエラーになるんですが、
どこをどうすればいいのでしょうか?
超初心者です。よろしくお願いします。
577:デフォルトの名無しさん
08/02/24 17:21:41
× ああああ
○ //ああああ
578:デフォルトの名無しさん
08/02/24 17:22:14
ソースから日本語を消す
579:576
08/02/24 17:27:51
説明へたですいません。
/* hello02.c */
#include <stdio.h>
int main()
{
printf("今日はよい天気です。\n");
printf("明日もよい天気でしょう。 \n");
return 0;
}
これなんですけど…
580:デフォルトの名無しさん
08/02/24 17:30:51
>>576
どんなエラー?
581:デフォルトの名無しさん
08/02/24 17:34:42
>>570-572
ありがとうございます、Boost 試してみます。
手元の mingw にはなさそうなので、まずはgooって
Boost 環境揃えてみますね。
>>576
・ソースの文字コードを変えてみる
・処理系を変えてみる
582:576
08/02/24 17:36:23
本当にすいません。
普通に表示されました。
なんか間違ったやりかたしてたみたいです…
申し訳ないです。
583:デフォルトの名無しさん
08/02/24 17:41:12
>575
そのためのsprintf、とだけいっておくけど。
584:デフォルトの名無しさん
08/02/24 17:48:41
>>583
sprintfだとメッセージウィンドウは生成されないですよね?
外見としてはMessageBoxの中身に数字や文字列を表示している様な方法がいいんです。
585:デフォルトの名無しさん
08/02/24 17:54:21
sprintfのsは何の意味か知っているか、とだけ言っておくけど。
586:デフォルトの名無しさん
08/02/24 17:55:05
>>584
ならsprintfしてMessageboxにいれる処理の関数つくればよくね?
587:デフォルトの名無しさん
08/02/24 17:56:41
要はフォーマット→MessageBox()と
二段構えになるのが嫌、というだけの話とエスパー
vsprintf()使って自作ラッパー関数でも書くんだな
588:デフォルトの名無しさん
08/02/24 17:58:37
>>584
boost::lexical_cast
を使うと幸せになれると思う
589:デフォルトの名無しさん
08/02/24 18:04:51
>>585-588
失礼しました。printfと勘違いしてました。
sprintfだと文字列に格納できるんですね。
boostは自分にはまだ早そうなので(正規表現使えるのは魅力的ですが)、sprintfでやってみます。
ありがとうございました。
590:デフォルトの名無しさん
08/02/24 18:05:19
>>588
効率が悪いのが難点
591:デフォルトの名無しさん
08/02/24 18:07:23
>>588
俺も最初それ思いついたけど、連結する数値がたくさんあると見苦しくなるから
std::stringstreamに流し込んで取り出す方がいいんじゃないかなあ。
592:デフォルトの名無しさん
08/02/24 18:45:34
DLLの読み込みで、コンパイラによって失敗します
序数で指定しても動きません どのような理由でしょうか?
VC++だと動かないですが、BCCとDMCで動きます
593:デフォルトの名無しさん
08/02/24 18:47:43
HINSTANCE hd=LoadLibrary("*****.dll");
FN = (fnc) GetProcAddress(hd, (LPCSTR)4); //序数での指定
このような記述はWindowsXPなら万能ではないんでしょうか?
594:デフォルトの名無しさん
08/02/24 18:50:46
訂正
読み込みはしますが、実行時にエラーになります 序数がずれるのかも・・と思い全ての番号で試したのですがだめです
595:デフォルトの名無しさん
08/02/24 18:52:47
継承について教えてください
CFooから派生したCFooEx0、CFooEx1、CFooEx2、CFooEx3があるとします。
そして、それぞれCJissou0、CJissou1、CJissou2、CJissou3に派生してるとします。
その上、CJissou0、CJissou1はIHoge0を、CJissou2、CJissou3はIHoge1を実装しているとします。
図にするとこんな感じ。
CFoo─CFooEx0┬CJissou0
IHoge0┘
CFoo─CFooEx1┬CJissou1
IHoge0┘
CFoo─CFooEx2┬CJissou2
IHoge1┘
CFoo─CFooEx3┬CJissou3
IHoge1┘
CFooとCFooEx~は弄らないとして、IHoge~のインターフェイス関数をCJissou~に実装します。
で、マネージャー的な物例えば、std::vector<CFoo *> vecにそれぞれの実態を入れて、
CJissou~の関数を呼びたいのですが呼ぶ際には、
dyanamic_cast<CJissou0 *>(vec[0])->Test();見たいな事をしないといけないと思います。
でもそういう呼び出しだとIHoge~も意味が無くなってしまうし、数が多くなると厳しくなります。(IHoge~は数個)
だから、dyanamic_cast<IHoge0 *>(vec[0])->Test();//エラー
見たいな呼び方をしたいのですがどうすればいいのでしょうか?
596:デフォルトの名無しさん
08/02/24 18:59:37
>>595
そもそもそのような継承にしてる理由は?
597:デフォルトの名無しさん
08/02/24 18:59:59
>>595
CFoo のメンバ関数ならキャストは要らないはず。
IHoge~ に意味が無くなると言うが、こっちからしたら CFoo や vec の使い方も
ひっくるめて最初からその継承関係の意味がわからん。
598:595
08/02/24 19:06:57
えっと、まあ、CFooがMFCのCViewで、CFooEx~がCTreeViewとかCListViewなのでどうした物かと質問しました・・・。
599:デフォルトの名無しさん
08/02/24 19:10:28
なんでvector<IFoo>とかにしないわけ?
あるいは、virtual Test()をもつ何かインターフェースに。
600:デフォルトの名無しさん
08/02/24 19:18:44
CFooEx の状態で持てないのなら
ダウンキャストすることになるだろうな。
601:デフォルトの名無しさん
08/02/24 20:05:03
>>590
もう自前でパースしてるよ
602:592
08/02/24 20:05:24
最適化オプション関係でした
603:デフォルトの名無しさん
08/02/24 20:10:05
>>601
車輪の再発明
604:デフォルトの名無しさん
08/02/24 20:25:22
boostが?
605:デフォルトの名無しさん
08/02/24 20:29:54
ごめん勘違い
606:デフォルトの名無しさん
08/02/24 20:58:50
文字コード?jisコード?って覚えるべきもの?
607:デフォルトの名無しさん
08/02/24 21:06:12
必要になったときに表を見れば十分
608:デフォルトの名無しさん
08/02/24 21:06:13
>>606
全てのJIS漢字のJISコードなんて、そうそう覚えられるもんじゃないと思うが。
609:デフォルトの名無しさん
08/02/24 21:14:12
class Piyo{
~
};
class Hoge{
public:
void hoge(Piyo[][256]);
};
void Hoge::hoge(Piyo[][256] piyo){
~
}
こんな実装をした時に、Hoge::hogeのpiyoを書いておくと'Piyoは未定義のシンボル'と怒られてしまいます。
仮引数をPiyo[][256]だけにすればコンパイルは通りますが、どう使えというのか・・・といった感じです。
コンパイラはBCC5.5を使っています。クラスの2次元配列をできれば「参照」で渡したいのですが、
どうすればいいんでしょうか?
610:デフォルトの名無しさん
08/02/24 21:15:36
単に書き方がおかしいだけだ。
void Hoge::hoge(Piyo piyo[][256]) {
しかもこれいわゆる参照渡しの挙動をするが、
正確にはポインタ渡しだし。
611:609
08/02/24 21:29:18
うわ・・・。確かにおかしな書き方してた・・・。
自分でもドン引きです・・・。ありがとうございました
612:デフォルトの名無しさん
08/02/24 23:16:37
URLリンク(streaming.linux-magazin.de)
cmakeについてのリアルタイム講演が聞けるそうな
613:デフォルトの名無しさん
08/02/24 23:20:24
ReadFile(fp , &(buf[N]) , 1500 , &sz , NULL);
でエラーで止まります bufは十分にとってあります なぜでしょうか
614:デフォルトの名無しさん
08/02/24 23:24:57
>>613
bufの宣言がどうなっているかにも拠るが、&(buf[N])をbufにしてみろ。
それで巧くいくなら、お前は馬鹿だ。
615:デフォルトの名無しさん
08/02/24 23:31:32
位置を変えてループして読もうとしてるんです bufにすると上手くいきますが前のデータが消えます
原因不明ですが、変数の位置変えたらエラーでなくなり一応うごくようになりました
616:デフォルトの名無しさん
08/02/24 23:34:06
たまたま動いてるだけくさいな。
単純にバッファオーバーフローしてるだけじゃないのか?
617:デフォルトの名無しさん
08/02/24 23:36:56
メモリ関係のエラーみたいです また止まりました
別のところから変更しないと直りそうにありません
設計やり直してきます
618:デフォルトの名無しさん
08/02/24 23:48:58
coutやnewの多重定義ってどうやるのかわかりません できますか
619:デフォルトの名無しさん
08/02/24 23:51:19
>>613
char buf[NMAX*1500]
なら、&(buf[N*1500])
char buf[NMAX][1500];
なら、&(buf[N][0])
char *buf[NMAX]
for(...) buf[N] = malloc(sizeof(char) * 1500);
なら、buf[N]
620:デフォルトの名無しさん
08/02/24 23:52:38
cout の多重定義??
621:デフォルトの名無しさん
08/02/24 23:55:54
<<のオーバーロードに違いない
622:デフォルトの名無しさん
08/02/24 23:56:41
ostream& operator<<(ostream& ostr, const Hoge& hoge) {
ostr << hoge.str();
}
みたいなやつか。
623:デフォルトの名無しさん
08/02/25 00:07:21
stringは連続していますか? memcpyとかはできますか?
624:デフォルトの名無しさん
08/02/25 00:08:24
なんでstringにmemcpyしたがる人が多いんだろう。
625:デフォルトの名無しさん
08/02/25 00:09:43
stringにmemcpyはまずいんじゃね
626:デフォルトの名無しさん
08/02/25 00:10:45
string s="9999999999";
strcpy( &s[5], "000");
は正しいですか
627:デフォルトの名無しさん
08/02/25 00:14:03
詳しいことわすれたけど、s[i]で文字を取得できるならできるんじゃね?
やった後、stringオブジェクトは壊れるとおもうけど
628:デフォルトの名無しさん
08/02/25 00:15:06
この日本語不自由そうなとこが同一人物くさい
629:デフォルトの名無しさん
08/02/25 00:15:58
>>623
規格ではそんな保障はされていません。
630:デフォルトの名無しさん
08/02/25 00:17:13
>>627
あっ嘘、s[i]で取得できてもできないと思う
置き換えたいなら、replaceを使いなさい
631:デフォルトの名無しさん
08/02/25 00:17:23
>626
std::stringのことなら、正しくない。
632:デフォルトの名無しさん
08/02/25 00:21:59
これが動くのですが、stringはchar*の拡張であることは保証されていませんか?だめな例はありますか
int main(){
string str="9999999999";
char *pointer=&str[5];
memcpy( pointer, "000", 3);
str+=(string)"add";
cout<<str;
return 0;}
633:デフォルトの名無しさん
08/02/25 00:25:35
stringの制御情報はどこへ格納されていますか?
ユーザーは合法的でない方法を使ってもアクセスできませんか?
634:デフォルトの名無しさん
08/02/25 00:28:12
>632
必要のないポインタ操作はやめましょう。
動くか動かないかがプログラムの正しさの判定基準ではありません。
635:デフォルトの名無しさん
08/02/25 00:28:47
>>632
あるコンパイラのあるバージョンで動くとしても、規格で保証されていなければ、
他のコンパイラや同じコンパイラの別バージョンでは動かないかもしれない。
それでもいいなら、どうぞ?
今後ずっと同じコンパイラを使い続けて、決して変えないのなら、たぶん問題ないだろう
636:デフォルトの名無しさん
08/02/25 00:30:23
>>633
なんのためのクラスだと思う?
637:デフォルトの名無しさん
08/02/25 01:00:06
例外の使い方について
エラーの通知にはエラーメッセージより例外を使う方がいいと聞いたのですが
オリジナルな例外クラスを投げたり、charを投げまくる仕様にしていいのですか?
例外というと、これ以上の実行に支障が出るときに使うようなイメージがあるのですが実際の現場ではどうなのでしょうか?
638:デフォルトの名無しさん
08/02/25 01:01:51
例外処理を主要処理に書くと遅くなったりしませんか?
639:デフォルトの名無しさん
08/02/25 01:14:59
コンパイラによって例外処理用のコードが追加されるから
パフォーマンスは落ちる。禁止オプションもあるくらいだからな。
特に組み込みでは。。。。。。
640:デフォルトの名無しさん
08/02/25 01:17:11
クラスメンバー変数は、自動で0やNULLで初期化されますか?
641:デフォルトの名無しさん
08/02/25 01:20:04
>>637
好きなように使え。
ただ、エラーメッセージと例外では通知する相手が違うぞ。
エラーメッセージはエンドユーザ、例外はプログラマに通知するもんだ。
ユーザがいきなり「0x00d2345でlogic_error例外が発生しました」とか見せられても訳わからんだろ。
charも投げられるが、標準との整合を考えて投げるのはオリジナルも含めてstd::exception派生のクラスにしとけ。
642:デフォルトの名無しさん
08/02/25 01:21:41
>>640
static領域に配置したオブジェクトのメンバなら、コンストラクタで何もしていなければ0になります。
それ以外は不定です。
643:デフォルトの名無しさん
08/02/25 01:29:37
static つけたらクラスが消滅しても値が残るんですか?
クラスが消滅したらアクセスできなくなると思いますが
つけなくても自動でstaticになりますか
644:デフォルトの名無しさん
08/02/25 01:50:30
>>641
なるほど・・・
戻り値でエラーを知らせたり、NULLを返したりという方法もあるのでどういう方法が主流なのかなと思ってまして
自分はたいていの場合
何が起こったのか確認して、何事もなかったかのように受け流してさいごにエラーログを確認する
位のデバッグライト的な使いか確かしてないのですが・・・
645:デフォルトの名無しさん
08/02/25 01:59:21
>>644
どれが主流というのは無い。場面によって適切な方法があるだけ。
ライブラリとか、設計思想によりエラーの返し方がある程度統一されてたりすることもあるけどね。
とにかく作ってみなさい。できたものを自分なりに分析して、ここはこうした方がよかったとか、省みることで成長するんだから。
646:デフォルトの名無しさん
08/02/25 02:09:23
>>643
残ります、というかクラスを複数生成しても全部同じstaticメンバ変数をさすんですよ?
三行目がいまいちなに言ってるのかわからんstaticつけないとstaticにはならないよ
647:デフォルトの名無しさん
08/02/25 02:12:48
まずインスタンスという言葉を覚えようや
648:デフォルトの名無しさん
08/02/25 02:13:09
>>643
>static つけたらクラスが消滅しても値が残るんですか?
(クラスではなくインスタンスのことを言いたいのだと思うが…)
staticで宣言した変数は、main関数の開始前から終了後まで存在する。
破棄されるのがmain関数終了後だから通常はそれへのアクセスが問題になることはないが、
staticの変数が異なるファイルで定義されて、一方のデストラクタからもう一方を参照するような
処理があるとまずい。
意味が分からないようなら気にしなくていい。
>つけなくても自動でstaticになりますか
ならない。
649:648
08/02/25 02:14:21
ちょっと訂正
×staticの変数が
○2つのstaticの変数が
650:デフォルトの名無しさん
08/02/25 02:24:32
質問があるのですが、
include " "
include < >
" ", < > の違いを教えて頂けませんか?
651:デフォルトの名無しさん
08/02/25 02:30:32
>>650
コンパイラのマニュアルか入門書を読みなさい。
652:デフォルトの名無しさん
08/02/25 02:47:52
>>650
URLリンク(www.google.co.jp)
上から順に読んでいけばそのうち解説してるサイトにたどり着く
653:デフォルトの名無しさん
08/02/25 07:25:36
>>632
std::string の内部バッファの連続性は次の規格で保証されるようになる。
おそらく現状全ての実装でそうなっていることが、その規格変更を実現したんだろう。
だから一応そう言うことをしても問題は無いはずだが、
メンバ関数でできることはメンバ関数でやった方がいい。
replace 使うといい。
654:デフォルトの名無しさん
08/02/25 09:45:12
例外ねぇ、何も考えずにint型のエラーコードを投げちゃうなぁ
返り値でエラーコード返しちゃうと返り値の型が拘束されちゃうしメンドクサ
結局こういう使い方だと例外のありがたみを半分も得ていない気がする
655:デフォルトの名無しさん
08/02/25 10:00:21
例外はstd::exceptionみたいな基本クラスを決めとかないと
ありがたみが半減する。
656:デフォルトの名無しさん
08/02/25 11:44:36
ガベージコレクションは、標準のC++でつくれますか?ライブラリでは動作するのか不安です
自作したいです
あと、整数変数は、初期化なしでアクセスしてもエラーは出ませんか?
657:デフォルトの名無しさん
08/02/25 11:46:47
素人が自作した方が不安だと思うんだが
658:デフォルトの名無しさん
08/02/25 12:00:29
これ動かすとクラス変数は値がほぼ一定ですが理由はなぜですか?
#include <iostream>
using namespace std;
class cl{public: int i; cl(){cout<<"class "<<i;} };
int main(){
int n, a[100];
for(n=0; n<100; n++){
cl *x=new cl;
cout<<" arrey "<<a[n]<<"\n";
}
getchar();
}
659:デフォルトの名無しさん
08/02/25 12:09:11
動的確保による違いでした たぶんヒープ領域は値があまり変化しないことが原因かも・・・
#include <iostream>
using namespace std;
class cl{public: int i; };
int main(){
int n, a[100] ;
cl x[100];
for(n=0; n<10; n++){
cout<<"class="<<x[n].i<<" arrey="<<a[n]<<endl;
}
getchar();
}
660:デフォルトの名無しさん
08/02/25 12:12:41
>>656
整数変数を初期化しなくてもエラーは出ませんが、ローカルな場合に不定値なので初期化しましょう。
661:デフォルトの名無しさん
08/02/25 12:37:27
定数文字列は値渡しにして、動的な文字列は参照渡しにしたいのですが、これだとメモリリークしますよね
どうやれば直りますか?
#include <iostream>
using namespace std;
class cl{
char *str;
public:
cl(char* const& x){ str=x; }
template <size_t n> cl(char (&x)[n]) {
str=new char[n]; strcpy(str,x);}
};
main(){
cl str="rrrr";
str="oooo";
getchar();
}
662:デフォルトの名無しさん
08/02/25 12:42:21
値渡しされているかフラグを作って、されていれば解放する様にすればいいのですが、
初期化前にコンストラクタで代入されてしまうとフラグが確認できません
663:デフォルトの名無しさん
08/02/25 12:47:11
>>661は間違えました 定数式が期待する方へ行っていませんでした それもどうやれば直りますか
664:デフォルトの名無しさん
08/02/25 12:56:55
>>661
やりたいことがよくわからん。せめて、コンパイルできるソース(の断片)を貼ってくれ。
665:デフォルトの名無しさん
08/02/25 13:00:43
まとめるとテンプレート関数で、
定数文字列" "と
固定文字列char [n]と
可変文字列char *を
区別して、上の二つならメモリを確保して値渡しにしたいんです
値を書き換えたいため
666:デフォルトの名無しさん
08/02/25 13:01:40
最近ずっとこいつ出没してるな
667:デフォルトの名無しさん
08/02/25 13:02:01
それと、新たにメモリを確保するときに、以前確保したメモリを解放してメモリリークしないようにしたいです
668:デフォルトの名無しさん
08/02/25 13:06:38
>>667
要は、const char *でコンストラクトするときはメモリを確保して、char *でコンストラクトするときは確保しなければ委員でね?
それと、書き換えのときはconst char *でもchar *でも以前の状態に応じて解放しないといけないんでね?