はきだめC/C++下級者の質問箱 2at TECH
はきだめC/C++下級者の質問箱 2 - 暇つぶし2ch200:デフォルトの名無しさん
06/10/15 18:03:24
1.マルチスレッドプログラミング相談室に行く
2.Win32API質問箱に行く
3.最高にド低脳な発言してください in ム板に行く

201:デフォルトの名無しさん
06/10/15 18:24:04
クリティカルセクションだし

202:デフォルトの名無しさん
06/10/15 18:25:50
セマフォでも使えば?

203:デフォルトの名無しさん
06/10/15 22:09:46
>>200
スレッドご紹介ありがとうございます。
前に専門スレいったことあるのですが、初心者スレ行けって
いわれたこがあったりしたので難しいです。(汗
移動しようと思いましたが回答いただけたので、
今回はすみませんがよろしくお願いします。

204:デフォルトの名無しさん
06/10/15 22:10:38
>>201,202
クリティカルセッションじゃダメですか。
セマフォじゃないのですが考えてみました。
グローバル変数flagを使います。
flagが1の時、スレッドAは実行、他B,Cは待機(Sleep)
flagが0の時、スレッドB,Cは実行、Aは実行しない(待機もしない)

void thread_A(void){
while(1){
//はじめにflagを立てる
flag=1;
//いろんな処理
//Aの処理が終わるので寝てたB,Cを起こすためflag=0
flag=0;
}
}

void thread_B(void){
while(1){
//はじめにflagをチェックして、値が1ならSleep
while(flag==1){Sleep(1000);}
//いろんな処理
}
}
//thread_Cも同様の内容です

これで実現できそうです。
セマフォについてですが、今回の処理に当てはめて考えるのが難しいのですが、
スレッドA,B,Cそれぞれ、どのような処理が必要かヒントいただけないでしょうか。

205:デフォルトの名無しさん
06/10/15 22:44:59
セマフォが難しいなら、ミューテックスを使えばいいじゃない

206:デフォルトの名無しさん
06/10/15 23:49:50
>>204
Section
↑これなんて発音するか知ってる?

207:デフォルトの名無しさん
06/10/16 00:26:09
セッション

208:デフォルトの名無しさん
06/10/16 00:45:41
セシーチオン

209:デフォルトの名無しさん
06/10/16 03:01:03
あれれ、
クリティカルセッション ×
クリティカルセクション ○
でしたか。はずかしい。

ネットで検索してるときに、脳内で変換して
クリティカルセッションでもひっかかるので、
ごちゃごちゃにしてました。

>>205
お互いに排除する相互排除するサンプルとか見かけるんですが、
今回みたいにAが一方的に他を排除するっていうのが、どうなんでしょうか。
ミューテックスも勉強して考えて見ますが、掃き溜めレベルの僕としては
Sleepを使うのに気づいたのは奇跡でした。

210:デフォルトの名無しさん
06/10/16 06:04:09
>>202
ミューテックス調べてみました。
一度にひとつのスレッドしか動かせないみたいなんですが、
今回の場合Aのときはひとつで動かしたいのですが、B,Cは同時に動くのちょっと
違うでしょうか。

211:デフォルトの名無しさん
06/10/16 11:29:58
違います

212:デフォルトの名無しさん
06/10/16 11:46:21
取ってすぐ戻せ

213:デフォルトの名無しさん
06/10/16 17:03:36
void thread_A(void){
    WaitForSingleObject(hMutex,INFINITE);
    while(1){
        //いろんな処理
    }
    ReleaseMutex(hMutex);
}

void thread_B(void){
    //取ってすぐ戻す
    WaitForSingleObject(hMutex,INFINITE);
    ReleaseMutex(hMutex);
    while(1){
        //いろんな処理
    }
}
//スレッドCも同様

これで大丈夫と思うのですが、きちんと処理できてますでしょうか?
linuxでいうlock,unlockでもできそうな気がしますが、同じようなものでしょうか。

214:デフォルトの名無しさん
06/10/16 17:13:38
OS限定されるけど、
A は EntrerCriticalSection() / LeaveCriticalSection() して
B,C は TryEnterCriticalSection() しちゃダメ?

215:デフォルトの名無しさん
06/10/16 20:17:33
ひどいなそりゃ

216:デフォルトの名無しさん
06/10/16 22:01:39
>>204
ヒント。
最大カウント2のセマフォを作る。
A は2回待ってすることしたら2つ手放す。
B と C は1回待ってすることしたら1つ手放す。

217:デフォルトの名無しさん
06/10/16 23:44:13
>>216
それだとAも待ち状態になっちゃうよ。

218:デフォルトの名無しさん
06/10/16 23:58:59
JavaやってからC++やると
C++ってオブジェクト変数の宣言だけでインスタンス化されるのが気持ち悪い。

219:デフォルトの名無しさん
06/10/17 00:35:31
199 の条件に A が待ち状態になってはならないという制約はない。
というか A が仕事している間 B、C を停止させる必要がある以上それは必須だろ。

220:デフォルトの名無しさん
06/10/17 00:46:14
>>219
君、大丈夫?

221:デフォルトの名無しさん
06/10/17 01:05:55
>>214
ありがとうございます。
なるほどです。EntrerCriticalSectionでも大丈夫な可能性があるんですか。
ただいま、セマフォでいっぱいいっぱいなのであとで必ず調べてみます。

>>216
ヒントありがとうございます。
コードはアドバイスいただいた通り、下のようにしてみました。

void thread_A(void){
    //2回待つ
    WaitForSingleObject;①
    WaitForSingleObject;②
    while(1){
        //いろんな処理
    }
//セマフォ2つ開放
    ReleaseSemaphore;
}

void thread_B(void){
//1回待つ
    WaitForSingleObject;
    while(1){
        //いろんな処理
    }
//セマフォ1つ開放
ReleaseSemaphore;
}
//スレッドCも同様

処理の順番ですが、下記で当たってますでしょうか。(続く)

222:デフォルトの名無しさん
06/10/17 01:07:34
・セマフォは2あるので、①、②を通ってスレッドAが実行->セマフォ2開放されます
・セマフォ2あるので、スレッドB,Cが実行
2順目なんですが、
・スレッドB,Cのどちらかの処理が終わって、ひとつセマフォが開放されて①を通過。
・次に処理が遅れているB,Cのどちらかの処理が終わって、ひとつセマフォが開放されて②を通過。
・スレッドAが実行される。
っていうループになりますでしょうか。

セマフォの基本がまだわかっていないので、スレッドBがReleaseSemaphoreしたと
セマフォが1残っているので、またスレッドBが実行されないかとか変なこと考えてしまいます。
この辺はwaitがキューで入っているとかそういうことなのかと思って調べてみます。

>>220
違う方法もあるんでしょうか。
よかったら、アドバイスよろしくお願いします。

223:デフォルトの名無しさん
06/10/17 01:08:14
処理の順番が「当たってる」とかいう発想が信じらられん。当てずっぽうかよ。

224:デフォルトの名無しさん
06/10/17 01:14:53
>>222
たしかに、動いているの確認すればいいですが、
理解力に自身がないので、これであっているのか心配でして。。。

225:デフォルトの名無しさん
06/10/17 01:38:01
223のようなやつが、初心者にどんどん抜かれていくんだよな。
かわいそう。

226:デフォルトの名無しさん
06/10/17 04:07:42
つーか、そもそも>>204でOK。
1sec(あるいはいくらか)のループが気に入らなければ>>213でOK。

何が気に入らんの?

227:デフォルトの名無しさん
06/10/17 05:34:19
>>226
初心者なので、せっかくヒントもいただいたので、
セマフォも勉強したいと思いまして。
現状ですが悪戦苦闘中でして、下記のコードになりました。

void thread_A(){
    while(1){
        WaitForSingleObject(hSemaphore,INFINITE);
        printf("AのWaitForSingleObject1を通過\n");
        WaitForSingleObject(hSemaphore,INFINITE);
        printf("AのWaitForSingleObject2を通過\n");
        for(int i=0;i<5;i++){
            printf("Aの処理中なのでB,C割り込んじゃダメ\n");
            //Sleep(1000);
        }
        ReleaseSemaphore(hSemaphore,2,NULL);  
    }
}

void thread_B(){
    while(1){
        //1回待つ
        WaitForSingleObject(hSemaphore,INFINITE);
        printf("BのWaitForSingleObjectを通過\n");
        //セマフォ1つ開放
        ReleaseSemaphore(hSemaphore,1,NULL);
        printf("Bのセマフォ1つ開放しました\n");
        //Sleep(1000);
    }
}
//Cも同様

228:デフォルトの名無しさん
06/10/17 05:35:48
>>227の続きです。
Sleep入れると大丈夫ですが、Sleep入れないと割り込み入ります。
できているようないないような。プログラミングがだめなので、わかりにくいです。
Sleep無いとだめということは、たぶん、だめってことですよね。
Sleepありは、出力下記のようになります。

AのWaitForSingleObject1を通過
AのWaitForSingleObject2を通過
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aのセマフォ2つ開放しました
BのWaitForSingleObjectを通過
Bのセマフォ1つ開放しました
CのWaitForSingleObjectを通過
Cのセマフォ1つ開放しました
<繰り返しです。>


229:デフォルトの名無しさん
06/10/17 05:47:55
すみません。コード改行入れているときに消してしまったところあります。
ごちゃごちゃしてすみません。
printf("Aのセマフォ2つ開放しました\n");
がなたったようです。

void thread_A(){
    while(1){
        WaitForSingleObject(hSemaphore,INFINITE);
        printf("AのWaitForSingleObject1を通過\n");
        WaitForSingleObject(hSemaphore,INFINITE);
        printf("AのWaitForSingleObject2を通過\n");
        for(int i=0;i<5;i++){
            printf("Aの処理中なのでB,C割り込んじゃダメ\n");
            //Sleep(1000);
        }
        printf("Aのセマフォ2つ開放しました\n");
        ReleaseSemaphore(hSemaphore,2,NULL);    
    }
}

void thread_B(){
    while(1){
        //1回待つ
        WaitForSingleObject(hSemaphore,INFINITE);
        printf("BのWaitForSingleObjectを通過\n");
        //セマフォ1つ開放
        printf("Bのセマフォ1つ開放しました\n");
        ReleaseSemaphore(hSemaphore,1,NULL);
        //Sleep(1000);
    }
}
//Cも同様

230:デフォルトの名無しさん
06/10/17 06:16:11
thread_B()のSleepの位置が違うし、
眠くてもう脳がだめみたいです。ほんとごめんなさい。
あと、割り込んでなかったみたいです。
Sleep無しの一部を切り取りましたが、
AのWaitForSingleObject1を通過後は、B,C割り込んでいいんでした。
AのWaitForSingleObject2を通過後は、B,C割り込めなければいいんですね。
ほんと、お騒がせしました。
あと<<217さんのご指摘が気になるのですが。

AのWaitForSingleObject1を通過
CのWaitForSingleObjectを通過
Cのセマフォ1つ開放しました
BのWaitForSingleObjectを通過
Bのセマフォ1つ開放しました
AのWaitForSingleObject2を通過
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aの処理中なのでB,C割り込んじゃダメ
Aのセマフォ2つ開放しました


231:デフォルトの名無しさん
06/10/17 06:21:24
>>217

232:デフォルトの名無しさん
06/10/17 08:55:09
>>230
きみは 216 のヒントを理解する能力があった。
217 は 216 のヒントを理解する能力がなかった。
ただそれだけのことなんで気にしなくてもいい。

233:デフォルトの名無しさん
06/10/17 16:43:48
カウント2のセマフォを使う必然性なんてどこにもないよ。

234:デフォルトの名無しさん
06/10/17 16:54:36
やりたいことをまとめると、
・スレッドAが実行中は、B・Cは待機する
・スレッドBあるいはCが実行中は、Aは待機する
・スレッドB・Cは同時に実行できる
ってことか?
だったらカウント2のセマフォが必要だね。

235:デフォルトの名無しさん
06/10/18 01:22:24
>>232
ありがとうございます。

>>233
セマフォっぽくないですが、ミューテックスのときみたいに、
取ってすぐ戻すと同じ動きになりそうですね。
って実はネットに書いてありました。

>>234
はい、やりたいことそれです。

いろんな方法一気に覚えられてよかったです。
ありがとうございました。

236:デフォルトの名無しさん
06/10/18 04:27:33
>>235
>>234の仕様だとすると、>>229のコードでは駄目だよ。
Aが連続してセマフォを獲得する保証は無く、Aがひとつ、Bがひとつ獲得した状態で
Cが待ち状態になる場合もある。それでいいならいいんだけど・・・。

237:デフォルトの名無しさん
06/10/18 07:54:55
>>236
Sleep無しで実行したときなのですが、
>>230の結果を見ると
Aがひとつ、Cがひとつ獲得した状態で
Bが待ち状態になっているようなんですが。
Aがひとつ、Bがひとつ、Cが待ちというのもあると思います。

>Aが連続してセマフォを獲得する保証は無く
Aが連続してセマフォを獲得する保証は、
どのようにすればよいでしょうか。
Aが連続で取れるように、B,CにSleepなど何か
処理をするということでしょうか?

238:デフォルトの名無しさん
06/10/18 14:59:52
>>237
Windowsに詳しくないのでこれだという解決策は示せませんが、この問題は
「read write lock問題」として有名です。
・誰も読んでないときは書ける
・誰かが書いてるときは書き終わるまで読めない
・誰かが読んでいるときは読み終わるまで書けない
・誰かが読んでいても読める
今回の例ではAが書き込みスレッド、B,Cが読み取りスレッドとして対応させると
わかると思います。

windows read write lock
windows read write synchronization
などのkeywordで検索すれば、根本的な解決策が見つかるはずです。

239:デフォルトの名無しさん
06/10/18 18:56:53
>>238
そういうことでしたか。

「Aがひとつ、Bがひとつ獲得した状態で Cが待ち状態になる場合」
はAがひとつ取っても、まだ待機している状態なので、
A,C待機、Bが実行という場合もありますね。
ただ、>>234には矛盾して無いので、
今回は、これもあって大丈夫ということにしたいと思います。

まとめますと、変更無いですが、
・スレッドAが実行中は、B・Cは待機する
・スレッドBあるいはCが実行中は、Aは待機する
・スレッドB・Cは同時に実行できる(片方だけのときもある)
ということになると思います。

「read write lock問題」さっそく勉強してみます。
ありがとうございました。

240:デフォルトの名無しさん
06/10/19 20:22:09
以下のプログラムをコンパイルする時点ではエラーはでません。
しかし、できたexeを実行するとエラーがでます。
どうしてでしょうか?おしえてください。
ちなみにコンパイラはBCC5.5.1です。
#include <stdio.h>
#include <string.h>
struct a {
int no;
char name[64];
};
int main(void)
{
struct a data[2];

data[1].no = 1;
strcpy(data[1].name,"name1");
data[2].no = 2;
strcpy(data[2].name,"name2");

printf("No.%d\n", data[1].no);
printf("%s\n", data[1].name);
printf("No.%d\n", data[2].no);
printf("%s\n", data[2].name);

return(0);
}


241:デフォルトの名無しさん
06/10/19 20:35:09
struct a data[3];

242:240
06/10/19 21:13:34
あ、できました。ありがとうございます。
でも何でですか?

243:デフォルトの名無しさん
06/10/19 21:22:51
>>240
struct a data[2];

data[0]: 先頭の構造体a
data[1]: 二番目の構造体a
data[2]: 三番目の構造体a <-定義されていない




244:デフォルトの名無しさん
06/10/19 21:23:28
配列の章をまた初めから読み返してみろ

245:240
06/10/19 21:28:02
ああ、わかりました。0から始まるんですね。
すいません。おさわがせしました。

246:デフォルトの名無しさん
06/10/19 21:33:29
質問です。

エラー E2209 test.cpp 1: インクルードファイル 'vcl.h' をオープンできない
エラー E2303 test.cpp 3: 型名が必要
エラー E2034 test.cpp 3: 'char *' 型は 'int' 型に変換できない
エラー E2303 test.cpp 4: 型名が必要
エラー E2034 test.cpp 4: 'char *' 型は 'int' 型に変換できない
エラー E2293 test.cpp 4: ) が必要
エラー E2141 test.cpp 6: 宣言の構文エラー

