06/08/22 09:36:05
>>1 乙~
3:デフォルトの名無しさん
06/08/22 11:44:16
C++でスレッドってどうやんの?
4:デフォルトの名無しさん
06/08/22 11:56:38
>>3
C++の規格の範囲には、スレッドは無い。
そこで、外部のライブラリやOSが提供するAPIを使ってスレッドを操作する。
これ以上何か知りたければ、自分で検索するか、こっちで。
マルチスレッドプログラミング相談室 その4
スレリンク(tech板)
5:デフォルトの名無しさん
06/08/22 14:55:32
適切なナビゲートに感謝します。
6:デフォルトの名無しさん
06/08/25 16:07:28
正規表現について教えてください。
aaa\bbb\ccc
上記のような文字列があったとします。
これを\で区切って、配列に格納したいです。
よろしくお願いします。
あっ、あとc/c++の正規表現の本って
見つけられないんですが無いんでしょうか。
7:デフォルトの名無しさん
06/08/25 16:43:46
>>6
\で区切りたいだけなら、正規表現ではないけど、Boost Tokenizerが使える。
パス文字列ならそれに特化したBoost Filesystemもおもしろい。
8:デフォルトの名無しさん
06/08/25 18:16:47
はきだめ的にはstrtokをバンバン使えというのが正しい。
9:デフォルトの名無しさん
06/08/25 18:53:00
boost馬鹿は死んでいいよ
10:デフォルトの名無しさん
06/08/25 20:43:27
Boostがないとまともに使えないC++の方こそどうにかしてください。
11:デフォルトの名無しさん
06/08/25 23:22:57
>>6
/**
文字列を指定の文字で分割し、単語のリストを作ります
@param text 入力文字列(","や";"を含む文字列)
@param separators 分裂文字列(",.;:","\n")
@param words 出力文字列リスト
*/
bool split(const string& text,
const string& separators,
vector<string>& words)
{
int n = text.length();
int start = text.find_first_not_of(separators);
while ((start >= 0) && (start < n))
{
int stop = text.find_first_of(separators, start);
if ((stop < 0) || (stop > n)) stop = n;
words.push_back (text.substr(start, stop-start));
start = text.find_first_not_of(separators, stop+1);
}
return true;
}
12:デフォルトの名無しさん
06/08/26 00:06:19
>>10
C++ をどうにかするのが Boost の存在意義だろ。
使用制限があるわけでもないんだから、おとなしく使っとけ。
13:デフォルトの名無しさん
06/08/26 00:34:11
>>11
なぜ bool ?
14:デフォルトの名無しさん
06/08/26 00:36:44
これで6と同じ動作をすると思う。
#include <boost/tokenizer.hpp>
#include <boost/range_ex/algorithm.hpp>
bool split(const std::string& text,
const std::string& separators,
std::vector<std::string>& words)
{
typedef boost::char_separator<char> char_separator;
boost::copy(
boost::tokenizer<char_separator>(text, char_separator(separators.c_str())),
std::back_inserter(words));
return true;
}
>>12
むしろ9に言ってやってください。
15:デフォルトの名無しさん
06/08/26 01:00:53
>>11
int に string::npos が入ったら -1 になるのって、確実?
16:デフォルトの名無しさん
06/08/26 07:02:26
メモリ領域の質問です。
メモリ領域は
・プログラム領域 (ソースコードをロードする)
・静的領域 (グローバル変数など)
・スタック領域 (ローカル変数や引数などの、いわゆるワーク)
・ヒープ領域 (mallocなどで、プログラマが直接管理する)
だと理解しているのですが、この理解は正しいでしょうか。
また、正しかった場合、静的・スタック領域ではなく、
あえてヒープ領域を使ってプログラマが特にメモリを管理するのは、
どんな意図があるのでしょうか。
具体的な使い道など教えて下さい。
17:デフォルトの名無しさん
06/08/26 08:19:18
>>7
>>8
アドバイスありがとうございます。
勉強してみました。
>>11
>>14
初心者、はきだめの僕としては、コードはすごい助かります。
穴があくまでじっくり読ませていただきます。
18:デフォルトの名無しさん
06/08/26 09:16:38
>>16
大体あってます。
Unixの場合は、
・testセグメント(命令(コード)の領域)
・dataセグメント(グローバル変数・static変数の領域)
・bssセグメント(Block Started by Symbol)
・stackセグメント
・ヒープ領域
となります。
Windowsのことは良く知りません。
またヒープを使うのは、動的にメモリを取りたいという要求があるからです。
グローバル変数やstatic変数では、この要求は満たせません。また、ヒープ
領域はごく限られたサイズしかないため、ヒープを使います。
19:デフォルトの名無しさん
06/08/26 09:17:25
修正:
testセグメント
↓
textセグメント
20:デフォルトの名無しさん
06/08/26 09:34:44
>>18
餅搗け。>19以外にも間違いだらけだ。
21:デフォルトの名無しさん
06/08/26 10:15:03
>>20
指摘してください。
22:デフォルトの名無しさん
06/08/26 10:22:42
>ヒープ領域はごく限られたサイズしかないため、ヒープを使います。
マゾっ娘確定
23:デフォルトの名無しさん
06/08/26 10:33:42
指摘サンクス。
修正:
また、ヒープ領域はごく限られたサイズしかないため、ヒープを使います。
↓
また、スタック領域はごく限られたサイズしかないため、大きなメモリを扱うためにヒープを使います。
24:11
06/08/26 18:17:50
>>13
バカの一つ覚えでvoidでなく、とりあえずboolやっとけってのがある。それでかも
>>15
元ネタがパクリで覚えてない
CSVとかのコンマ区切り用で実際使ってます
25:デフォルトの名無しさん
06/08/26 19:29:13
>>20
間違いだらけって、どこが間違い?
いや、煽りじゃなくて、純粋に知りたい。
26:デフォルトの名無しさん
06/08/26 19:57:23
>>25
>20じゃないけど気づいた点を列挙。
>>>16
>大体あってます。
そうでもないでしょ。
>Unixの場合は、
>・testセグメント(命令(コード)の領域)
これは>19だね。
>・dataセグメント(グローバル変数・static変数の領域)
明示的に初期化される場合のみ。
>・bssセグメント(Block Started by Symbol)
初期化されない静的変数などはこちら。
例えば0で初期化している場合は実装依存と思われ。
>またヒープを使うのは、動的にメモリを取りたいという要求があるからです。
表現が微妙だ。
>グローバル変数やstatic変数では、この要求は満たせません。また、ヒープ
>領域はごく限られたサイズしかないため、ヒープを使います。
>23だが「ごく限られた」が相対的だなぁ。
ついでに言えば、自動変数でも動的確保できるんだが。
27:デフォルトの名無しさん
06/08/26 20:07:04
大体あってるじゃん。
28:26
06/08/26 20:14:53
そうかなぁ、スタックがワークに使われている理由を理解できていない気がするんだが。
それと、スタックのもう一つの重要な役割も書かれていないし。
#それらは末節だと言うのなら大体あっているってことだろうけどね。
29:デフォルトの名無しさん
06/08/26 20:22:12
>>28
> そうかなぁ、スタックがワークに使われている理由を理解できていない気がするんだが。
その理由とは?
> それと、スタックのもう一つの重要な役割も書かれていないし。
その役割とは?
30:デフォルトの名無しさん
06/08/26 20:33:54
再帰
関数の戻り先の保存
31:デフォルトの名無しさん
06/08/26 20:37:36
>>30
「~などのいわゆるワーク」って書いてるじゃん。
明記してないから、理解してないということ?
32:デフォルトの名無しさん
06/08/26 21:42:27
>>16
メモリ領域は環境によっていろいろ変わるから、それで完全に
正しいかどうかは判別できない。でも一般的な区分として
そういう領域があるというのは正しい。以下は一般的な話。
プログラム領域にロードされるのはソースじゃなくてコンパイルされた
マシンコードね。
ヒープを使うのは、他のやつらが不適切なとき。
静的領域を使うと、プログラム起動中はずっとメモリを握ったままになるので
大きな領域で、必要な場合と不要な場合が分かれるようなときは効率が悪い。
スタックを使えば要らなくなったときにすぐ解放できるけど、解放の順序が
必ず確保と逆順じゃないといけない。あとはサイズに制限がある環境がほとんど。
33:デフォルトの名無しさん
06/08/26 22:48:50
つまり、大体あってるってことじゃん。
34:デフォルトの名無しさん
06/08/28 16:56:19
「大体」の基じゅ(ry
35:デフォルトの名無しさん
06/08/28 17:00:19
0 点じゃないってことじゃないの?
36:デフォルトの名無しさん
06/08/28 19:35:32
3点満点で1点てところだね
どうにも割り切れない
37:16
06/08/29 16:49:19
色々議論になってしまってすみません。
メモリ領域の分類については、
現時点の自分のレベルで理解する分には
差し支えないと思いました。
malloc(ヒープ)の利用については、以下のように解釈しました。
処理中で扱う配列データの個数が不定な場合に、
その時々に応じて臨機応変に配列を用意したい。
そのためにmallocで動的に配列用のメモリを確保する。
→メモリ節約技の1つ
なるべく理解してから書こうと思ったので、
レスが遅れました。すみませんでした。
ご回答頂いた>>18、>>26、>>32さん、
その他皆様ありがとう御座います。
38:デフォルトの名無しさん
06/09/01 03:32:13
builder使ってます。
ファイルを一行ずつ読んで、printfで出力したいんですが、
「メモリが"written"できませんでした」っていうエラーになります。
配列とかポインタとか良くわかってないので、その辺がおかしいんだと思います。
また、下記の場合読み込むファイルが3行だけになってるんですが、
行数が決まってないときのlist[num]を動的に処理する方法も
どうしたらいいのがわかりません。よろしくお願いします。
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <iomanip>
int main()
{
std::ifstream fin("hoge.txt");
if(!fin){
printf("エラー");
return -1;
}
const int num = 3;
char* list[num];
for(int i=0; i<num; i++){
fin >> list[i];
}
for(int j=0; j<num; j++){
printf("%s\n",list[j]);
}
fin.close();
return 0;
}
39:デフォルトの名無しさん
06/09/01 05:02:26
char *list[num]は、ポインタの配列だが、配列の中身(=各ポインタの値)は不定。
C99とGCC以外では、配列の大きさは「定数」として、コンパイル時に決まってなければいけない。
あらかじめわからない場合は動的に確保する。(何も考えずにvectorを使うのも可)
40:デフォルトの名無しさん
06/09/01 07:48:28
>>39
アドバイスありがとうございます。
vector使って書いてみました。
vectorとstringで、文字数と行数が動的できたと思うんですが、
これで大丈夫でしょうか?ちょっと心配です。
int main()
{
std::ifstream fin("hoge.txt");
if(!fin){
printf("エラー");
return -1;
}
std::vector<std::string> list;
std::string s;
while(!fin.eof()){
getline(fin,s);
list.push_back(s);
}
for(int j=0; j<list.size(); j++){
printf("%s\n",list[j]);
}
fin.close();
return 0;
}
41:デフォルトの名無しさん
06/09/01 08:46:05
listという名前のvector...
42:デフォルトの名無しさん
06/09/01 09:25:52
「大丈夫でしょうか?」って・・・実行はしてみたの?
43:デフォルトの名無しさん
06/09/01 09:46:35
そりゃ一応動くらしきもの書いて、期待の動きはしてるようだが
はたして重大なバグが潜んでいないか心配なので添削お願いできますか
ということだろ。なんでみんなギスギスしてんの?
44:デフォルトの名無しさん
06/09/01 10:53:29
はきだめだから
45:デフォルトの名無しさん
06/09/01 11:16:17
だよな
46:デフォルトの名無しさん
06/09/01 18:55:48
まあとりあえず
・while (!fin.eof()) {} というやり方は大抵望み通りの動作にはならない
・printfにstringをそのまま渡しても大抵望みどおりの動作にはならない
とだけ
47:デフォルトの名無しさん
06/09/01 21:39:21
これで十分だろう。
while (getline(fin, s)) {
list.push_back(s);
}
48:デフォルトの名無しさん
06/09/01 22:41:15
>>46
c_str()無いですね。
正常に動いてたっぽいんですが、違うソース
貼り付けてしまったのかもしれません。
while (!fin.eof()) {} は良くないですか。
奥が深いです。
難しいので今後の課題にさせてください。
>>47
ありがとうございます。
while (getline(fin, s))というのもできるんですね。
こちらに変えてみます。
49:デフォルトの名無しさん
06/09/01 23:19:17
while (!feof()) 系のやり方の駄目具合は、
最終行に改行だけの行(空行)がないファイルや
最後に改行がないファイルを扱ってみるとわかる。
なぜそうなるかは、feof()の仕組みを考えながら動きを追ってみるとよい。
もちろん、fin.eof()でも同じ。
50:デフォルトの名無しさん
06/09/01 23:29:51
Cのfeof()が立つのは、ファイルを読んだ後。
~~~~~~~~~~~~~~~~~~~~~~
BASICとは違うのです。
51:デフォルトの名無しさん
06/09/02 00:13:19
クララが立つのはいつ?
52:デフォルトの名無しさん
06/09/02 00:27:24
においのいい草を食わせた後
53:デフォルトの名無しさん
06/09/03 01:29:21
>>49
>>50
詳しくありがとうございます。
こういうのって、経験して覚えていくんでしょうか。
覚えることがいっぱいあって大変です。
54:デフォルトの名無しさん
06/09/04 05:53:30
すごい簡単なことなんですが、ifの条件ってintだと、
0はfalseでそれ以外はtrueっていうことでよかったでしょうか。
-10~10までやってみました。
自分で関数作るときに-1をfalseにしてたんですが、
ほかの人がみたら変に思われますか?
#include <stdio.h>
for(int i = -10; i<10 ; i++){
if(i){
printf("%dはtrue\n",i);
}else{
printf("%dはfalse\n",i);
}
}
55:デフォルトの名無しさん
06/09/04 05:59:34
確認画面見ようと思ったら
書き込まれてしまいました。
コード、段落とかint main()とか抜けててすみません。
56:デフォルトの名無しさん
06/09/04 06:09:48
>>54
> すごい簡単なことなんですが、ifの条件ってintだと、
> 0はfalseでそれ以外はtrueっていうことでよかったでしょうか。
良い。
> 自分で関数作るときに-1をfalseにしてたんですが、
> ほかの人がみたら変に思われますか?
非負値を返す関数のエラーとして負値を返す事はある。
getchar の EOF とか。
真偽値しか返さない場合は、偽の場合 0 を返すのが当然。
真の方に関しては、何を返すかは case by case だが、
普通は 1 を返したのでいい。
is 系関数とか、真の時 1 以外の値も返す実装の場合もあるけど、
これは高速化の為にそうしてるだけ。
まあどちらにしろ、非 0 を返すのが当然。
C++ なら普通は bool 型にして true/false を返すけど。
57:デフォルトの名無しさん
06/09/04 06:29:01
さっそく、お返事ありがとうございます。
勉強始めたばかりなんですが、本でエラーのとき
return -1っていうのがあったような気がして、
-1にしてたんですが、if文書いてて「あれ」っと思いました。
いろんな種類のエラーを返す複数のエラー処理を
してたのも知れません。
0が偽で1が真ですか。了解しました。
58:デフォルトの名無しさん
06/09/04 09:44:59
>57
「エラーを返す」と「偽を返す」の違いを考えてみよう
59:デフォルトの名無しさん
06/09/04 21:24:03
エラーの内容が複数ある場合は、
0 を正常として、他の値をエラーとするね。
60:デフォルトの名無しさん
06/09/04 21:31:23
俺は0をエラー、1を正常にして、エラー番号をポインタでもらった引数に入れる。
61:デフォルトの名無しさん
06/09/04 21:41:19
そういう実装も見るね。
62:デフォルトの名無しさん
06/09/04 23:23:19
UNIX系で 0=OK、 1、2、3、4=エラーって見かける
63:デフォルトの名無しさん
06/09/04 23:28:30
DirectX も D3D_OK(0) が正常で他がエラーとか。
64:デフォルトの名無しさん
06/09/04 23:30:30
質問です。
std::vector<std::vector<int> > array;
とある場合、clearをする場合は
array.clear();
を呼ぶだけでメモリは解放されるのですか?
それともループでまわしながら解放しなければいけませんか?
65:デフォルトの名無しさん
06/09/04 23:37:51
>>64
array.clear() でいいよ。ループは要らない。
66:64
06/09/04 23:54:11
>65
どうもありがとうございます。
助かりました。
67:デフォルトの名無しさん
06/09/05 00:04:00
ちょっとクラスについて質問です。
入門用の本とかを見ると、C++のクラスは
Javaで言うJavaBeansみたいな使い方ばかり書いてあるけど、
関数の塊のようなクラスは、普通作らないものなのでしょうか?
単純にヘッダをインクルードして関数を呼び出すものなのか、
それとも関数群をクラスにして、そこから呼び出したほうがいいのか。
悩んでおります。
68:デフォルトの名無しさん
06/09/05 00:09:48
>>67
クラスにするメリットがあるなら、そうすればいい。
Java とか関係無しに、それだけの話じゃないのか?
69:67
06/09/05 00:24:16
>>68
オブジェクト指向って言うから、オブジェクト的にしなきゃ
いけないのかなぁ、と思いまして。
好きにすりゃいい、ってことなんでしょうけど。
特にメリットもなく、関数全部クラスにしたようなプログラムは
クソソース扱いなんだろうかと思うと、夜も寝られません。
70:デフォルトの名無しさん
06/09/05 00:34:30
>>69
何のメリットも無いのに複雑度を上げるソースは糞ソースに違いない。
71:デフォルトの名無しさん
06/09/05 00:40:54
> 関数の塊のようなクラス
俺からすれば、これはJavaが普通の関数を持てない(全てクラス内に入れないといけない)から、
仕方なくやっているという風にしか見えない。
72:67
06/09/05 00:46:56
>>69
確かにそうッスね。
ライブラリとして、クラスにしてまとめるのも変?
>>71
あ、僕も最初はそう思ってたけど、だんだん麻痺して、
最初にクラスありきな頭になってたかも。
73:デフォルトの名無しさん
06/09/05 00:54:51
その関数群が共通となるデータを持たないのなら、クラスにする必要ないでしょ。
まぁ、共通のデータ構造を持っているならネームスペースに放り込んじゃえばいいしね。
74:デフォルトの名無しさん
06/09/05 08:13:31
あるフォルダのどんどん増えていく複数のテキストファイルを圧縮するって
いうアプリを作りたいのですが質問です。
複数のテキストファイルを選択して、zipなどで圧縮するというのは
できると思うんですが、新しく増えたテキストファイルを圧縮ファイルと
一緒にする方法を悩んでいます。
私の頭では、下記のような手順しかできそうにありません。
①圧縮したファイルをフォルダに解凍
②新しいファイルをそのフォルダにコピー
③まとめて圧縮
ただ、この方法だと圧縮された容量の大きいファイルを
毎回、解凍、圧縮することになります。
それで、下記のようなようなことをしたいんですが
アドバイスをお願いできないでしょうか。
新しいファイルを圧縮して、それを圧縮ファイルに追加で
書き込むっていうことができれば、負担が少なくて良いかと
思っているんですがどうなんでしょうか。
また、圧縮ファイル内でもファイル名で区切れば、
全部解凍しないでも、そのファイル名での区間を
読み取って解凍すれば部分的に取り出すことができると思います。
えっと、圧縮するときも解凍するときも毎回丸々全部を
計算しないで、加えるところだけ圧縮、
読みたいところだけ解凍って言うことがしたいです。
75:デフォルトの名無しさん
06/09/05 08:16:28
>>74
やりたいことはわかった。あとは、何をやったらどんな問題が出たのかも書いてほしい。
76:デフォルトの名無しさん
06/09/05 08:18:11
>>74
使ってる圧縮フォーマットは何?
ライブラリ使って操作してるんなら、どのライブラリ?
77:デフォルトの名無しさん
06/09/05 08:25:14
>>75 それはもう書いてあるだろ。
78:デフォルトの名無しさん
06/09/05 08:38:15
>>75
>>76
すみません。実はこれから作ろうと思ってます。
ろくに調べないで質問してしまい
申し訳ございません。当方、初心者なのでこういうことが
実現可能かどうかわからず、それが知りたいということでした。
確かに、何が聞きたいのかわからない文章でした。
実現できそうということで、ひとつずつ調べて
書いてみます。
わからないことがあったら、また
よろしくお願いします。
時間掛かりそうですが、できたらコード書きます。
ありがとうございました。
79:デフォルトの名無しさん
06/09/05 08:45:23
共通アーカイブライブラリに行ってみたらどうだろう。
80:デフォルトの名無しさん
06/09/05 10:02:02
>77
m9プ
81:デフォルトの名無しさん
06/09/06 11:37:38
少なくとも、自前実装であれば、実現はできるだろう。
何かのライブラリ使うなら、マニュアルを百万回繰り返して読んでみてくれ。
俺なら、>>79の方法をとるが…。(でも、ZIPだけシェアウェアだったような希ガス…。)
うろ覚えですまんが、lzhだったら、全体のヘッダの後に、個数分の(ファイルごとのヘッダ+圧縮データ)が並んでるだけ。
だから、最後に単純にデータ付加すりゃヨロシ。
zipは知らないので、今、仕様を斜め読みしてみたが、最初のヘッダがなくて、個数分の(ファイルごとのヘッダ+圧縮データ)が並んで、
なんか、最後に変なデータ(ディレクトリツリーのデータ?)がついてるみたい。
(バイナリエディタで、zipファイルを覗いてみても、最後のあたりに、ファイル名のデータが入ってるね。)
まあ、それでも、たいした大きさじゃないので、どこかにデータ退避させれば、簡単にデータ付加できるだろ。
82:デフォルトの名無しさん
06/09/07 14:53:42
ファイルの読み込みの仕方を教えてください
PGM形式の画像を読み込みたいんですが、コメント行の読み飛ばしなどがよくわかりません。
どうやって読み込んだらいいのでしょうか?
83:デフォルトの名無しさん
06/09/07 15:01:05
>>82
つ[libpnm]
84:デフォルトの名無しさん
06/09/08 06:22:28
C++の資格って何かありますか?
85:デフォルトの名無しさん
06/09/08 07:46:02
>>82
pngじゃないのかよワロス
テキスト形式の画像フォーマットなんだ。おもしろい。
読み込み専用でいいなら、Susieのプラグインもあるみたいだね。
コメント行の最初は#になってるんだね。(改行は\n限定(\r\n不可)で。)
じゃ、最初1バイト読んで、分岐させて、次の行に逝けばいいじゃん。
ファイルから読んでるのか、メモリから読んでるのか、
また、テキスト読み込みには、何のクラス・関数使ってるのか分からんので、
これ以上は答えられない。
>>84
基本情報技術者・ソフトウェア開発技術者は持ってるので、
別の資格が欲しいってこと?
86:デフォルトの名無しさん
06/09/08 08:55:19
>>85
基本情報は取ったんだけど何とろうか迷ってる
さすがに今更サーティファイのCやJAVAなんて受ける気になれないしさ
87:デフォルトの名無しさん
06/09/08 09:14:14
資格より職務経歴
88:デフォルトの名無しさん
06/09/08 11:27:15
コールバックについて質問です。
手元の本3冊にも全く書いてないのですが
どのように書けばよいのでしょうか。
コールバック関数は普通の関数みたいなんですが、
呼び出す側の関数がどのように書くものなのかわかりませんでした。
下記は、pro2の引数がおかしいっていうエラーがでますが
呼び出した関数が実行されて、次にコールバック関数が実行、
"hello2hello"と出力されることを期待して書きました。
ネットで関数のポインタを渡すと呼ばれるって解説があったので、
ただ、priを引数に入れただけです。
これを動くようにしたいんですが、よろしくお願いします。
簡単に説明しているページなども歓迎です。
#include<stdio.h>
int pri(){
char* str = "hello";
printf("%s",str);
return 1;
}
int pri2(pri){
char* str = "hello2";
printf("%s",str);
return 1;
}
int main()
{
pri2(pri);
return 1;
}
89:デフォルトの名無しさん
06/09/08 11:35:19
>>88 URLリンク(www.google.co.jp)
90:デフォルトの名無しさん
06/09/08 13:09:32
>>89
関数ポインタで、ぐぐれば良かったですか。
見てみます。
ありがとうございました!
91:デフォルトの名無しさん
06/09/08 15:17:37
お世話になっております。
関数ポインタのページいくと、コールバック関数について
触れているページもありました。
自分で作った関数を引数にして渡せるAPI関数(なかのコードがわからないブラックボックスの)
なんか見かけるんですが、ちゃんとその関数は、返り血の型、引数の型と個数が
定義されていて関数の中でポインタで呼び出されてるんですね。
ただ単に、引数にコールバック関数の名前だけを入れると
実行されるわけでは無いんですね。
普通に考えてもそんな意味のわからないルール作らないですよね。
見かけてもいきなり関数名だけ、引数に入れているので今まで
意味がわかりませんでした。
と思ったのですが、こういう解釈でよかったでしょうか。
92:デフォルトの名無しさん
06/09/08 18:34:13
>>91
解釈と感想がごっちゃになっててよくわからん。
きっと君自身ごっちゃになっているのだろうね。
先ずは、他人にきちんと説明できるように整理してみたら?
93:デフォルトの名無しさん
06/09/09 14:09:42
環境
OS:windows2000
コンパイラ:Borland C++
プログラム中においてフォルダを作成して
その中にデータファイルの保存をしたいんですけど、
どうやればいいんですか?
94:デフォルトの名無しさん
06/09/09 15:06:52
つ[mkdir()]
95:93
06/09/09 17:31:20
>>94
#include<windows.h>
int main(void)
{
system("md test");
return 0;
}
これで実現することができました。
ただこれだとフォルダ名が固定になってしまいます。
そこでフォルダ名を決めれるようにするにはどうしたらよいのでしょうか?
96:デフォルトの名無しさん
06/09/09 18:26:21
>>95
mkdir()は使わんの?
どちらにしろユーザーから入力された文字列を渡せばいいじゃない。
めっちゃ基本中の基本だけど。
97:デフォルトの名無しさん
06/09/09 18:31:00
>>95
つ[sprintf()]
つ[boost::format()]
つ[_mkdir()]
つ[CreateDirectory()]
つーか、調べるってことはできんもんかね。
98:デフォルトの名無しさん
06/09/09 21:32:04
systemなんて恐ろしい関数をよく使う気に
99:デフォルトの名無しさん
06/09/10 14:20:44
まあ確かに普通はあまり使わんかな。
外で何されてもわかんないもんなー。
100:デフォルトの名無しさん
06/09/10 20:58:47
現在ポインタ及びリスト構造の学習中で
tagData * EraseNext(tagData *p);
こういう文を見かけたのですが、どういう意味かわかりません
tagdata * の”*”はどういう意味でしょうか?
101:デフォルトの名無しさん
06/09/10 21:18:35
>>100
仮引数と同じ、tagDataへのポインタ。としか言いようがない。
102:デフォルトの名無しさん
06/09/11 10:12:05
ポインタの学習中でその質問はないだろー
103:デフォルトの名無しさん
06/09/11 10:33:44
×学習中
○たった今学習を始めたところ
104:デフォルトの名無しさん
06/09/11 15:33:01
たとえば、(tagData* p)と、(tagData *p)を別物と思ってるとか。
105:デフォルトの名無しさん
06/09/11 17:51:29
初心者以前のレベルの質問なのでこちらにきました。
telnetのクライアントの送受信の並列処理(マルチスレッド)について質問です。
telnetクライアント並列処理(親スレッドは受信、子スレッドは送信)を
実装することは、どういうことができるようになることなのでしょうか?
受信と送信のスレッドが起動していて、受信も送信もどちらでもできて、
単純な"送信→受信"だけじゃなくて、
「接続が確立したらいきなり"受信だけ"とか"受信→送信"というのもできる」ように
なることをいうのでしょうか?
サーバーの場合は、親スレッドがアクセプトして、
子スレッドを作って処理をさせることによって、
「複数のクライアントを相手することができる」というのは勉強しました。
よろしくお願いします。
106:デフォルトの名無しさん
06/09/11 18:14:08
>>105
送信が連続している状況でも安定して受信できる。
telnetのプロトコルはチャットほど単純じゃないから敢えてそうすることもあるんでないかな?
107:デフォルトの名無しさん
06/09/11 21:15:07
>>106
ありがとうございます。
>送信が連続している状況でも安定して受信できる。
スレッドがたくさん作られるということでしょうか?
スレッドだとちょっと複雑で自分的に難しいので、マルチプロセスで考えさせてください。
以下かなり省略した物になりますがコードです。
if(pid>0){
//親プロセス
while(1){
//受信処理
}
//シグナル送信、プロセス終了の処理
}
else if(pid=fork()){
//子プロセス
while(1){
//入力と送信処理
}
//シグナル送信、プロセス終了の処理
}
サーバーの場合、たくさんのプロセスが作られることになると思いますが、
上記のコードの場合は、親と子2つしかプロセスが作られないことになりますでしょうか?
アプリケーションを起動すると"標準入力から送信"、"受信"この2つのプロセスが起動して同時にできるだけ。
送信を連続でした場合、受信は並列ではなく、送信した命令の順番どおり受信することになるでしょうか?
長文すみません。変なところあると思いますので
ご指摘ください。補足させていただきます。
よろしくお願いします。
108:デフォルトの名無しさん
06/09/12 01:46:54
>スレッドがたくさん作られるということでしょうか?
いいえ。
>上記のコードの場合は、親と子2つしかプロセスが作られないことになりますでしょうか?
はい。
>送信を連続でした場合、受信は並列ではなく、送信した命令の順番どおり受信することになるでしょうか?
サーバの御心次第です。
telnetプロトコルもそうだが、例えば標準入出力をみても必ずしも対になっていないことに注意。
109:デフォルトの名無しさん
06/09/12 08:23:15
>>108
ずばりの回答ありがとうございます。
すっきりできました。
110:デフォルトの名無しさん
06/09/22 03:42:09
pthread_createで複数スレッドを作ったときの
プロセス内のスレッドの数が知りたいんですが方法
ありますでしょうか。
よろしくお願いします。
111:デフォルトの名無しさん
06/09/24 01:24:23
linuxのfork+execについて質問です。
下記のコードは10回繰り返し、execvを繰り返して、
プロセスが生成できなかったときは、もう一度繰り返したいため
失敗したときに、i--;してます。
・このコードでエラーのときの処理できているか確認したいのですが、
プロセス生成をわざと失敗するようにすることできるでしょうか?
・i--で繰り返しの処理はできてるでしょうか?
for(i=0;i<10;i++){
//子プロセスの生成
if((pid=fork())==0){
execv(path,opt);
}else if(pid>0){
//親プロセス
}else{
//子プロセス生成失敗の時はiを一つ減らして繰り返し
i--;
}
}
112:デフォルトの名無しさん
06/09/24 03:10:28
>>111
実験してみたいだけならこんなマクロでも用意すればよろしかろ。
#define myFork(x) (fgetc(stdin) != (x) ? fork() : -1)
#んで、fork()の代わりにmyFork('\n')とでもすればいい。
113:デフォルトの名無しさん
06/09/24 07:36:29
>>112
関数のマクロ定義ってこういうふうに使えるんですね。
はじめてみました。
ど初心者なので感動しました。
どうやって勉強していけば、こういう感覚が身につくんだろう。。。
114:デフォルトの名無しさん
06/09/24 20:28:57
「勉強」しているうちは無理。
115:デフォルトの名無しさん
06/09/25 09:28:13
君は勉強をやめたの?
116:デフォルトの名無しさん
06/09/26 00:58:06
>>115
やってることは同じでも「勉強」だと認識してやってるようなうちは芽が出ないってこと。
117:デフォルトの名無しさん
06/09/26 09:10:23
なにその理屈w
118:デフォルトの名無しさん
06/09/26 12:04:37
勉強をやめてしまうことこそ芽がしぼむだろ普通に考えて。
119:デフォルトの名無しさん
06/09/26 12:09:54
日々是勉強
120:デフォルトの名無しさん
06/09/28 10:52:48
ファイルの排他制御をしたいのですが、open()関数を使って、
ファイルディスクリプタをflockの引数に入れてロックする方法はできました。
ディスクリプタではなくて、ストリームを使って排他モードで開きたいと思ってます。
コードです。
#include <fstream>
int main(){
using namespace std;
ifstream fin;
fin.open("filepath",ios::in, filebuf::sh_none);
return 0;
}
こんなエラーが出ます。
error: `sh_none' is not a member of `std::filebuf'
URLリンク(www.codeguru.com)
こういうページが見つかったので、filebuf.sh_noneにしてみましたが
だめでした。
買ったばかりのlinuxのパソコン壊れて、現在の環境はcygwinです。
・filebuf::sh_noneはどのようにすればよいでしょうか。
・排他制御は、他にスマートで簡単な方法ありますでしょうか。
よろしくお願いします。
121:デフォルトの名無しさん
06/09/28 11:49:22
filebuf.sh_noneなんて非標準だから使えないのは別に悪く無い。
正攻法ではファイルディスクプリタで読み書きするバッファクラスを自分で作れということになるのだが、まあ面倒。
122:デフォルトの名無しさん
06/09/28 14:42:23
>>121
お返事ありがとうございます。
>filebuf.sh_noneなんて非標準だから使えないのは別に悪く無い。
非標準とかそういうこともあるんですか。知りませんでした。
URLリンク(www.kumei.ne.jp)
有名そうなページでもfilebufってでてきたので、エラーがでるのは、
自分の書き方が変だと思いこんでました。
いろいろ検索してみると、ifstreamで排他モードはできない
と書いてある掲示板の書き込みもありました。
windowsだとライブラリあるんですが、linuxだとそういうの
簡単にできるの無いっぽいです。
boostもちょっと見てみたんですが良くわからないし、
自分のスキル的にopen+flockじゃないとだめのようです。
123:デフォルトの名無しさん
06/09/28 15:04:29
実はflock()は完全ではない罠。
124:デフォルトの名無しさん
06/09/29 00:01:02
>>123
flock調べたんですが、どういうところが完全じゃないんでしょうか?
cじゃなくてperlのページなんですが、自分でファイルのある無しの
関数作るよりも、flock使うほうがいいってあったんですが。
検索していたらこういうページを発見しました。
URLリンク(www.tietew.jp)
[io]fstream <=> fd
こういうことできるってことしか読み取れませんでしたが、
1、[io]fstream で開く、
2、[io]fstream => fdでディスクリプタ取得
3、flockでロック
4、[io]fstreamで操作
っていうことができないでしょうか。
ストリームとディスクリプタがどんなものかわかって無いので、
並行して操作できるのかどうかわかりませんが。
4番目の操作が、ストリームで操作できないと、
はじめからディスクリプタで開くしかないですよね。
読んでもわからないので、とりあえずやってみるしか無いでしょうか。
125:デフォルトの名無しさん
06/09/29 06:50:45
flock()は、flock()を使わないプロセスからのアクセスを制限できないんじゃないのか?
誰もがflock()使ってアクセスする保証があるなら問題ないが。
126:デフォルトの名無しさん
06/09/29 09:43:57
それを問題あると言っちゃうのか・・・。
127:デフォルトの名無しさん
06/09/29 11:25:46
>>125
>>126
お返事ありがとうございます。
>flock()は、flock()を使わないプロセスからのアクセスを制限できないんじゃないのか?
なんかひらめいたかもしれません。
はじめfdで開いてflockします。同じプロセスならそのままfstreamでファイルを
開いて操作できそうです。
違うプロセスでもflockを呼び出さなければfstreamでファイルを開いて
操作できそうですね。実験したらflockを呼び出さなければ待機しませんでした。
fstream.openって返り値ないので、ちゃんとオープン
してるのかわからないんですが。書き込みしてみて確認してみたいと思います。
なんかflockの仕組みがやっとわかってきました。
>>124みたいなややこしいこと考えなくてもよさそうです。
○自前のflockでも他のプロセスは同じ自前のflockを、
呼び出さないとだめなので、その点はシステムコールの
flockと同じということよろしかったでしょうか?
○必要なくなってしまいましたが、[io]fstream <=> fd
の関数はどれでどのような使い方かご教示
お願いできないでしょうか。
参考になるのかわからないですが
URLリンク(www.tietew.jp)
環境が対応していないのか、わかりませんせんがいろいろ
試しても動きませんでした。
よろしくお願いします。
128:デフォルトの名無しさん
06/10/01 13:49:36
Cで、ある一定時間内に入力がなければ
次の処理に移る、ということをしたいんですが
どのように書けばいいのでしょうか。
129:デフォルトの名無しさん
06/10/01 14:01:09
一定時間内に入力が無いってどういうこと?
関数内で、tm構造体からforかwhileで時間取ってはその時間の差分とって
条件満たせば、関数を抜け出すようにしてみれば?
130:デフォルトの名無しさん
06/10/01 14:15:22
キーボードからの入力のことです。
ずっと入力待ちなるんじゃなくてしばらくしたら飛ばしたいんです。
while(時間の条件){
scanfとか; ←ここでずっと止まったりしないですかね?
}
131:デフォルトの名無しさん
06/10/01 14:24:45
標準Cでは無理だね。
「キーボードが押されたか」の検出は。
132:デフォルトの名無しさん
06/10/01 14:37:52
そうですか・・・。ありがとうございました。
133:デフォルトの名無しさん
06/10/01 14:48:47
標準Cでできないとはつまり、
WindowsならWindowsの関数、UnixならUnixの関数使えばできるよということ。
134:デフォルトの名無しさん
06/10/01 15:14:13
機種依存スレに行けばいいかも。
Windowsだったら思い切ってAPIスレへ。
135:デフォルトの名無しさん
06/10/02 01:13:41
夜遅くにすみません…
今、VC++でプログラミングしてるんですが、
ダイアログボックスから変数を持って行きたい時はどうすればいいですか?
例えば
ダイアログボックスで
次の数の二乗を算出します
とか書いてユーザに入力を求めて、そしてユーザが入力したら
その値を元に計算→出力
的な感じなんですが…
136:デフォルトの名無しさん
06/10/03 03:14:22
ヘルプを見ろ。それで全てが解決する。
137:デフォルトの名無しさん
06/10/04 22:20:22
class CDSig : public CDialog
{
// コンストラクション
public:
CDSig(CWnd* pParent = NULL); // 標準のコンストラクタ
・
・
・
以下略
------------------------------------
VCでダイアログを作成しクラスCDSigを作成したところ自動で上のようなクラスが
自動で作成されました。
標準でコンストラクタが出来ているようですが、自前でクラス内の変数を初期化する
コンストラクタを作成するにはどうしたらよいのでしょう?
名前CDSigの定義を追加すると
error C2668: 'CDSig::CDSig' : オーバーロード関数の呼び出しを解決することができません。
と怒られます。
138:デフォルトの名無しさん
06/10/05 00:05:25
>>137
その「標準のコンストラクタ」の定義を変更しろ。
139:デフォルトの名無しさん
06/10/07 14:42:09
C++で
「変数aとbの符号が同じ場合」という条件を判断する関数があれば教えてください。
自分はif ( ( a < 0 ) == ( a < 0 ) ) と書いてるのですが、あまりに非効率な気がするので...
140:デフォルトの名無しさん
06/10/07 14:49:07
a*b > 0
141:139
06/10/07 14:53:15
>>139
スミマセン
変数a,bは有効数字15ケタなんです。書き忘れました。
それでも掛け算は避けた方がいいかな~と思ってます。
142:デフォルトの名無しさん
06/10/07 15:22:13
>>141
有効数字15桁ってどんな型?
まぁ、何をもって効率とするかが未定義なのでそもそも答えようがないけど。
・コーディングの効率なら、テンプレート関数でそういう関数を一個作っておけばいい。
・実行効率なら、型ごとに大抵は符号ビットを持っているだろうからそれを見ればいい。
143:141
06/10/07 15:37:59
>>142
double型です。
符号ビットの見方を教えてください
144:デフォルトの名無しさん
06/10/07 15:41:46
IEEE754
変数(のbit)同士でxorでも取ったあと、
符号bitのみ見ればいいんじゃないかね。
145:141
06/10/07 16:00:07
1bitが符号判定に割り当てられてるのは勉強しましたが、
どうやって1bitを見ればいいのかさっぱりわかりません。
コードを書いてもらえませんか...
146:デフォルトの名無しさん
06/10/07 16:12:58
&
147:デフォルトの名無しさん
06/10/07 16:46:54
URLリンク(ja.wikipedia.org)
148:デフォルトの名無しさん
06/10/07 17:05:08
( a < 0 ) == ( b < 0 )
これが画像処理の1ピクセルごとに繰り返されるのなら
気になるかもしれんが、そうでもないならこれで十分。
double使ってるんだからそんなにシビアなものを組んでるとも
思えんし。シビアなところならdouble使うのをやめる工夫をして、
整数タイプでxorしたらいい。
もしどうしてもって言うなら>>146だけど、エンディアンには気を
つけてね。
149:デフォルトの名無しさん
06/10/07 17:12:14
つーか、パフォーマンスを期待しているならそんなところよりも他にやることが山ほどありそうだが。
150:141
06/10/07 17:20:38
>>146, 147, 148, 149
2000回ほどのループなので、計算負荷が高すぎて困っているというわけではないのですが
Cの先輩方はどのように書くのか知的好奇心から質問しました。
&も使えるように練習してみます。ありがとうございました。
151:デフォルトの名無しさん
06/10/07 17:27:28
ひとつだけアドバイスしておくが
おまえが小手先でごちゃごちゃやろうとしている方法よりも
単純な>>139のままのコードの方がが、最適化されて速くなっている可能性も十分ある。
とりあえず、何か小技を使おうとする前に
必ずアセンブラ出力を見て不満があるかどうかを判断すべき。
もちろん、それ以前に、そこまで速度を求める必要があるのか
あるいは他の部分で工夫すべき点がないのか、ということをよーーく考えるべきだが。
152:デフォルトの名無しさん
06/10/07 18:14:19
PXOR
153:デフォルトの名無しさん
06/10/08 12:42:50
( a < 0 ) == ( b < 0 )
何に使うのか知らないけど、これじゃ、ちゃんと動かない可能性ある罠。
a<0が、1返して、b<0が2返したら、!=になるし。
また、aかbのどちらかがゼロだったらどうする?(プラス扱いするならいいけど)
おいらなら、signって関数(符号に応じて-1,0,1を返す)を作って、
sign(a)==sign(b)って書く。
おそらく関数の中でif文使うから、実行効率は最悪だけど、
実行効率より、バグ鳥する時のコードの読みやすさ考えないと。
あと、どうしても効率最優先でも、何に使うのかが分からないと、最適な判別式は決められない。
154:デフォルトの名無しさん
06/10/08 12:47:33
pugya-
155:デフォルトの名無しさん
06/10/08 13:15:16
>>153
a < 0 が0か1であることは保証されている。
156:デフォルトの名無しさん
06/10/08 13:30:28
>>153
Cの比較演算の仕様を勉強しなおしてからお越しください。
157:デフォルトの名無しさん
06/10/08 14:36:37
0 か 1 になるのは C.質問者は C++ で聞いている.まあそれでも
The operands shall have arithmetic, enumeration or pointer type. The operators < (less than), > (greater
than), <= (less than or equal to), and >= (greater than or equal to) all yield false or true. The type of
the result is bool.
であって,bool 同士の == が正常に動くことも保証されてるから >>153 はアホ.
158:デフォルトの名無しさん
06/10/08 23:56:38
#include <string>
using std;;string;
struct A {
string a;
};
struct B {
string b;
B &operator=(const string &s){
b = s;
}
};
int main(void){
A a;
A aa = a; // xxx
B b;
B bb = b;
return 0;
}
---
質問なのですが、main()のxxxのところってまずいですよね?
159:デフォルトの名無しさん
06/10/08 23:59:42
別に。
160:デフォルトの名無しさん
06/10/09 00:00:15
間違えた。
B &operator=(const B &b0){
b = b0.b;
}
161:デフォルトの名無しさん
06/10/09 00:02:14
>>159
stringのメンバにポインタがないことは保障されているのですか?
162:デフォルトの名無しさん
06/10/09 00:09:21
>>161
stringはコピーコンストラクト可能かつ代入可能。
ポインタは含まれているが、コピー時は生ポインタを明け渡すわけじゃなくって
ポインタが指し示す内容をコピーする様に作られてる。
よって何の問題も無い。
163:デフォルトの名無しさん
06/10/09 00:15:33
A のデフォ代入演算子がmemcpy() だとまずいと思ったのですが。
つまり、デフォの実装が
A A::operator=(const A &a0){
memcpy(this, &a0, sizeof(A));
}
164:デフォルトの名無しさん
06/10/09 00:17:34
送信失敗、すみません。
デフォの実装が
A A::operator=(const A &a0){
memcpy(this, &a0, sizeof(A));
return *this;
}
これだと、メモリ二重開放にならないかと心配したわけです。
165:デフォルトの名無しさん
06/10/09 00:21:22
C++のクラス(=構造体)の代入処理は、各メンバの代入処理を行なう形になる。
たまたまPODメンバがまとまっていれば、memcpy()相当の実装をするかもしれない。
166:デフォルトの名無しさん
06/10/09 00:21:48
なるよ。
つーかそんな馬鹿な実装はしちゃいかん。
C++におけるmemcpyは純粋に生のバイナリデータ転送用で、メンバのコピー用じゃない。
余談だけど、thisがポインタなのはthis登場時にC++がまだ参照をサポートしてなかったからで、
thisがポインタであることを副作用的に使うコード(memcpyの引数にする、this[2]とか書く、エトセトラ)は
総じて何か勘違いしている傾向。
忌避したくらいで丁度いいぞ。
167:デフォルトの名無しさん
06/10/09 00:22:32
>>159,>>162 は間違い。自前で代入演算子をちゃんと定義してやらないと
>>163-164 で心配している通り memcpy な実装になってメモリリークする。
168:デフォルトの名無しさん
06/10/09 00:27:03
>memcpy な実装になってメモリリークする。
服脱いで正座してbasic_stringのコード読んで来い。
そんなになってたまるか。アホらしい。
169:デフォルトの名無しさん
06/10/09 00:29:57
>>168
コンパイラが
A A::operator=(const A &a0){
a = a0.a;
}
と解釈してくれるものなのでしょうか?
170:デフォルトの名無しさん
06/10/09 00:36:15
>>169
>165
171:デフォルトの名無しさん
06/10/09 00:37:51
158の場合では代入演算子ではなく、コピーコンストラクタが使われる。まあ話は変わらないが。
operator =が定義されていないときのデフォルトの実装は、
各メンバと基底クラスに代入演算子を使用したのと同じ動作をするということになっている。
また、コピーコンストラクタにも同じような規定が存在する。
162の言うとおりstd::stringが適切なコピーコンストラクタやoperator =を持っているため、
158/164の心配は杞憂だということになる。
172:デフォルトの名無しさん
06/10/09 00:38:56
ああ、ごめんみんなもう書いていたね。
173:デフォルトの名無しさん
06/10/09 00:41:26
>>168
それ全然問題の本質じゃないから。
174:デフォルトの名無しさん
06/10/09 00:43:06
>>171
>158の場合では代入演算子ではなく、コピーコンストラクタが使われる。
例が悪くてすみません、全くもってその通りでした。
>>165
これがFAでしたか。
皆様ありがとうございました。
175:153
06/10/09 00:44:02
>>155-157 そうだったのか。申し訳ない。
176:デフォルトの名無しさん
06/10/09 01:56:06
質問させてください。
ちょっと説明が下手でわかりにくいかもしれませんが、
ある関数の中で、引数の配列の長さを知ることはできるでしょうか?
例えば配列の平均を求める関数averageを作りたいとき
main関数内でa[100]とかb[80]とかを定義して、average関数に引き渡すとします。
(average(a)みたいな感じで)
このとき平均を求めるには当然、配列の要素の数が必要になるわけですが、
これをaverage関数内で求めることはできるのか?という質問です。
今は配列とともに要素の数もaverage関数に渡しているのですが、他に良い方法があったらご教授ください。
177:デフォルトの名無しさん
06/10/09 02:01:26
>>176
C++なら関数テンプレートにすればできんことはないよ。
多分↓こんな感じにすればおk
template<int array_size>
int average(const int array[array_size])
{
...
}
178:デフォルトの名無しさん
06/10/09 02:15:52
template <int N>
int average(int (&array)[N])
179:デフォルトの名無しさん
06/10/09 02:16:34
で、後は要素の数は
sizeof(array) / sizeof(array[0])
180:デフォルトの名無しさん
06/10/09 02:17:14
Nでもいいかもしれん。
181:デフォルトの名無しさん
06/10/09 02:22:05
Cなら要素数を別の引数で渡すこと以上の方法はないし、それが最も一般的だと思う。
C++なら177-178のように直接要素数をテンプレート引数にして配列への参照を引数にするのもいいが、
Boost.Rangeを使えばついでにstd::vectorなんかも渡せるようになってお得かもしれない。
ただしコードが難解になりやすいきらいがある。
#include <iostream>
#include <numeric>
#include <boost/range.hpp>
template<typename RandomAccessReadableRange>
typename boost::range_value<RandomAccessReadableRange>::type
average(RandomAccessReadableRange& r)
{
typedef typename boost::range_value<RandomAccessReadableRange>::type value_type;
return std::accumulate(boost::begin(r), boost::end(r), value_type()) / boost::size(r);
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::cout << average(arr) << std::endl;
}
182:176
06/10/09 12:05:08
なるほど…Cでは引数として渡すしかないんですね。
実はC++はまだ勉強してないんですが、これを機に勉強してみようと思います。
みなさんご丁寧にありがとうございました!
183:デフォルトの名無しさん
06/10/10 17:29:20
>>182
Cなら配列と要素数を構造体にまとめる方法もある。
配列の要素数を知りたいという問題の解決には全くなっていないが、多少管理が楽になる?
184:デフォルトの名無しさん
06/10/11 03:17:22
>>151がいいこといった。みんあ、よく聞いておけよ!
185:デフォルトの名無しさん
06/10/11 22:40:17
連想配列みたいなことをしたいのですが質問です。
以下コードです。
#include <stdio.h>
#include <string>
#include <vector>
int main(){
std::vector<std::string> data;//連想配列を想定
enum key_type {name,street,tel} _key;
//name=val_name&street=val_street&tel=val_tel
//この文字列を分割して、一番目のkeyとvalueを取り出す
std::string key="name";
std::string value="val_name";
//連想配列と仮定して代入したいのですが、
//'_STL::string' から 'key_type' へのキャストはできないというエラーがでます
data[(key_type)key]=val_name;
printf("%s",data[(type)key].c_str());
return 0;
}
文字列を分割して取り出した、key値を列挙型の値にできれば
うまく連想配列に代入できるんですが、上のようなコードで
動くようにできないでしょうか。
よろしくお願いします。
186:デフォルトの名無しさん
06/10/11 22:47:07
訂正お願いします。
×data[(key_type)key]=val_name;
○data[(key_type)key]=value;
もうちょっとはっきり違う名前にすればよかったですが、
_keyは列挙型で、keyはstd::string型です。
よろしくお願いします。
187:デフォルトの名無しさん
06/10/11 22:55:28
>>185
key_typeのname, street, telなどといった列挙子は、
コンパイル時定数で、基本的に実行時に参照する方法はない。
C++は、どちらかというと何でも静的(コンパイル時)に解決するのが特徴。
どうしても実行時に文字列から列挙子を取り出したければ、
std::map<std::string, key_type>を使えば何とかなるだろうが、
だったら、初めからそのdataをstd::map<std::string, std::string>にすればいいだろということになるわけで。
188:デフォルトの名無しさん
06/10/11 22:57:01
std::map<std::string, std::string>
189:デフォルトの名無しさん
06/10/11 23:07:25
>>187
>>188
std::map検索してみました。
連想配列みたいなことができそうですね。
ありがとうございました。
190:デフォルトの名無しさん
06/10/11 23:11:07
まあvectorでも大きめに取っておいて、push_heap()などのアルゴリズムを
使って、中にはstd::pair<std::string, std::string>を入れておけばそこそこの
速度は出るが。
191:デフォルトの名無しさん
06/10/11 23:34:12
>>189
みたいな事じゃなくてそのまんま。
192:デフォルトの名無しさん
06/10/11 23:35:36
うわっごめん
std::search_heap()ってalgorithmにはないのね。
素直にstd::sort掛けてからstd::binary_search()使うしかないか。
193:デフォルトの名無しさん
06/10/11 23:40:22
Loki::AssocVectorという手もある。
194:デフォルトの名無しさん
06/10/12 00:11:20
>>193
それ良さそうだね。今std::mapと、std::pairをぶち込んだstd::vectorを
作って比較したら、std::mapの方がstd::vectorのstd::lowerbound()を
使ったバージョンより2倍速かった。自分の環境でですが。
195:デフォルトの名無しさん
06/10/12 07:01:35
for(double t=0;t<100;t+=0.1)
{
/////
}
このようなforループで、変数tを増加させているのですが、
途中でtの値を出力すると、
10.000000000018849
のように、小さな誤差が蓄積しています。
割り算とかはではなく、単純な足し算のみしかしていないのですが、
このような誤差はどこから来るのでしょうか?
196:デフォルトの名無しさん
06/10/12 07:15:11
0.1 を有限桁数の二進数で厳密に表現することができないから。
それにしても誤差が大きいな。こっちだと 10 に対応するのは 9.9999999999999805。
理論的には 0.1 を有限桁数の二進数で表したときの誤差が 1e-16 くらいで、
これを 10/0.1 = 100 回くらい足すから 1e-14 くらいの誤差になるはずだけど。
こっちの結果はそれに適合してるんだけどなあ。
197:デフォルトの名無しさん
06/10/12 13:15:49
なにか誤差を蓄積しない方法はないでしょうか?
for(double t=0;t<1000;t+=1)
{
/////
}
とかなら、誤差が蓄積しないのでしょうか?
198:デフォルトの名無しさん
06/10/12 15:13:38
>>197
基本的に浮動小数は誤差が入ると思え。
ループ回数が重要ならループ変数は必ず整数にするのが原則。
ただし、 >>197 の例だと(おそらく)誤差は全く出ない。
詳しくは浮動小数の表現(IEEE754方式)を調べるべし。
199:デフォルトの名無しさん
06/10/15 17:42:36
windowsのマルチスレッド、排他制御についてなのですが、
こちらでも良かったでしょうか。
スレッドA,B,Cがあるとします。
このA,B,CをCriticalSectionクリティカルセッションを使うと
他のスレッドが処理していたらお互いに待つことになると思います。
そうじゃなくって、
Aが処理しているときはB,Cはストップ
Bが処理しているときは他のスレッドは待たない
Cが処理しているときは他のスレッドは待たない
ということがしたいです。
クリティカルセッション使うと、B,Cが処理しているときも
他のスレッドが待つことになってしまいます。
Aの排他制御する区間に入るまでに、B,Cは区切りのいいところまで処理して(ループの最後など)
待機をさせるというイメージです。
Aのスレッドだけコードのイメージです。
void thread_A(void){
//いろんな処理
//B,Cを区切りのいいところで、待機させる命令
EnterCriticalSection(§ion);
//排他制御
LeaveCriticalSection(§ion);
//いろんな処理
}
説明がくどくてすみません。
そもそもクリティカルセッションの話じゃないんでしょうか。
よろしくお願いします。
200:デフォルトの名無しさん
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++以前の問題ですが、どうぞアドバイスを下さい。お願いします。