とでてコンパイルできません…

247:デフォルトの名無しさん
06/10/19 21:40:33
>>246
ソースを見せてみ

248:デフォルトの名無しさん
06/10/19 21:46:38
こちらです

#include <vcl.h>
#pragma hdrstop
USERES("test.res");
USEFORM("Unit1.cpp", Form1);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Title = "test";
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
return 0;
}

249:デフォルトの名無しさん
06/10/19 22:35:31
君はVCLをもっているのか?

250:デフォルトの名無しさん
06/10/20 00:00:25
2時間前くらいからCを勉強し始めたんですが、うまくいきません。
半径を入力して球の体積と面積を求めるってやつなんですけど、
入力が反映されなくて。

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

void main()
{
double rad, surface, volume;

printf("\nPlease input a radius. "); scanf("%f",&rad);

printf("Radius = %f \n",rad);

surface = 4 * M_PI * rad * rad;
volume = 4 / 3 * M_PI * rad * rad * rad;

printf("S = %f V = %f \n",surface,volume);
}


251:デフォルトの名無しさん
06/10/20 00:08:38
>>250
そのプログラムを動かし、たとえば1と入力するとどうなる?

252:デフォルトの名無しさん
06/10/20 00:34:47
4/3=1

253:デフォルトの名無しさん
06/10/20 00:36:25
>>251

0.000000 です。

254:デフォルトの名無しさん
06/10/20 00:38:37
>>253
S = とか V = とか表示されねーのか。そりゃ不思議だな。

255:デフォルトの名無しさん
06/10/20 00:40:50
うまくいかない、じゃなくて、何を期待してどういう結果になったのか書くべし。

それ以前に、勉強開始たった2時間半程度で人に聞くのはどうかと。
その時点では分からないことだらけで当然だろう。
とりあえずは参考書などで基本事項を一通り勉強したら?

%f → %lf

256:デフォルトの名無しさん
06/10/20 00:57:06
>>255

どうもありがとうございます。
参考書の例題だったんですが、
書いてある通りやってもうまくいかなくて。

257:デフォルトの名無しさん
06/10/20 01:02:34
関数の中で関数別の関数呼んで、またそのなかで別の関数を…っていうふうに
階層が深くなってるとき、下のほうで起こったエラーはどこで処理するのがいいんですか。
一番下なのか…?はたまた上までエラーコード引っ張っていって一番上なのか…?

また上まで引っ張っていった場合、その途中の関数で起こったエラーコードとかぶらないようにするために
考えると、エラーコードの種類がすごく肥大化してしまったんですけど、
こういうものなんでしょうか?

258:デフォルトの名無しさん
06/10/20 01:08:04
>>257
C では、そういうもの。
そういう問題への対策が、最近の言語に備わっている例外処理機構。
C++ にもある。

259:デフォルトの名無しさん
06/10/20 01:14:09
>>258
なるほど。そういうものなんですか。
ありがとうございます。

後例外処理なんですが、実はあまり理解していなくて、try catchする(c++)のと、戻り値判定(c)するのと
どう違うのかと疑問に思ってました。例外処理のメリットというか。。
上記のような問題を解決する機構が例外というのはどういうことなんでしょうか。

何かキーワードだけでも教えていただけたらできるだけ自分で調べてみます。。

260:デフォルトの名無しさん
06/10/20 01:23:15
>>259
C++ の例外処理機構を使えば、エラーは発生した
その場所で迷わず throw すればいい。
エラーを処理する場所や方法は使用者が選べる。

↓のスレに情報がいくらか貯まっている。

例外処理
スレリンク(tech板)

261:デフォルトの名無しさん
06/10/20 01:23:54
try {
func1
 +func2-1
   +func3  --(A)
 +func2-2  --(B)
} catch (...) {
 // エラーきた --(C)
}
のように奥の func3 で例外を発行すると、func1 の途中部分であっても
きれいに脱出して(デストラクタの面倒は見て) (C) に到達できる。
この例の場合、(B) は実行されない

262:デフォルトの名無しさん
06/10/20 01:33:57
>>260
上まで引っ張っていかなくてもいいってこと…ですよね?
なるほどそれだとたしかにエラー処理が綺麗に書けそうな気がします。
スレのほうも熟読してみます!ありがとうございました。

>>270
なるほど!これはわかりやすいです。
これは便利なんですね…
いままでせっかくc++のコンパイラ使ってたのに全部戻り値判定で引っ張っていたのが
すごく時間と労力を無駄にしてたきがしてきました…大げさかもしれませんがw
こんな機能ならぜひ例外処理を勉強してうまく使っていくようにしたいとおもいました。

どうもありがとうございました。


263:デフォルトの名無しさん
06/10/20 02:06:14
基本的に例外処理は便利で有意義なもの。
がんがん使え。

が、C++に限っては、性能を気にしだすと封印せざるを得なくなる諸刃の刃。
でもやっぱりがんがん使え。
使い慣れないとデストラクタ周りで戸惑ったりするので、経験値稼ぐためにもばんばん使え。
デメリットのことは後で考えればよい。

264:デフォルトの名無しさん
06/10/20 02:19:37
はい。ガンガン使っていくようにしたいです。
何かのプログラムの本で、便利な機能は変なこだわりは捨ててどんどん使ったほうがいいって書いてたのを
読んだことがことがあります。
あとご指摘のデストラクタとの絡みのところもしっかり勉強したいと思います。

265:デフォルトの名無しさん
06/10/20 02:29:18
へー、諸刃の刃なんて言葉も一応辞書に載ってるんだ。
普通は諸刃の剣だと思ってたけど。

266:デフォルトの名無しさん
06/10/20 02:29:59
指が滑ったんだ。
ケツの穴の小さいこというなよ。
刺さらないじゃないか。

267:デフォルトの名無しさん
06/10/20 02:33:31
つーか、今まで「もろはのけん」だと思ってたよ。
ついでに正しい知識が身についてよかった。


・・・・吉野家コピペくらいでしか使わないかもしれないが。

268:デフォルトの名無しさん
06/10/20 10:57:54
うかつなこと書くなよ
剣がケツの穴に刺さったところ想像しちゃったじゃないか

269:デフォルトの名無しさん
06/10/20 19:58:59
C++で例外と入ったら、性能よりも例外安全のほうがよっぽど心配になる。

270:デフォルトの名無しさん
06/10/21 00:59:54
そいつもいちいちごもっとも。

271:デフォルトの名無しさん
06/10/21 01:38:49
質問失礼します。

stringに入っている文字列を char* に変換したいのですが
良い知恵はありますでしょうか。
const char* では無く char* にしたいのです。

今のところ思いつくのは、自前で char* の領域を確保して
そこに c_str() の内容をコピーすれば問題は無いかと思うのですが
せっかく便利なクラスがあるのに、何だか冗長な気がします。

一応調べた限りでは const_cast という物があるようですが
const_castした文字列にアクセスした場合の動作は未定義という
記述がされていたりするのでそれはちょっと無いかな、と思います。

272:デフォルトの名無しさん
06/10/21 01:54:43
>>271
std::vector<char>でも使えば?

273:デフォルトの名無しさん
06/10/21 01:59:47
const_castは古いライブラリの機能を無理やり使いたい時とかのためだけに用意されてる様なもん。
基本的に使っちゃ駄目。

で、const_castを止めておきながら、こんなコードを薦めるのは激しくナニなんだが、
std::stringは添え字演算子が使える。
ので、一応

std::string str = "nullpo";
char* p = &str[0];

みたいな書き方はできないわけじゃない。


やっちゃ駄目よ?
問題起こしたところも見たことは無いけど。

274:デフォルトの名無しさん
06/10/21 02:29:31
>>271
>stringに入っている文字列を char* に変換したいのですが
これが何を言っているかはっきりしないんだけど、

char *型の引数を要求するけど実際には渡した領域を更新することはない、
という関数に渡すというような使い方なら、const_castで問題ないと思う。
>const_castした文字列にアクセスした場合の動作は未定義
参照するだけなら問題ないんじゃなかったっけ?

文字列を更新する目的で char*型にしたいといっているなら、
自分で更新可能な領域にコピーするしかない。


275:271
06/10/21 03:05:01
>272-274
参考になります。
今回の場合、実際は更新しない文字列だったので
>274さんの言う通りconst_cast使っても問題はあまり無さそうです。

ただ、更新する文字列のことも考えると
自前で確保する方法も覚えて損はなさそうですね。
std::vector はまだ使った事がありませんが覚えておきます。

ありがとうございました。

276:デフォルトの名無しさん
06/10/21 07:38:19
>>273
そのうちstd::vector同様にstd::basic_stringでも認められるという噂を聞いたことがあるんだ。

277:デフォルトの名無しさん
06/10/21 10:49:27
>>276
いや、あれは実際に採用されるかどうかはまだ怪しい話。

278:デフォルトの名無しさん
06/10/21 19:30:53
このレベルで「はきだめ」なのか…orz
ここ以下のおいらはどこに行けばいい?

279:デフォルトの名無しさん
06/10/21 19:39:19
こんなスレもあるぜ

【初心者歓迎】C/C++室 Ver.32【環境依存OK】
スレリンク(tech板)



でも、余程頓珍漢な事を書かない限りここでもokだと個人的には思うが。


280:デフォルトの名無しさん
06/10/21 20:05:10
まぁ、ここは下級者の質問をネタに半可通が自爆するスレだからこそ掃き溜めというわけだからな。

281:デフォルトの名無しさん
06/10/23 11:02:39
int function(const int x)

int function(int x)
の違いを教えてください。



282:デフォルトの名無しさん
06/10/23 12:09:53
>>281
前者はxがconstだから関数の中で代入できない
関数に渡す値は非constでもOK

283:デフォルトの名無しさん
06/10/23 17:21:12
#include <iostream>
using namespace std;

//avg関数の宣言
double avg(int t[]);

int main()
{
int test[5];

cout << "5人のテストの点数を入力してください。\n";
for(int i=0; i<5; i++){
cin >> test[i];
}
double ans = avg(test);
cout << "5人の平均点は" << ans << "点です。\n";

return 0;
}

//avg関数の定義
double avg(int t[])
{
double sum = 0;
for(int i=0; i<5; i++){
sum += t[i];
}
return sum/5;
}



284:283
06/10/23 17:24:23
配列を関数で引数として使う場合は実引数として配列名を渡しますよね
でも配列名は先頭要素のアドレスを表しますよね。
関数のdouble avg(int t[])の仮引数、t[]に先頭要素のアドレスを渡すことで
何で上のソースが動くのですか?
もし配列の各要素の値が渡されるとしたなら納得できるのですが、
アドレスが渡されるのにこの関数が動く理由がわかりません・・・
どなたか納得できるように説明していただけませんか?

285:デフォルトの名無しさん
06/10/23 18:03:33
>284
C言語の配列がメモリにどう配置されるかを学ぶと良い

Cの配列は要素[0]を先頭に
連続したメモリ領域に配置される

例えば char s[255]; と書いた場合
s[0] のアドレスが 54322 バイト目なら
s[1] のアドレスは 54323 バイト目になる

char は1バイトだから1バイト毎
short なら2バイトだから2バイト毎な

だから配列の先頭要素のアドレスが判れば
その先の要素のアドレスも判る

286:284
06/10/23 20:29:26
>>285
詳しい説明ありがとうございます。
何となくですが分かりました。
もうちょっと詳しく勉強してみます

287:デフォルトの名無しさん
06/10/23 21:22:18
関数を使う立場からすれば、大きさの分かっている配列を渡しているが
渡された立場からみると、配列の大きさがわからない。
で、範囲外のアクセスでバグる と。

288:デフォルトの名無しさん
06/10/24 04:00:10
そこでテンプレートです。

289:デフォルトの名無しさん
06/10/24 08:26:57
#include <string.h>

#include <string>

#include <cstring>
の違いを教えてください。

cmath等と同様、cstringが最新のC++にあっているのかと思っていたのですが、
bcc32でcstringでコンパイルできたものがvc7ではstringにしないと、

二項演算子 '!=: 型 'std::string' の左オペランドを扱う演算子が見つかりません (または変換できません)

というエラーが出てコンパイルできませんでした。時期的には、vc7の方が新しいはずなのですが・・・

290:デフォルトの名無しさん
06/10/24 08:45:25
>>289
そもそも何がしたいんだ?

Cの<string.h>のC++版が<cstring>で、
strlenとかstrcpyなどの関数を使用するときにインクルードする。

C++での<string>はstd::stringという文字列クラスを扱うときに用いる。

291:デフォルトの名無しさん
06/10/24 12:15:02
>289
・C言語の "string.h"
文字列操作の為のライブラリ

・C++ の <string>
文字列クラス std::string を使う為のライブラリ

・C++ の <cstring>
C言語の "string.h" 風味のライブラリ



C言語の str~ 系の関数を使いたいなら
cstring をインクルードする

もしくは、ソースには"string.h" と書いて
大概の処理系にある
C言語としてコンパイルするオプション(や拡張子 .c)
でコンパイルすれば良い

292:デフォルトの名無しさん
06/10/24 16:58:06
#include <iostream>
using namespace std;

//func関数の宣言
void func();

int a = 0;

//main関数
int main()
{
for(int i=0; i<5; i++)
func();

return 0;
}

//func関数の定義
void func()
{
int b = 0;
static int c = 0;

cout << "変数aは" << a << "変数bは" << b << "変数cは" << c << "です。\n";
a++;
b++;
c++;
}

293:292
06/10/24 17:02:11
staticをつけると、そのローカル変数はグローバル変数と同じ記憶寿命を持つんですよね?
同じ記憶寿命を持っても上のコードでfunc()関数が呼び出される度にstatic int c = 0;と初期化しているのに何故実行結果では
0,1,2,3,4と増えていくのでしょうか?

staticをつけて初期化されるのは一回目だけということでしょうか?


294:デフォルトの名無しさん
06/10/24 17:48:49
その通り
「初期化」は最初だけ
毎回0にしたければ「代入」をするべし

295:デフォルトの名無しさん
06/10/24 17:52:36
>>294
一つ謎がとけました
ありがとうございます

296:デフォルトの名無しさん
06/10/25 05:43:46
まだまだ謎がありそうだけど、
あなたを犯人です。

297:デフォルトの名無しさん
06/10/25 07:00:13
>296
中国語でおk

298:デフォルトの名無しさん
06/10/25 12:14:07
スレ違いかと思いますが、どこで聞けばいいのかもわからないアフォです。どうか助けてください。
普段からコンパイラにbcc5.5を使っているのですが、
今回、グラフィックスを描く必要があって、
fURLリンク(spdg1.sci.shizuoka.ac.jp)に置いてあるlGrWn0999b-f2bcc.exeでインストールして、
URLリンク(www005.upp.so-net.ne.jp)にある以下のサンプルを
動かしてみました。
#include <GrWin.h>

int main(void)
{
int width = 640, height = 400; /* ウィンドウサイズ640×400 */

GWopen(0); /* ウィンドウのオープン */
GWsize(-5, &width, &height); /* ウィンドウサイズ設定 */
GWsize(-3, NULL, NULL); /* フレーム(枠)サイズ設定 */
GWvport(0.0, 0.0, (float)width / (float)height, 1.0); /* ビューポート設定 */
GWindow(0.0, 0.0, (float)width - 1.0, (float)height - 1.0);
GWquit(); /* 終了処理 */ /* ↑ワールド座標系設定 */
return 0;
}
普段課題を出されたときと同じようにbcc32 sample.c のように打ち込んだのですが、
Error:外部シンボル '_GWopen'が未解決(C:\CWORK\SAMPLE.OBJが参照)
Error:外部シンボル '_GWsize'が未解決(C:\CWORK\SAMPLE.OBJが参照)
Error:外部シンボル '_GWvport'が未解決(C:\CWORK\SAMPLE.OBJが参照)
Error:外部シンボル '_GWindow'が未解決(C:\CWORK\SAMPLE.OBJが参照)
Error:外部シンボル '_GWquit'が未解決(C:\CWORK\SAMPLE.OBJが参照)
というエラーが出てしまいどうしても動いてくれません。
一度bccとGrwinをインストールし直したり、手動でインストールしようとして他のプログラムまで動かなくなったり、
あの手この手を尽くしたつもりなのですがダメでした。
googleで似たような症状を探しても見つけられないし、八方塞がりです。
どなたか解決法のわかる方、いらっしゃいませんでしょうか?


299:デフォルトの名無しさん
06/10/25 12:35:41
GrWinとやらはダウンロードしてないがlibファイルは入ってなかったか?
入ってたとしたらそれをリンクすればいけるかもしれない

300:デフォルトの名無しさん
06/10/25 18:06:14
すいません教えて下さい。
ClassDef のオブジェクトを他の関数らで使いまわしたいのです。
その場合、ClassDefのオブジェクトが無ければ作り
作られていればそのオブジェクトを使いたいのです。

そこで GetObjという関数を作り、そこで上記の判断を
させようと思うのですが、どのように作れば良いのかが・・・

下記の他にも良い書き方があればご教授の程お願い致します。

ClassDef* ObjDefP = NULL;

ClassDef GetObj()
{
if( ObjDefP = NULL ){
ClassDef ObjDef;
ObjDefP = &ObjDef;
return AppObj;
}else{
//return ObjDefP//ここが良くわかりません・・・
}
}

func1() {
ClassDef Obj = GetObj();
Objに対して処理1
}

func2() {
ClassDef Obj = GetObj();
Objに対して処理2
}

301:デフォルトの名無しさん
06/10/25 18:23:11
シングルトンパターンだな.
new 使わない微妙なやつだけど、参照返しで

class ClassDef {
private:
 ClassDef() {} ~ClassDef() {}
public:
 static ClassDef& GetObj() { static ClassDef body; return body; }
 // その他公開メソッド
};

////// 利用側
func1() { ClassDef& cObj = ClassDef::GetObj(); }
func2() { ClassDef& cObj = ClassDef::GetObj(); }

302:デフォルトの名無しさん
06/10/30 03:48:35
以下で、どれが一番清く正しく美しいですか?
お兄ちゃんはどんな風に書く?
int main(void) {}
int main() {}
main(void) {}
main() {}

303:デフォルトの名無しさん
06/10/30 03:53:14
>>302
Cならばint main(void) {}
C++ならばint main() {}

304:デフォルトの名無しさん
06/10/30 09:33:03
ちょっとしたテストコードは main() { で書いてる。
でもある程度長くなりそうなら
値返すだけでなくコマンド引数も受け取る。

305:デフォルトの名無しさん
06/10/30 18:58:32
ああ、コマンド引数は考えなくてもいいですけど。
そっか、Cではint main(void)が厳密なんですね?
C++ではvoidが省略できるみたいな?

306:デフォルトの名無しさん
06/10/30 20:55:41
C++ は main() って書くと int main() 扱いじゃなかったか?
んで暗黙に return 0; が書かれたことになるって仕様だったような。

307:デフォルトの名無しさん
06/10/30 21:21:34
>>306
暗黙のintはなくなった。2文目は正しい。

308:302
06/10/31 22:01:45
自分の得たい答えは得られました。
ありがとうございました。

309:デフォルトの名無しさん
06/11/02 10:04:14
iostreamで質問があります。
文字列を入力するとき
string s;
cin >> s;
とすると、長さ1以上の場合は問題ないのですが
長さ0の文字列が入力できません。
エンターキーだけ押せば長さ0の文字列と見なして欲しいのですが、
どうすればいいでしょうか。

310:デフォルトの名無しさん
06/11/02 10:13:02
getline(cin,s)

311:309
06/11/02 17:12:16
>>310
ありがとうございました!

312:デフォルトの名無しさん
06/11/13 00:50:01
初学者の下らない質問ですがお許しください。
VC.Net2005を買ってきたのですがマシンパワーが足りないのでIDEを
使いたくなくてコマンドラインコンパイラとして使用しようと思っています。

C:\Program Files\Microsft VisualStudio 8にインストールし、
C:\ComLineCode\Cpp\にソースコードを置こうと思っています。

テストという事でcpptest.cppと名前を付けたコードをコンパイルしようと
したのですが、includeファイルが見つからないといわれたので、
OS(Win2k)の環境変数にINCLUDEを作り、iostreamを検索した結果出てきた
フォルダを指定してやったのですが、
C++例外処理を使っていますが、アンワインドセマンティクスは有効にはなりません。
と出てコンパイルできません。

// cpptest.cpp
#include <iostream>
using namespace std;
void main(void)
{
cout << "表示されれば設定OK";
}
//EOF

cl cpptest.cpp
ソースは間違って居ないと思うので設定が不味いだけだとおもうのですが、
どのようにしたら上手くコンパイルできるでしょうか?

C++以前の問題ですが、どうぞアドバイスを下さい。お願いします。

313:デフォルトの名無しさん
06/11/13 01:18:59
>>312
「スタート→プログラム→Visual C++ 2005 Express Edition
→Visual Studio Tools→Visual Studio 2005 コマンド プロンプト」
で必要な環境変数が設定された状態のコマンドプロンプトが起動できる。

その例外処理がなんたらというのはエラーではなく警告。一応実行ファイルは作られている。
そしてその警告文には、その後に「/EHsc を指定してください。」と書いてあるはずだ。そのとおりにしろ。

314:デフォルトの名無しさん
06/11/13 01:21:20
>>312
エラーメッセージはちゃんと全部読め。
cl /? を見ろ。オンラインマニュアルを読め。

315:デフォルトの名無しさん
06/11/13 01:21:24
INCLUDEはvcvars32.batとか使えば勝手に設定されるからそっち使えよ。

でもってアンワイ(ryに関しては warning って書いてあるでしょ?
エラーじゃなくて警告だから気にしないのなら気にしなくていいし、
気になるんなら警告に書いてある通りにオプションつけろ。

316:デフォルトの名無しさん
06/11/13 01:22:22
>>313-315
3P汁

317:デフォルトの名無しさん
06/11/13 01:27:36
いまだにデフォルトになってなかったのか。なんでだろうな?

318:デフォルトの名無しさん
06/11/13 04:10:14
vcvars32.batに
SET CL=/EHsc
の行を加えておくことを推奨

319:デフォルトの名無しさん
06/11/13 10:16:37
int* p;



int *p;

って同じもの?

320:デフォルトの名無しさん
06/11/13 14:49:47
>>319
同じ。だが
int *p, *q;

int* p, q;
は違うから初心者は注意するように。

321:デフォルトの名無しさん
06/11/13 22:05:25
どう違うんだろう

int *p, *q; は

int *p;
int *q;



int* p, q; は

int *p;
int q;


であってる?

322:デフォルトの名無しさん
06/11/13 22:15:32
あってる

323:デフォルトの名無しさん
06/11/13 22:16:00
ありがとう

324:デフォルトの名無しさん
06/11/14 12:49:06
ディレクトリの中を*を含んだ文字で検索するプログラム作っています。
windowsだと
_findfirst,_findnextがあって、*を含んだ検索が出来ます。
linuxだと
opendir,readdirがありますが、*を含んだ検索が出来ません。

そこで質問なんですが、
struct dirent *dir;とすると、
readdirを読んで、dir->name比較する関数で毎回調べて、
繰り返さないといけないでしょうか?

なにか他に簡単な方法あるとよいのですが。
よろしくお願いします。

325:デフォルトの名無しさん
06/11/14 12:56:06
まあ普通にreaddir+fnmatchで大した手間にはならないと思うけど
他にやり方があるのかは知らない。

326:デフォルトの名無しさん
06/11/14 13:09:21
>>325
実は、_findfirst,_findnextで作ってしまいまして。
コンパイルできないと思ったら、linuxだからということがわかりました。
似たような関数があればー。と思ったのですが。

確かに、そんなに大変ではないかもしれないです。
ありがとうございました。

327:デフォルトの名無しさん
06/11/14 23:55:59
C++で型をコンパイル時に判別する方法ってどうやれば良いのでしょうか。

例えば
template <T>
hogehoge(T val){


328:デフォルトの名無しさん
06/11/15 00:00:53
すみません、途中で書き込んでしまった・・・。

C++で型をコンパイル時に判別する方法ってどうやれば良いのでしょうか。
例えば
template <T>
void hogehoge(T val){
   if(T == int) {
処理1
} else if (T == char) {
処理2
}
}
のようなことをやりたいのです。もちろん上のコードはコンパイルなどできませんが・・・。

void process(int val){...}
void process(char val){...}
....
みたいなものを型ごとにひたすら用意して、
void hogehoge(T val){
  process(val);
}
とすればできますが、それだとコード量がふくらんでしまいます。他に良い方法ありますか?

329:デフォルトの名無しさん
06/11/15 00:13:53
>>328
明示的特殊化を使えば?

330:デフォルトの名無しさん
06/11/15 07:29:32
>>326
つ[popen("/bin/ls *", "r")]

331:デフォルトの名無しさん
06/11/15 11:58:02
>>328
typeid

332:デフォルトの名無しさん
06/11/15 17:56:02
>>328
BoostにMPLとかtype_traitsとかいろいろあるよ。

まあこんなところで勧めていいかわからないが。

333:デフォルトの名無しさん
06/11/18 03:34:45
質問です。
今までファイルからデータをストリームとして呼んでいたのですが、ファイルの内容を簡易的に隠蔽したくて、
ヘッダファイルにchar filedata[] = "(ファイルの内容)";
として、ソースに埋め込んだのですが、これをファイルからの読み込みと同じように、ストリームとして読み込み処理を行いたいのです。
char配列をストリームにする方法ってあるのでしょうか。

334:デフォルトの名無しさん
06/11/18 08:10:49
>>333
iostream の実装は自分で定義することができるようになってるから、
いちおう可能なはず。簡単かどうかは知らない。
↓ここらへんから始めれ。
URLリンク(www.google.co.jp)

335:デフォルトの名無しさん
06/11/18 09:58:12
つstd::istringstream <sstream>

336:デフォルトの名無しさん
06/11/18 22:36:06
vector<T>ってTがbool型以外の時はメモリが連続していると聞いたのですが、

vector<float> *vec = new vector<float>(5000);

for(int i=0; i<5000; i++) {
float *tmp = (float *)&vec[i];
cout << *tmp << endl;
*tmp = 100;
}
Visual C++ 2005 でこのコードを実行するとエラーになります。
Visual C++だとメモリが連続していないのでしょうか?

337:デフォルトの名無しさん
06/11/18 22:47:32
>>336
× (float *)&vec[i];
○ &(*vec)[i]

無茶なキャストした時点でなんかおかしいって気づけよ。

338:デフォルトの名無しさん
06/11/18 22:57:10
>>337
gcc4.0だとこれでも上手くいくのですが・・・・。

339:デフォルトの名無しさん
06/11/18 22:59:45
ちなみにこのページを参考にしました。
URLリンク(www.s34.co.jp)

340:デフォルトの名無しさん
06/11/18 23:03:26
>>338
未定義動作。

>>339
そのページを見て vector を new するとは、本末転倒。

341:デフォルトの名無しさん
06/11/18 23:08:10
>>338
間接参照のレベルが一段違うだろうが。

342:336
06/11/18 23:11:33
>>336
あ、分かりました。
float *tmp = (float *)&vec[i];
でなくて
float *tmp = &(*vec)[i];
とすべきだったんですね。vec[i]ではvector<float>の配列としてi番目のvector<float>オブジェクトにアクセスする意味になってしまう・・・。
寝ぼけてました。すみません。

343:デフォルトの名無しさん
06/11/18 23:13:03
意味を持つのはvec[0]だけ。
vec[1]~はメモリのどこを指しているのかわからない。

344:デフォルトの名無しさん
06/11/18 23:21:04
>>343
ばかですか?

345:デフォルトの名無しさん
06/11/18 23:23:37
どこを指してるかはわかるだろ

346:デフォルトの名無しさん
06/11/18 23:29:59
要するにvec[1]をアクセスした時点で未定義動作だろ

347:デフォルトの名無しさん
06/11/18 23:30:08
>>344
危険いっぱいの所を指している、という事を言いたかっただけなんじゃまいか

348:デフォルトの名無しさん
06/11/18 23:35:43
配列の要素を指していないポインタに対して +/- した時点で未定義動作。
p[i] は (*(p+i)) と定義されているので、 vec[0] も未定義。

349:デフォルトの名無しさん
06/11/18 23:43:49
vec[0]は*vecなので、vector<float>を指しているだろ。
何言ってんの?

350:デフォルトの名無しさん
06/11/18 23:47:44
× vec[0]は*vec
○ vec[0]は*(vec+0)

351:デフォルトの名無しさん
06/11/18 23:49:32
>>350
本気で信じてるのか?規格書のどこに書いてあるか出せよ。

352:デフォルトの名無しさん
06/11/18 23:52:42
>>348の1行目が本当だとしても
NULLは0とは限らないがNULLが0でないコンパイラなんてまずない
ってのと一緒で、ほとんどのコンパイラじゃ問題にならないんだよな?

353:デフォルトの名無しさん
06/11/18 23:54:30
C++ では 5.7p5 に >>348 の言ってることは書いてあるが、
その前に 5.7p4 で配列じゃないオブジェクトを指すポインタは
要素数1の配列と同等に扱うとなっているので、問題ない。
5.7p4 を読まずに 5.7p5 だけ読んだんだろう。

C では 6.5.6p7, p8 に同様のことが書いてある。

354:デフォルトの名無しさん
06/11/18 23:54:33
いやいや、そんな些末な納得の仕方よりも、規格書で該当する部分を
出してもらえばそれで完全に決着するから。

355:348
06/11/18 23:56:46
正直スマンカッタ

356:デフォルトの名無しさん
06/11/18 23:56:54
というわけで>>348>>350は無知だと証明されました。終わり。

357:デフォルトの名無しさん
06/12/01 12:42:11
linuxなんですが質問です。

ただ単にファイルをコピーするプログラムと
lsコマンドを自作したのですが、
もし、lsコマンドするフォルダに書き込み中のファイルがあったら、
「書き込み中」を表示したり、違う処理をしたいのですが、
書き込み中か調べる方法ってありますでしょうか?

考えてみたのですが
■lsコマンド側で解決方法
sleepを入れて容量の増減を調べる。
(これだと返ってくるまで、すごい時間が掛かってしまいます。)

■書き込むプログラム側の解決方法
・元のファイルをA,コピー先のファイルをA'とすると
1、A'を作ります
2、ファイルディスクリプタ指定してA'をlockします
3、書き込みします。
4、lock解除

・何かCOPYコマンドにオプション付けるとコピーが終わるまで
読めなくなるとないでしょうか。

358:デフォルトの名無しさん
06/12/01 13:40:39
>>357
357です。
なんか質問の内容がぼけてしまってますね。
ちょっと質問内容変更させてください。

書き込むプログラムは、自分で作ったもので
無い場合(lockしてない場合)でも書き込み中か
知る方法ってあるでしょうか?
sleep使って調べると時間かかってします。

359:デフォルトの名無しさん
06/12/01 14:14:40
「書き込み中」を、「コピープログラムがコピーを完了していない」状態と考えていいのかな?
それならば、コピー完了を知る手段は一般的にはないと思う。
解決策としては、こんなもんかなぁ……

・コピー元ファイルのサイズを知り、コピー先ファイルのサイズと較べる。
・コピー対象ファイルの終端の特徴を知り、コピー先ファイルの終端がその特徴に一致するか調べる。
#汎用性はないが、コピー対象が特定のフォーマットに従っているならそれなりに実用的か。
・コピープログラムに完了を通知してもらう。
#通知方法は色々考えられる。signalでもいいし、ファイルでもipcでもいいだろう。
・コピープログラムに一旦別の名前でコピーしてもらい、コピー完了後に目的の名前に変えてもらう。


360:デフォルトの名無しさん
06/12/01 19:59:29
>>359
何通りもありがとうございます!
どれもすごい参考になりました。
上2つは、初心者の僕でもすぐにできそうです。
signalも勉強してみます。

361:デフォルトの名無しさん
06/12/11 18:25:45
どうして

static const int Size = 256;
int a[Size];
for (int i = 0; i < Size; ++i)

ではなく

static const std::size_t Size = 256;
int a[Size];
for (std::size_t i = 0; i < Size; ++i)

の方が正しいの?


362:デフォルトの名無しさん
06/12/12 00:34:24
>>361
誰がそんなことを言ってたかは知らんが、その範囲を見ただけでは
上が間違っているとは思えないが。
下のほうは、size_tが64bitのような環境ではかえって無駄なことをしているだけのように思える。

363:デフォルトの名無しさん
06/12/12 03:39:31
>誰がそんなことを言ってたか
cppllから引っ張ってきたネタでしょ
URLリンク(www.tietew.jp)

話題を提供しつつ小遣いを稼ぐという視点は無かったな

364:デフォルトの名無しさん
06/12/12 03:51:10
cppll って、技術コミュニティとしてはもう崩壊してるよね。
C/C++ コミュニティで「昔の C コンパイラでも void を書くか書かないで・・・」に
突っ込みが入らないのは異常だろ。

365:デフォルトの名無しさん
06/12/12 05:34:30
>>362
そりゃ実装依存の話であって、誰が悪いかっつったら断りなしにsize_tを64ビット化した環境のが悪い気が。
もっとも、size_tは基本sizeofの返り値用の型だし、要素数表現に使われてるのはちょっと微妙なわけだが。

366:デフォルトの名無しさん
06/12/12 17:03:25
size_tを要素数や文字列長に使うのは自然だと思うけど。
無符号というのも意味的にスッキリしてるし。
ビット長はその処理系で必要な長さになってるんだから無駄と言うのも変な話だ。

367:デフォルトの名無しさん
06/12/14 02:07:17
例えばmallocの引数型がsize_tなのは、
そのままsizeof演算子の結果に配慮したからで、
これを要素数倍するのは構わないのだが、
要素数を扱う型にくくってしまうのは、少々短絡的。

文字列長に使うのは、charがなんだかんだで
バイト単位と認められてしまってるところから。

一番悪いのはlengthof演算子だのlength_tだのを
用意しなかったCそのものだと思われるが、
C++に世代が移ってループもイテレータで回す昨今、激しくどうでもいい。

俺も上のようなことは正直こじつけそのもので、自分でもまったく信じてない。


最近だとptr_diffなんかも64ビット化してるんで、
細かい目で見るとポインタの加減算もコストが嵩んでる。

無視するのがいいのだろうが、世の中ままならぬ。

368:デフォルトの名無しさん
06/12/14 11:23:59
そういやC99ではどうなん?

369:デフォルトの名無しさん
06/12/14 19:53:08
>>368 何の話だ?

370:デフォルトの名無しさん
07/01/06 18:19:48
boolは1バイト消費するのですか?


371:デフォルトの名無しさん
07/01/06 19:48:59
かもしれないし4バイトかもしれない

372:デフォルトの名無しさん
07/01/07 08:06:00
>>370
STLなら1ビット

373:デフォルトの名無しさん
07/01/07 12:43:05
>372
はぁ?

374:デフォルトの名無しさん
07/01/07 15:18:41
>>373
std::vector<bool>のことを言っているんだろう

375:デフォルトの名無しさん
07/01/07 16:46:38
vector<bool> は領域節約のため特殊化する必要があるが
それは 1 bit を保証するものではない。

376:デフォルトの名無しさん
07/01/07 17:15:33
>>374-375
それって valarray<bool> のことじゃなかったっけ?

377:デフォルトの名無しさん
07/01/08 00:18:10
>>376
23.2.5 Class vector<bool> [lib.vector.bool]
1 To optimize space allocation, a specialization of vector for bool elements is provided

378:デフォルトの名無しさん
07/01/12 17:01:28
引数を受け取るコンストラクタがある関数オブジェクトを
渡す方法を教えてください。

struct Func
{
  int data;
  func(int v) : data(v) {}
  int operator() (int i) { return v*i; }
}

template<typename F>
int Test(F f, int i)
{
  return f(i);
}

int main()
{
  Func func(1);
  return Test(func, 2);
}

Test<F>(Func) に一致するものが見つからないと怒られます。

struct Func
{
  int operator() (int i) { return i; }
}
こうすると通ります。なぜでしょうか?

379:デフォルトの名無しさん
07/01/12 17:02:51
func(int v) : data(v) {}のところはFunc(~のtypoです

380:デフォルトの名無しさん
07/01/12 17:28:07
struct Func
{
  int data;
  Func(int v) : data(v) {}
  int operator() (int i) { return data*i; }
}

まだ間違ってました。


381:デフォルトの名無しさん
07/01/12 17:33:04
>>378-380
通るじゃないか。コンパイラ何使ってんの?

382:デフォルトの名無しさん
07/01/12 17:36:23
うあれ?TurboC++です。もう一度やってみます

383:デフォルトの名無しさん
07/01/12 17:42:23
gcc3.4.2なら通るぞ。

384:デフォルトの名無しさん
07/01/12 17:42:26
すみません、再構築したら通りました・・・・

385:デフォルトの名無しさん
07/01/12 17:50:21
makefileをちゃんと書いてないんじゃないの?
ヘッダとの依存性とかを

386:デフォルトの名無しさん
07/01/15 22:00:14
C++で
vector<counter> v(dic.begin(), dic.end());
sort(v.begin(), v.end(), cmp);
for (vector<counter>::iterator i = v.begin(); i != v.end(); ++i)
cout << i->first << ":" << i->second << endl;
return 0;
の部分の機能がわからないのでどなたか解説してください

387:デフォルトの名無しさん
07/01/15 22:50:34
URLリンク(www005.upp.so-net.ne.jp)

388:デフォルトの名無しさん
07/01/15 22:52:01
dicというコンテナからcounter型のvectorを生成し、
それをcmpを比較関数としてソート
ソート結果を表示


389:デフォルトの名無しさん
07/03/02 11:50:48
1.0-1.0が0にならない理由を教えてくだすれ

390:デフォルトの名無しさん
07/03/02 12:02:14
0になるだろ

391:デフォルトの名無しさん
07/03/03 00:45:07
ポインタで
char *p;
p = "ABC";
とした時の
pは"ABC"を表すのですか?
*pは何を表すのですか?

392:デフォルトの名無しさん
07/03/03 02:01:01
pは"ABC"の先頭アドレスをさす
*pは'A'を表す

393:デフォルトの名無しさん
07/03/03 03:11:04
>>392
ありがとうございます!

394:デフォルトの名無しさん
07/03/04 18:58:20
C言語系のサイトでよく見るんですが
kitty on your lap とは何なのでしょうか?
hello worldみたいなもの?

395:デフォルトの名無しさん
07/03/04 19:08:10
ぐぐっても…一番上には出てこないのか。
何番目かに引っかかる「ひざの上の同居人」ってゲームに
そういうサブタイトルがついてたんだよ。
今では陳腐に見えるけど、当時はまだまだ新鮮なコンセプトで、
一部の猫耳好きから圧倒的な支持を受けた。

396:デフォルトの名無しさん
07/03/04 19:09:23
よく見るって…そんなの使ってるの一箇所だけだろ

397:デフォルトの名無しさん
07/03/04 19:12:02
さくら、ケロちゃんと同じくらいは使われてるんじゃね?

398:デフォルトの名無しさん
07/03/04 19:15:57
あのヲタクチックなサンプルコードさえなければ
あそこは最高のサイトだと思うんだがな…

399:デフォルトの名無しさん
07/03/04 19:20:44
一昔前はプログラマ言ったらそんな奴らばかりだっただろ

400:デフォルトの名無しさん
07/03/04 19:37:35
今もだけどな

401:デフォルトの名無しさん
07/03/05 23:04:36
スレリンク(prog板:842番)
に誤爆してしまったのでこちらに再投下します。

std::string変数を空にするのに、
var=std::string("");
とか馬鹿馬鹿しいことやってるんですが、普通はどうするんでしょうか。

402:デフォルトの名無しさん
07/03/05 23:13:33
>>401
var.clear();

403:デフォルトの名無しさん
07/03/05 23:22:07
あっあありがとうございます。

404:デフォルトの名無しさん
07/04/13 09:12:41
nullと0の違いを教えてください

405:デフォルトの名無しさん
07/04/13 09:21:57
0はただのゼロだが、nullは「意味を持たない」という文脈で使われ、
その実体は必ずしもゼロではない
例えば大抵の処理系では int *p=null; と int *q=0; は等価だが、
場合によっては q はメモリの「ゼロ番地」を指しており、
実際に読み取ることができる、ということもありうる

406:デフォルトの名無しさん
07/04/13 09:33:16
とすると、大抵の処理系では、0番地とヌルポはどのようにして見分けているのですか?

407:デフォルトの名無しさん
07/04/13 09:48:57
>>404
CにもC++にもnullなんてものはない。
NULLのことなら、NULLが0なんじゃない。0がNULLなんだ。

408:デフォルトの名無しさん
07/04/13 10:13:41
>>405
いくら「はきだめ」でも、嘘はいくない。

409:デフォルトの名無しさん
07/04/13 10:58:09
>>404
C言語の定義によればどんなポインターの型にも特別な値、
すなわち 「ヌルポインター」が存在する。このヌルポインターは
他のどんなポ インターの値とも区別可能で、「いかなるオブジェクトや
関数へのポ インターと比較しても等しくなることがないことを
保証されている」。 すなわちアドレス演算子&を適用した結果が
ヌルポインターとなることもない。

C言語の定義によれば、ポインターを書くべきところに現れた定数0は、
コンパイル時にヌルポインターに変換される。すなわち初期化・代入・
比較をするときに左辺/右辺のどちらかにポインター型の変数か式が
現れたときは、コンパイラはもう一方の側の定数0がヌルポインター
を要求していることを理解し、適切なデータ型のヌルポインターの値
を産み出す。

410:デフォルトの名無しさん
07/04/14 19:12:14
C++Q&Aの2.24に
class Vehicle{
public:
virtual void startEngine()=0;
vietual ~Vehicle();
};
Vehicle::~Vehicle(){}

「そこから導出される派生クラスではstartEngine()メンバ関数を提供してはいけない。」

とあるんですが、これは使うなって事ですか?
「提供してはいけない」っていう言葉の趣旨がわからんのですが。


411:デフォルトの名無しさん
07/04/14 19:15:40
多分
s/しては/しなくては/
ではないかと。

412:デフォルトの名無しさん
07/04/14 20:41:27
ですよね。
定義しないとエラーになるんで、これは一体・・・と思ってた所です。

訳者が監修扱いになってるんで、誤訳かなぁと思ってた所です。


413:デフォルトの名無しさん
07/04/14 20:45:54
デストラクタをvirtualにしないと駄目な理由がいまいちわかりません。


414:デフォルトの名無しさん
07/04/14 20:49:42
>>413
struct Base
{
// virtual ~Base() {}
};
struct Derived : Base
{
Derived() : p(malloc(100)) {}
~Derived() { free(p); }
private:
void* p;
};

{
Base* x = new Derived;
delete x;
}

415:デフォルトの名無しさん
07/04/14 21:06:15
そこでshared_ptrですよ、と惑わしてみる

416:デフォルトの名無しさん
07/04/15 08:19:41
動的束縛(アップキャスト)を使った状態でのdeleteが駄目って事ですか?



417:デフォルトの名無しさん
07/04/15 09:42:37
float x=0.1;
exp(0.1*x)だとfloatなのにpow(0.1*x,2)だとdoubleになってしまうのは何故なのでしょうか?
pow(float(0.1*x),2)とすれば、floatになってくれるのですが、expとpowで何が違うのでしょうか?


418:デフォルトの名無しさん
07/04/15 09:49:12
んなこたーない。

つーか、何を根拠にfloatだのdoubleだの言ってるんだ?

419:デフォルトの名無しさん
07/04/15 16:40:47
まずCかC++かはっきりさせろ

420:デフォルトの名無しさん
07/04/15 16:48:26
C++です。

421:デフォルトの名無しさん
07/04/15 17:25:36
で、根拠は?

422:デフォルトの名無しさん
07/04/15 17:33:13
cmathを使っている

423:デフォルトの名無しさん
07/04/15 18:57:11
ダメだこりゃ。

424:デフォルトの名無しさん
07/04/15 19:14:06
math.hを使え

425:デフォルトの名無しさん
07/04/15 20:25:31
なんでやねん。

426:デフォルトの名無しさん
07/04/15 21:33:50
>>417
0.1 * xは、0.1がdouble型だからxもdouble型へ昇格され、全体としてもdouble型になる。
expもpowもdouble型の引数を取るものが呼ばれるはず。
そうでないならコンパイラがおかしいはず。
そもそも418も指摘しているとおりで、417自身がどうやって調べたのかも怪しいが。

ついでにいくつか言うが、float型リテラルを作るには0.1fのようにfを後置しろ。
そんな関数スタイルのキャストでも(勿論Cスタイルのも)使うな。
ここではstatic_castを使え(Boostのimplicit_castもありだ)。

427:デフォルトの名無しさん
07/04/17 13:06:00
#include <windows.h>
#include <stdio.h>


void main()
{
 double a;

 a = 2/6;
 printf("%f\n", a);
}

VC6にて上のように単純に2÷6を計算したら0が出力されます。
0.33333・・・を出したいのですがどうすればいいのでしょうか?

428:デフォルトの名無しさん
07/04/17 13:48:59
>>427
a = 2.0 / 6.0;

429:デフォルトの名無しさん
07/04/17 13:54:24
>>428
ありがとー


430:デフォルトの名無しさん
07/04/17 20:52:34
共用体が有効なときってあるの?
活用方法が見出せない。

431:デフォルトの名無しさん
07/04/17 22:11:20
>>430
確かに。職業PGだが、BigEndianとLittleEndianが混在した状況で
共用体が必要な場面は少ないと思う。実際使わないし。

組み込み系ならBEかLEかははっきりしているので
union X {
long a;
char b[sizeof(long)];
};

とかやることがあるかも。

432:デフォルトの名無しさん
07/04/17 23:37:36
領域をケチりたい場合にはよく使ったが、
最近はメモリに気を使う必要性が減ったから、
わざわざそういうことはしなくなったな。

433:デフォルトの名無しさん
07/04/18 01:02:36
union REGS は昔良く使われてたな。
今は struct sockaddr 関係で使われてたような。
sin_addrが内部の何かのdefineだった気がする。実装依存だろうけど。

434:デフォルトの名無しさん
07/04/18 11:00:22
>>430
であれば、使わなければよい。

実例としては、例えば「ICMPヘッダ union」でググるよろし。

435:デフォルトの名無しさん
07/04/21 18:03:25
freeにNULLを渡した場合の挙動は仕様として決まっていますか?
また、一般的な処理系ではどうなっているでしょうか。

436:デフォルトの名無しさん
07/04/21 18:24:28
>435
標準CではfreeにNULLを渡したときは何もしない(だから渡してもよい)
ことが保証されている。

437:デフォルトの名無しさん
07/04/30 09:05:06
32bit Windowsと64bit Windows両方で共通のコードを書きたいのですが、
int、doubleなど同じ変数型でも変数の桁数、精度がそれぞれで違うと思いますが、
これらの違いの一覧はどこかで公開されているのでしょうか?
これらはOS依存なのでしょうか?それともコンパイラ依存なのでしょうか?



438:デフォルトの名無しさん
07/04/30 10:41:58
VC++なら、
たぶん求めてるのはこの中から見つけ出せると思う。
URLリンク(msdn2.microsoft.com)(VS.80).aspx

439:デフォルトの名無しさん
07/04/30 10:49:34
intってコンピュータが64bitなら64bitになるというものじゃないのですか?

440:デフォルトの名無しさん
07/04/30 11:00:43
IP64,LP64,LLP64とかでググレ

441:デフォルトの名無しさん
07/04/30 16:20:50
if文の条件としてキーボードでaが入力されたら~ということを表したいのですが、
char c;
if((c=getchar())==a)
と言ったものを考えたのですが、
char c;
if((c=getchar())=='a') に直すべきでしょうか。
非常に稚拙な質問ですが、よくわからないので助けてください。


442:デフォルトの名無しさん
07/04/30 16:26:29
>>441
正しくコンパイルできて動くほうを選べ。

443:デフォルトの名無しさん
07/04/30 17:07:24
>>442
ごめんなさい、今出先なのでコンパイルできる環境がないもので・・・。
どうか教えていただけませんか。

444:デフォルトの名無しさん
07/04/30 17:12:29
>>443
教えるも何も >>441 からでは判別不能。エスパーの召喚が必要だ。
コンパイルできない環境で知る必要も無いだろう。帰ってからゆっくり試せ。

445:デフォルトの名無しさん
07/04/30 19:00:38
>441
前者は、入力した文字を 変数 a の内容と比較している。
後者は、入力した文字が a という文字かどうかを判定している。
さあ、選べ。

446:デフォルトの名無しさん
07/05/01 01:23:21
>>445
トークンa
'a'という整数

447:デフォルトの名無しさん
07/05/01 07:40:59
>441
ついでにgetchar()の戻り値、文字リテラルの型はintだからchar c;ではなくint c;
とすべき

448:447
07/05/01 07:42:04
>文字リテラルの型はint
Cの場合ね。

449:デフォルトの名無しさん
07/05/06 19:11:31
下記のファイルの3列目を読み込んで配列に格納したいです。
-----
1,2,3,4
5,6,7,8
9,8,7,6
5,4,3,2
-----

数値はカンマで区切られています。
どうやったら a[0]=3, a[1]=7, a[2]=7, a[3]=3
というふうに格納できるでしょうか?
a[0][2]=3, a[1][2]=7, a[2][2]=7, a[3][2]=3
でも構いません。よろしくお願いします。

450:デフォルトの名無しさん
07/05/06 19:12:13
宿題は宿題スレへ

451:デフォルトの名無しさん
07/05/06 19:19:57
>>449
適当でいいのなら fgets で 3 列目まで読み込んでから
sscanf(buf, "%d,%d,%d,%d", &a[0], &a[1], &a[2], &a[3]);
みたいに。

真面目にやるなら strtok とか、コンマを strchr で探して切り捨てたりしてから、
atoi とか。

452:デフォルトの名無しさん
07/05/06 19:31:52
一行読み込むごとに
sscanf(buf, "%d,%d,%d,%d", &dummy, &dummy, &a[i], &dummy);
でいいじゃん

453:デフォルトの名無しさん
07/05/06 20:42:28
普通に %*d つかえよw

454:デフォルトの名無しさん
07/05/06 20:45:02
あ、三列目ってそっちか。

455:449
07/05/06 20:47:58
>>451-454
とくに宿題ではないのでここに書かせてもらってます。
型は決まっているのでsscanfでできました。
ありがとうございました。

456:デフォルトの名無しさん
07/05/07 00:21:59
>>453
すっかり忘れてたわー

457:デフォルトの名無しさん
07/05/07 11:33:22
>>452
で、3カラム目だけ得る目的なのに4カラム目を空読みする理由は?
#"%*d,%*d,%d"で充分。

458:デフォルトの名無しさん
07/05/07 17:30:42
>>457
上につられたってことにしといてください

459:デフォルトの名無しさん
07/05/07 23:31:13
#include <stdio.h>
#define JIJYO(x) ((x)*(x))

main()
{
int i = 1;
while(i <= 5) {
printf("結果:%d\n", JIJYO(i++));
}
}
において、実行結果は1^2,3^2,5^2の順に表示されるのですが、
何故、1^2,2^2,3^2……とならずに、i++が2回ずつ呼びだされるのでしょうか?

460:デフォルトの名無しさん
07/05/07 23:42:30
見え見えの落とし穴にはまるあなたは
きっと仲間内では天然キャラとして愛される存在なのでしょう

461:デフォルトの名無しさん
07/05/07 23:53:10
>>459
漏れも初心者なんで、あってるかどうかわからないけど。

#define JIJYO(x) ((x)*(x))

((i++)*(i++)) に展開されるんじゃないかな。

462:デフォルトの名無しさん
07/05/07 23:56:59
マクロを教える時に必ず注意される所だと思うが。

463:459
07/05/08 02:02:18
>>461
なるほど……。
ありがとうございました。

464:デフォルトの名無しさん
07/05/08 13:38:07
C++について。
問題文: f(x)=x^3(xの3乗)のdf(x)/dxのプログラムをC++で作れ。
(1≦x≦2、xは0.01ずつ増加<x(i+1)=x(i)+0.01>、そのときのf(x)の値も用いる。)

5月14日までに考えて来い!との事なので・・・
どうかご教授願いたく存じますm(_ _;)m

465:デフォルトの名無しさん
07/05/08 13:56:57
>>464
for (int x=100;x<=200;x++)
{
    cout<<(x/100.0)<<" "<<3*(x/100.0)*(x/100.0)<<"\n";
}

466:デフォルトの名無しさん
07/05/08 13:59:49
>>464
宿題スレとのマルチはお勧めしない。

467:デフォルトの名無しさん
07/05/08 15:44:46
さすが掃き溜め。

468:デフォルトの名無しさん
07/05/08 16:20:58
C++厨死ね

469:デフォルトの名無しさん
07/05/10 01:28:34
>>464
丸投げしといて、回答があれば丸写ししようなどと考えてる (らしい) 奴が
>ご教授願いたく
などとふざけた台詞を吐くお陰で、この単語に脊髄反射してしまう奴が
後を絶たないんじゃないかと思うようになって来た。

470:デフォルトの名無しさん
07/05/15 23:33:14
すいません・・・二重ポインタ**の意味がどうしてもわかりません・・・
多次元配列がどうのこうのって書いてあったけど・・・

471:デフォルトの名無しさん
07/05/16 00:30:42
>>470
ポインタのポインタで検索汁

472:デフォルトの名無しさん
07/05/16 00:45:13
ありがとうございました.二重ポインタで検索してました.

473:デフォルトの名無しさん
07/05/17 19:23:25
ぬるぽいんた

474:デフォルトの名無しさん
07/05/17 23:52:42
がっいんた

475:デフォルトの名無しさん
07/06/07 11:04:30
ropeってどんな時に使うのですか?
いまいち利点が分からないのですが。

476:デフォルトの名無しさん
07/06/07 11:19:39
>>475
URLリンク(www.oopweb.com)

個人的には、「非標準である」というデメリットしか思いつきません。

477:デフォルトの名無しさん
07/06/07 12:04:02
gccで作成した静的ライブラリとg++で作成したオブジェクトファイルを
リンクさせようとすると

undefined reference to ****

のようになります。
ライブラリの方はgccでしかコンパイルがうまく通らないのですが、
今後作成するプログラムはC++で書くため、gccでコンパイルしたものと
g++でコンパイルしたものをうまくリンクしたいのですが
何かよい解決策はないでしょうか?

478:デフォルトの名無しさん
07/06/07 12:17:22
>>477
「名前マングル」でググるよろし。
ライブラリのヘッダに手を入れていいなら
プロトタイプ宣言の先頭に

 #ifdef __cplusplus
 extern "C" {
 #endif

最後に

 #ifdef __cplusplus
 }
 #endif

を入れる。

479:デフォルトの名無しさん
07/06/07 13:12:38
while(1)
{
scanf("%d", &a);

switch (a) {
case 1:
printf("a = 1\n");
break;
case 3:
printf("a = 3\n");
break;
case 5:
printf("a = 5\n");
break;
default:
printf("others\n");
break;
}
}


これでgとか非数値を入力するとscanfが飛ばされて
defaultの所が延々流れるのですが何故でしょうか?

480:デフォルトの名無しさん
07/06/07 13:20:52
1. g の地点で scanf が失敗
2. a には何も入らないため、変数に最初に入ったゴミにより default が選択される
3. others と出力される
4. 1 に戻る

この無限ループ

481:477
07/06/07 13:22:09
なるほど、うまくいきました。ありがとうございます。

482:デフォルトの名無しさん
07/06/07 13:51:28
const int* p = new int[10];
delete[] p;

これ、エラーも警告も何も出ないんですけど、
仕様上合法なんですか?

483:デフォルトの名無しさん
07/06/07 13:59:51
>>480
なるほど、文字入力を%dの10進数指定して読み込んだら
ASCIIコードの値が格納されるかと勘違いしてました。
ていうか失敗の後再読み込みされずにgのゴミで処理されるって
scanfの仕様どうなってるんだろうかと今さらながらググってみたら
一番最初に出てくる関数だから侮っていたら書いてあることが意外と難しくてビックリでしたorz


484:デフォルトの名無しさん
07/06/07 14:15:41
>>482
const int の配列を割り当てるのも、それを解放するのも
何の問題ありません。

でも p[0] = 0; なんてするとエラーになる罠。

485:デフォルトの名無しさん
07/06/07 14:26:43
メモリの破棄には const の力は及ばない・・・ということですか。
分かりました。

486:デフォルトの名無しさん
07/06/07 15:59:10
破棄そのものは内容書き換えないからな

487:デフォルトの名無しさん
07/06/07 16:04:32
理屈は分かるけど、それでいいんかいと思わなくはないなw

void foo(const int* p) {
 delete[] p;
}

を foo(p); って呼んで、
ああ、p は foo で何の影響も受けてないよねー、と思ったら、
delete[] されてた、なんつって。

まあ、const_cast という悪魔も確かにいるけどね。

488:デフォルトの名無しさん
07/06/07 17:36:12
そんな気持ち悪いことはしないでくださいとしかなあ。

489:デフォルトの名無しさん
07/07/06 09:47:01
C言語で、文字列 str1 の先頭から1文字づつ取り出して
別の文字列 str2 に追記していく場合、
strncatを使用して

strncat(str2,&str1[i],1);

とするとstr2の内容が文字化けしてしまいます。
FedoraCore6なんですが、どうすればいいでしょうか?

490:デフォルトの名無しさん
07/07/06 09:48:11
何を入れたらどう化けたんだよ

491:デフォルトの名無しさん
07/07/06 10:01:41
>>490
(だとか)だとかを入力後、他の文字を追記するとstr2に文字化けが生じてしまいます


492:デフォルトの名無しさん
07/07/06 10:03:31
つまり、マルチバイト文字を入れたときに化けるんだな
化ける前と化けた文字を見れば一発でわかるが・・・
iはちゃんと1ずつ進めてんの?

493:デフォルトの名無しさん
07/07/06 10:05:06
マルチバイトはstrncpyの3番目が1の場合2回(UTF-8なら3回)実行しないとだめなのはわかってる?

494:デフォルトの名無しさん
07/07/06 10:07:47
半角(などを使用していたつもりだったので、
文字列内にマルチバイト文字は入っていないと思っていたのですが・・・・

sizeof("(")でもsizeof("1")でも同じ値がかえってきたのですが、"("もマルチバイトなんでしょうか?
あらかじめstrlenで文字数を数えてからiを回しています。


495:デフォルトの名無しさん
07/07/06 10:08:40
(だとか)だとかを
「だとか」じゃなくて、"("、")"のほうかよw

496:デフォルトの名無しさん
07/07/06 10:10:48
>>495
すみません、ちゃんと""つけておいたほうが良かったですね。

497:デフォルトの名無しさん
07/07/06 10:13:54
文字化けを見てみないとわからんけど、\0終端して無いからゴミがくっついてるんじゃね

498:デフォルトの名無しさん
07/07/06 10:17:24
そういや、最初にstr2は0で初期化してる?
strcat は\0のとこに追加するんだぜ。

499:デフォルトの名無しさん
07/07/06 12:01:06
str(n)cat なんていう下衆なもんは使わないことをおすすめする。

500:デフォルトの名無しさん
07/07/06 12:18:09
>>498
してませんでした。
やってみます

501:デフォルトの名無しさん
07/07/10 21:31:00
クラスにはセットとゲット以外に、
なるべくメンバ関数を作らないようにすべきですか?
それとも、どんどん関数を含めても良いのでしょうか?
思想的な質問ですが…

502:デフォルトの名無しさん
07/07/10 21:33:03
アクセサ自体ベタベタ付ける物ではない
メンバ関数・変数ともにそのクラスを表現するのに必要なものだけで良い

503:デフォルトの名無しさん
07/07/10 21:38:34
つまりメンバ関数にする意味があるもののみ含めるのが良いと、
そういうことで良いでしょうか。

504:デフォルトの名無しさん
07/07/10 21:59:27
それでおkかな。
OOには単一責任の原則と言う物があるから
基本的にクラスが持つ責任は一つだけ。
メンバ関数をその責任に応じたもののみを付けるのが良い。
無駄に責任を負うと初心者にありがちなblobアンチパターンになる。

505:デフォルトの名無しさん
07/07/11 01:28:49
class A
{
public:
  int x;
};
class B: public A
{
public:
  int y;
}:
class C: public B
{
  int z;
};

継承を習っているんですが、上のようなコードがあったとき、

int main()
{
  C object;
}

このようにクラスCのオブジェクトを生成したとすると、
int x, yの分のメモリを保持しているクラスCのオブジェクトができるんでしょうか?



506:デフォルトの名無しさん
07/07/11 01:35:06
もう一つ質問なんですが

class A
{
  int x;
};
class B: public A
{
public
  int y;
};
int main()
{
  A* p;
  p = new B;
}

このようにクラスA型のポインタでクラスBの領域を動的確保した場合、
Bのオブジェクトができるのですか?
それともAのオブジェクトができるのでしょうか?


507:デフォルトの名無しさん
07/07/11 01:35:08
>>505
うん。もちろん z もね。

508:デフォルトの名無しさん
07/07/11 01:37:23
>>507
ありがとうございます!!


509:デフォルトの名無しさん
07/07/11 01:38:42
>>506 B

510:デフォルトの名無しさん
07/07/11 01:40:07
>>509
ありがとうございます!
これで今ある疑念が解消されました!


511:デフォルトの名無しさん
07/07/11 01:54:21
解消されたと言った手前、いきなりですが
>>506の場合において、生成されたクラスBのオブジェクトが持つint yにアクセスする手段ってありますか?
ポインタはクラスA型なので、アロー演算子を使っては呼び出せないですし…
もしかして不可能ですか?


512:デフォルトの名無しさん
07/07/11 02:09:52
>>511
A* が指してるオブジェクトが本当に B だと確信できるなら static_cast で
B* に変換してアクセスできる。ただし、行儀のいいコードではない。

513:デフォルトの名無しさん
07/07/11 02:14:45
いや普通ダウンキャストだろ

514:デフォルトの名無しさん
07/07/11 02:25:11
static_cast でダウンキャストするわけですが何か?

515:デフォルトの名無しさん
07/07/11 05:10:25
コマンドプロンプトの履歴?をもっと多く表示させたいんです。
最初のほうの計算がきれてしまいます。

516:デフォルトの名無しさん
07/07/11 05:15:38
>>515
ウィンドウ名が書いてあるところ右クリック

プロパティ

あとはお好きにドゾー

517:デフォルトの名無しさん
07/07/11 05:22:20
>>516
そこからがわからないんですけど
バッファサイズとバッファ数を大きくすればいいのでしようか?

518:デフォルトの名無しさん
07/07/11 08:55:39
さいです

519:デフォルトの名無しさん
07/07/12 02:28:20
>>517
あー説明不足ですまん。

> バッファサイズとバッファ数を大きくすればいいのでしようか?
おk。

520:デフォルトの名無しさん
07/07/15 18:42:34

 漢字かな雑じりの string を小文字にしたいんですが,以下の方法では「認.」 が化けてしまいます.

std::string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ AB確認.";//期待する変換: abcdefghijklmnopqrstuvwxyz AB確認.
std::ctype<char> c;
c.tolower( str.begin(), str.end() );//「認.」 が化ける


 以下の方法で上手くいっているように思いますが問題ありますでしょうか?
また,もっと簡単な方法があれば御教示下さい.

for( int i=0; i < str.size(); i++)
{
  if ( _ismbblead(str[i]) )
  {
    i++;
    continue;
  }
  str[i] = tolower(str[i]);
}



521:デフォルトの名無しさん
07/07/15 21:09:48
for(i=0; N; i++){
・・・



このときの繰り返し条件Nってどういう意味になりますか?

522:デフォルトの名無しさん
07/07/15 21:11:49
Nのところが0以外なら繰り返してください、っていう意味!!!!

523:デフォルトの名無しさん
07/07/15 21:17:25
共有メモリに(キューデータ構造)を構築したいのですが
どうしたらいいのでしょうか?

524:デフォルトの名無しさん
07/07/15 21:30:25
>>523
まずは、パソコンの電源を入れる

525:デフォルトの名無しさん
07/07/15 23:02:52
>>520
wchar_t 使えば?

526:デフォルトの名無しさん
07/07/16 00:43:59
wchar_t じゃ解決にならんと思うのだが。

527:デフォルトの名無しさん
07/07/16 00:58:23
>>526
何か問題あるの?

528:デフォルトの名無しさん
07/07/16 01:47:49
>>520 で済む事なのに
わざわざ文字コード変換とかするとか、
いくらなんでも無駄すぎる。

529:デフォルトの名無しさん
07/07/16 01:53:54
>>521
Nがtrue(真)なら繰り返す
Nがfalse(偽)なら打ち切る
そして true とは 0 以外の値を持つ事であり、false とは 0 であることである。


530:デフォルトの名無しさん
07/07/16 02:18:50
>>528
お前の言うことは分かるが、もし527に対して言っているのなら、
答えになっていないぞ。
無駄かどうかはともかく、wchar_tでも解決できるのだから。

個人的にはwchar_tを使うのはありだと思う。
確かにこの例では_ismbbleadの1つで済むが、そうでない(wchar_tにしたほうが手っ取り早い)場合は結構ある。
それ以外にも利点や必要があってwchar_tを使っていると、
522程度でもwchar_tを使えばいいと思うようになってくる。
今時変換のコストなんて微々たるもの。
なんなら元データをwchar_tと同じ文字コードにすればいい。(完全に脱線したが)

ただ、std::stringとstd::wstringとの間に簡単な変換方法が無いのは痛い。

ところで、wchar_t使う方法では、やり方次第で
全角英字まで小文字になりそうな気もする。

531:デフォルトの名無しさん
07/07/16 02:22:10
L"" で初期化すれば変換なんて要らないんじゃないの?

532:デフォルトの名無しさん
07/07/16 02:29:58
wchar_t は2バイトだったり4バイトだったりするからな・・・

533:520
07/07/16 14:26:31

皆さん御解答有難う御座います.
wchar_t も検討しましたが,問題なさそうなので >>520 で行きたいと思います.
有難う御座いました.

534:デフォルトの名無しさん
07/07/19 01:28:47
int x;
std::cin >> x;

ってすると、xがint型であってもキーボードからWWWって文字列を入れたりすることができちゃうじゃないですか
これって防げませんか?


535:デフォルトの名無しさん
07/07/19 01:56:16
>>534
入力されたらどうするかを自分で決めて好きに実装すればいい。
最悪は1文字ずつ処理。

536:デフォルトの名無しさん
07/07/19 21:54:41
その方法がわかりません・・・・・

537:デフォルトの名無しさん
07/07/19 22:57:53
一旦、文字列として読み込めばいい。

538:デフォルトの名無しさん
07/07/20 00:55:38
配列と、forとかの反復処理を勉強してください。

539:デフォルトの名無しさん
07/07/20 03:37:06
わざわざ再発明させなくてもいんじゃね?っていつも思う。
てか悪い。C++は良く分からなかった。

#include <stdio.h>
main() {
   int a;
   do {
      printf("値>");
      scanf("%d",&a);
      while (getchar() != '\n') { }
   } while((a < 1) || (a > 9999));
   return 0;
}

540:デフォルトの名無しさん
07/07/20 04:07:14
>>534
fail したら clear してから string へ読み捨てれば

541:デフォルトの名無しさん
07/07/20 22:37:43
じゃあC++における標準入力って何でも文字列で読み込まないとエラー処理できないわけですか…


542:デフォルトの名無しさん
07/07/20 22:52:48
>>541
Cでも同じじゃね?
ってか、入力されるのは実際文字列であってたまたま数字だったら変換してくれてるってことでしょ。
Variantみたいな型が無い時点で>540のようにするしかないかと。

543:デフォルトの名無しさん
07/07/21 01:04:15
>>541
どうしてもっていうならテンキー以外のキーボードをつなげるな

544:デフォルトの名無しさん
07/07/21 06:29:53
人はそれを電卓と呼ぶ。

545:デフォルトの名無しさん
07/07/21 06:57:01
cin.ignore 使えば

546:デフォルトの名無しさん
07/07/21 19:06:59
URLリンク(www.kk19.net)

地球上のキーボードが全てこれだったら、
ちっとはマシな世の中になってたかもな

547:デフォルトの名無しさん
07/07/22 07:58:57
>>546
せめてリターンキーは必要だろう
CtrlとALTときたら普通はSHIFT
指五本あるのになんで三キーしかないのか


548:デフォルトの名無しさん
07/07/22 19:36:32
同時に全部押すことにしか使わないのさw

549:デフォルトの名無しさん
07/07/23 01:49:49
最近は使わないんだろうな。
NTのログインにも使わなくなったからな・・・

550:名無しさん@そうだ選挙に行こう
07/07/29 15:26:31
参照っていうのは『参照!』ってやった時にしかアクティブにならないのがファイナルアンサーですか?

551:デフォルトの名無しさん
07/07/29 21:52:37
ニッポンランゲージでOK

552:デフォルトの名無しさん
07/07/30 14:01:40
構造体を関数で参照した時に
その関数では使わない構造体の中の変数があった時
関数に構造体を渡した時に、
構造体の中の変数が多いとそれだけ何か、処理が増えてしまうのか
それとも「参照!」ってやったときだけ処理されるのかが知りたいです(´・ω・`)


553:デフォルトの名無しさん
07/07/30 14:08:55
参照渡しなら問題ない。

554:デフォルトの名無しさん
07/07/31 00:41:42
>>552
もう少し質問を簡潔にまとめてくれると助かる。
構造体を値渡しすれば関数内で利用されてない変数の有無に関わらずコピーの処理が発生する。
よって、構造体が大きくなればなるほど処理も大きくなる。
これを避けたいのであれば>>553のようにするか、ポインタ渡しすればいい。

555:デフォルトの名無しさん
07/07/31 10:51:52
>>554
日本語の拙い>552に合わせて変な用語を使わなくていいよ。
構造体のメンバを変数と言われるとどうにも理解しにくいから。
#メンバ変数と言おうと要素と言おうとその辺は構わんが。

ついでに注釈。問題の関数がインライン展開されるような代物なら、
参照渡しでなくともコピーが発生しない可能性はある。
従って、迷ったときは値渡しで充分だ。

556:デフォルトの名無しさん
07/07/31 12:05:33
謝罪を賠償しるニダ

557:デフォルトの名無しさん
07/08/01 02:10:49
>>553
ありがとう

>>554
なるほど

>>555
インラインっていうのを始めて知りました
それだとコピーされなかったりするんですね
でもとりあえず参照使っときます

558:デフォルトの名無しさん
07/08/01 02:28:35
恥ずかしい

559:デフォルトの名無しさん
07/08/01 11:49:12
迷ったらconst参照でいいよ。

560:デフォルトの名無しさん
07/09/25 00:02:25
typedef struct __blockData{
uint32_t index;
uint32_t block_size;
struct __blockData *next;
}BlockData;


struct __blockData *next;この部分なんとか
BlockData *next;って書きたいんですけど

なんとかならないっすか?

561:デフォルトの名無しさん
07/09/25 00:05:15
なんとかならないっすね

562:デフォルトの名無しさん
07/09/25 00:14:43
ええーーーやだやだ
ちょっとちょっとそんなぁ

まってくださいよ>>561さん
俺がどんな思いで12分過ごしたと思うのですか?

563:デフォルトの名無しさん
07/09/25 00:35:10
typedefはあくまで再定義
最後の行のBlockData;までいったところで初めて再定義完了になるから
自分を指す場合ちゃんとstruct __blockDataと明示しないと不可。

564:デフォルトの名無しさん
07/09/25 00:39:25
そうなのか

やけ酒するしかないな...
高校生だけどまぁいいかw

565:デフォルトの名無しさん
07/09/25 00:48:04
通報しました

566:デフォルトの名無しさん
07/09/25 00:55:34
>>560
これでいいんじゃね?

typedef struct __blockData BlockData;

struct __blockData{
uint32_t index;
uint32_t block_size;
BlockData *next;
}BlockData;

567:デフォルトの名無しさん
07/09/25 01:04:43
>>566
それはCでもC++でも無理だろ。書き忘れたがC++コンパイラなら
struct BlockData;と前方宣言する事でコンパイルをパス出来た。

568:566
07/09/25 01:08:52
あ、最後に余計な BlockData がついてた。ごめん。

>>567
最後の余計なやつだけ修正すればコンパイルできるよ。
C++ なら前方宣言も要らなくて struct BlockData { BlockData* ... ってできるよ。

569:デフォルトの名無しさん
07/09/25 01:13:22
うへー

570:デフォルトの名無しさん
07/09/25 01:17:52
void *next;

では・・・・だめですかそうですか。

571:デフォルトの名無しさん
07/09/25 01:18:50
uint_ptrと
void *

の使いわけってどうすればいいの?

572:デフォルトの名無しさん
07/09/25 01:26:04
大文字じゃなくて小文字なの?あんま見覚えが無い・・・

UINT_PTRはunsigned intだった気もするけどよく覚えていない

573:デフォルトの名無しさん
07/09/25 04:52:14
a |= b

ってどんな意味なんでしょうか?


574:デフォルトの名無しさん
07/09/25 08:13:47
>>573
a = a | b

575:デフォルトの名無しさん
07/09/25 09:29:14
>>572
UINT_PTRはC99のuintptr_t相当。

576:デフォルトの名無しさん
07/09/25 23:18:36
>>571
int と voidの使い分けは?


577:デフォルトの名無しさん
07/10/18 01:34:33
あげあげ

578:デフォルトの名無しさん
07/10/18 02:00:25
>>571

void* はどんな型のポインタが渡されるか分らない場合に使う。
(キャストしないと参照先を見れない)
int* はポインタが指し示した先がint型であるとされる。

char a = 'a'
int* p1 = (int*)&a;
void* p2 = &a;

となっているとき*p1はエラーにならんが*p2はエラーになる。
なので関数内で使用時のキャストし忘れが防げる…のではなかったかな?

579:デフォルトの名無しさん
07/10/18 08:17:44


580:デフォルトの名無しさん
07/10/18 08:32:36
すみません。書きかけを送信してしまいました。
ハード、ソフト共に同じはずなのに、別のPCではマルチプロセスのミューテックスによる排他制御が上手く働いていないみたいなのですが、
原因として何を疑えばいいのでしょうか。もう全然判んないです。

581:デフォルトの名無しさん
07/10/18 09:30:23
>>580
最小限のコードを晒す

582:デフォルトの名無しさん
07/10/19 08:27:30
『上手く働いていないみたい』といいたい気持ちはわかるが
それでは他人にはわかってもらえませんよ。

583:デフォルトの名無しさん
07/10/19 08:30:39
>>580
今まで偶然動いていただけで同期処理に漏れがあったかだな

584:デフォルトの名無しさん
07/10/19 09:13:13
>>580
うちでは上手く働いている
実力不足じゃね?

585:デフォルトの名無しさん
07/10/20 11:06:18
今まで低速シングルCPUで動いていたが
高速なPCに変えたらおかしくなったとか
クアッドコアに変えたらおかしくなったとか
そういうマルチスレッドプログラムなんかもあるんだろうな。

586:デフォルトの名無しさん
07/10/20 13:03:24
機種依存ソフトなんだろう。

587:デフォルトの名無しさん
07/10/20 16:34:20
方角が悪い。

588: ◆NpJ1Hez.TM
07/10/24 04:48:27

YES!!

589:デフォルトの名無しさん
07/10/25 17:57:28
関数ポインタテーブルとswitch-case文
ってどっちが高速なの?

どっちも個数は100

590:デフォルトの名無しさん
07/10/25 21:02:40
ポインタ

591:要は、実測あるのみ
07/10/29 12:07:48
>>589
一概には言えないが、テーブルの方が遅いことは多分ないと思う。
恐らくは、大差ないと思うが。

592:デフォルトの名無しさん
07/10/30 01:12:14
テーブルが遅くなるケースも充分考えられるよ。もちろん、メモリアクセスの速度を除いて。

単純な例だと、2つの値(分岐先)が交互に来る場合。
こういった規則的なものなら、分岐予測はほぼ必ず成功する(ものが多い)。
最近のプロセッサなら、もっと複雑なパターンでも予測出来るものもある。
一方、テーブルジャンプだと、(普通は)前回と同じ分岐をすると仮定されるので
必ず分岐ミスとなる(ものもある)。

当然、分岐予測ミスのペナルティの大きさも含めて、プロセッサによる差が大きいけどね。

593:デフォルトの名無しさん
07/11/16 19:20:28
>>589
なぜ「switch-case文より関数ポインタテーブルのが高速」だと考えるのか?

条件分岐が排除できるから

では、なぜ条件分岐が排除できると高速になるのか?

実際に実行するコードがかなり前から分かっていれば、
CPUでコードプリフェッチやアウトオブオーダー実行などの最適化を行えるから

関数ポインタテーブルを使えば実行するコードがかなり前に分かるのか?

条件にもよるが、おそらくはノー
多くの場合、直前にならないと関数ポインタの値が分からない

つまり、関数ポインタテーブルを使っても、少なくともx86の場合は速くなりません。
条件分岐なら二者択一でとりあえずどちらかの分岐コードを実行するという手もありますが、
関数ポインタだとそういうこともできないので、多くの場合ストールします。
実際に実行するコードアドレスがかなり前から分かっていて、
そのアドレスを特定のレジスタ(か不変なことが保証されているメモリ)
に保存しておくことができればストールは回避できます。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch