07/12/11 13:44:33
>>173
>>171が
>stringのサイズと中身を順に詰めていって、読み出す時は
>サイズを読む→その分だけデータを読む、を繰り返していけばいい。
と書いてるじゃないか
176:デフォルトの名無しさん
07/12/11 13:45:33
>>174
stringは可変長領域へのポインタを持っているだけだろうからその方法じゃ無理
177:デフォルトの名無しさん
07/12/11 13:46:29
char配列経由しないでstringに格納する方法は有りますか?
178:デフォルトの名無しさん
07/12/11 13:49:08
>>177
何をどこから格納するの?
179:177
07/12/11 14:04:14
たとえばdoubleならIEEE型のバイナリを8バイトずつディスクに書き込めるじゃないですか
stringもバイナリで読み書きできない物かと
180:デフォルトの名無しさん
07/12/11 14:06:13
>>179
c_str()を使うといいよ
181:デフォルトの名無しさん
07/12/11 14:06:27
自前でchar配列を管理した方が読み書きは速そうですね
182:179
07/12/11 14:07:46
書き込むときは良いんですけど、読みこみがchar配列から変換する必要がでてしまいます
183:180
07/12/11 14:08:12
ごめん間違えた忘れて
184:デフォルトの名無しさん
07/12/11 14:08:32
あらかじめresizeしてから格納すればよいのでは?
185:デフォルトの名無しさん
07/12/11 14:10:06
リサイズで領域確保すればバイナリで読み込めますか?
186:デフォルトの名無しさん
07/12/11 14:12:11
試せ
187:デフォルトの名無しさん
07/12/11 14:14:06
速度を気にしてるようだけど、実測した上で言ってるの?
そもそもデータ構造はvector<string>でいいの?
要求を満たす代替案は考えてないの?
188:デフォルトの名無しさん
07/12/11 14:15:57
質問をまとめるとですね・・・
string型を直接ディスクに書き込んだり直接読んだり出来るかという事です
189:デフォルトの名無しさん
07/12/11 14:21:56
>>188
「直接」が曖昧
string s;
ofstream f(filename);
f << s;
fwrite(&s, sizeof(string), 1, fp);
190:デフォルトの名無しさん
07/12/11 14:23:43
>>189
その方法で読み書き出来るんですか?試してみます
stringは読み込むときにresizeしておかなくても読み込めるんですか?
確保していないところに書き込まれないですか?
191:デフォルトの名無しさん
07/12/11 14:24:31
>>188
boost::serialization
192:デフォルトの名無しさん
07/12/11 14:30:45
サンクス 出来ました
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
main(){
string s="this a pan.", t;
fstream fp;
fp.open("stringdat", ios::out | ios::binary );
fp.write( (char*) &s, sizeof(s));
fp.close();
fp.open("stringdat", ios::in | ios::binary );
fp.read( (char*) &t, sizeof(s));;
fp.close();
cout<<t;}
193:デフォルトの名無しさん
07/12/11 14:32:32
string sを長くしたら表示中にエラーが出ました やはり確保しておかないと駄目ですか
194:デフォルトの名無しさん
07/12/11 14:36:48
ありがとうございました 確保しておいたらエラー出ませんでした
195:デフォルトの名無しさん
07/12/11 14:39:32
>>192
これは良いコードw
196:デフォルトの名無しさん
07/12/11 14:50:57
でも確保するサイズがなぜか2倍以下だとエラーになります なんか不安定だしメモリ食うので安全にcharにしようと思います
197:デフォルトの名無しさん
07/12/11 14:55:50
YUV422に関して、ど素人なのですが
再生用YUV422のサンプルファイルと、
再生用サンプルプログラム等を
ダウンロード出来るサイトご存じの方いませんでしょうか?
198:デフォルトの名無しさん
07/12/11 14:59:22
>>192
うわぁ…
199:デフォルトの名無しさん
07/12/11 15:17:07
すみません
vector<string>なんですけど、既に10Mバイトくらい使用していたとして、確保されている領域も無いとき
新たにstring型を追加するときは、別の空き領域を探してきて元のデータをコピーするんでしょうか? 手間かかりますよね?
また、vector<string> str;
str.resize(100000);
と十分に確保してあれば各str[n]がどんなにメモリ食っても再配置されませんか?
200:デフォルトの名無しさん
07/12/11 15:18:39
再配置されているかどうか調べるにはどうすればいいですか? 意図的に再配置を起こさせるような実験プログラムは判りますか?
201:デフォルトの名無しさん
07/12/11 15:31:39
>>199
きっと意図しているのは str.reserve() なのではないかと思うけど、ふ
つうの実装だったらたくさんリザーブしておけばそこまでは再配置され
ないんじゃないかねえ。規格は手元にないので知らない。
メモリへの要件が厳しいようなら、自分で vector 相当のものを書いた
ほうが柔軟に対応できるかもしれない。
202:デフォルトの名無しさん
07/12/11 15:43:51
int main(){
void *p[10000];
string str;
str="This is a pan.";
p[0]=&str;
cout<< *((string*)(p[0]));
}
とやれば出来ますけど、サブルーチンでstringを追加するにはstatic 付けたらいいですか?
newで確保してもメモリから消えないんですけど値はつねに保証されますか?
203:デフォルトの名無しさん
07/12/11 15:46:45
自前で作るならstring使わないでchar配列を動的確保した方が安定しそうですね
でもサブルーチンで確保しても値は保証されますか?
204:デフォルトの名無しさん
07/12/11 15:49:12
そもそも、メンバ関数を初期化という概念がどこから来たのか知りたいぜ。
205:デフォルトの名無しさん
07/12/11 15:54:00
>>202の場合、pを引数で渡しても、strは消滅の可能性がありますよね だから読み込めない場合がありますよね
staticやnewで確保すればpを引数にしてデータアクセスはつねにできますか
206:デフォルトの名無しさん
07/12/11 15:57:34
>>199
全体のデータサイズよりも、文字列の個数によって方法論が決まってくるんじゃないかな。
stringの実装には色んなやり方があるけど、いずれの場合も、サイズの大きな中身はポインタで持ってる。
だから、10MB使用している状態でvectorが要素を再配置したからといって、その10MBのすべてが
せっせと大移動を繰り広げるわけではない。
たとえばvector<string>の要素数が10で、それぞれのstringサイズが1MB、合計10MBのとき、
そのあとpush_back()で再配置が起きても、移動するのは「string型そのもの」だけ。
string型自体のサイズは、せいぜい数バイトから多くても20バイト台で、これが10個コピーされるだけってことになる。
でも、「平均10バイトの文字列が100万個で10MB」となると、これの再配置は確かにコストが高いわけで、
つまりこの辺は、君がイジろうとしているデータの性質次第で、アプローチが変わってくる部分だと思う。
207:デフォルトの名無しさん
07/12/11 16:03:23
>>206 ありがとう
208:デフォルトの名無しさん
07/12/11 16:09:55
>>202,203,205
どうも基本的なC++の知識が欠如しているように見えますよ。C++の入門
書を一冊読んでみたらいかが? メモリ効率を気にするのはまだ早いんじゃ
ない?
もちろん、
void add_item(string** array, int capacity, int size) {
if (size >= capacity) return;
string str = "...";
array[size++] = &str;
}
という風にすると、array[]に入れた値は関数から抜けた時点で無効です。
static にしたら汎用性がなくなりそうなので、new でしょうね。
209:デフォルトの名無しさん
07/12/11 18:28:51
>>206
>>stringの実装には色んなやり方があるけど、いずれの場合も、サイズの大きな中身はポインタで持ってる。
>>だから、10MB使用している状態でvectorが要素を再配置したからといって、その10MBのすべてが
>>せっせと大移動を繰り広げるわけではない。
では、vector型データの参照渡しは無意味ってこと?
例えば
vector<int>& Foo(){ return hoge; }; //①
vector<int> Foo(){ return hoge; }; //②
この場合、①も②も関数を引き渡すコストは同じなの?
210:デフォルトの名無しさん
07/12/11 18:37:26
お前は何を言ってるんだ
211:デフォルトの名無しさん
07/12/11 18:40:16
>206
でもさ、vectorの再配置は、コピーコンストラクタで行うんだから、
stringの性質によっては、どっちも10MBすべて大移動になるでそ?
特に最近は、スレッドの絡みで、COWしないのが流行りだし。
212:デフォルトの名無しさん
07/12/11 19:25:24
なんか話が噛み合ってないおかーん
213:デフォルトの名無しさん
07/12/11 19:58:08
rope使えよ
214:デフォルトの名無しさん
07/12/11 21:42:35
struct point{int x,y;};
を<algonithm>でソートしたいんですが、
キーがxの順とyの順を切り替えて使いたいです
切り替えないなら
bool operator< (const node& left, const node& right){return (left.x
< right.x);}
でいいんですが、切り替える時はどういう風にオペレータを定義すればいいんでしょうか?
どちらの順にするかは各クラスによって決まっているので出来ればメンバ関数化したいです
環境はg++です
215:デフォルトの名無しさん
07/12/11 21:51:05
x, yそれぞれの比較関数作ってsortに渡せばいいじゃん
216:デフォルトの名無しさん
07/12/11 22:04:16
>>215
クラス内に書くと
operator<(const point&, const point&)' must take exactly one argument
と怒られるので仕方なくグローバル関数にしています、
上と同じ内容のオペレータをメンバ関数にするにはどうしたらいいのかサッパリでorz
217:デフォルトの名無しさん
07/12/11 22:08:54
bool operator < (const point& rhs) { return (this->x < rhs.x); }
218:デフォルトの名無しさん
07/12/11 22:50:00
age
219:デフォルトの名無しさん
07/12/11 23:37:46
>>217
'class Hoge' has no member named 'x'
オペレータ全然わかんねorz
220:デフォルトの名無しさん
07/12/11 23:41:39
pointをメンバで持ってるクラスについて、そのpointで比較したいなら、
当然、rhsの型をそのクラスにして、比較したいpoint型のメンバ変数名を
差し挟まなくちゃあいけませんよ。
221:デフォルトの名無しさん
07/12/12 00:12:25
現在、60kbyte分のメモリをmallocしてmemsetで60kbyteのサイズ分文字を格納しています。
これを、ソケット通信すると、MTUごとにフラグメント化され60kbyteの一つのデータとして
ではなく、MTUサイズ分の複数の異なるデータになってしまいます。
(途中の経路でパケットキャプチャしてオフセットフラグを確認しすべて0だった)
そこで、60kbyteのデータを一つのデータとして作成する方法を教えていただけませんか?
222:デフォルトの名無しさん
07/12/12 00:14:03
TCPは?
223:221
07/12/12 00:22:01
>>222
TCP通信かUDP通信かってことですか?
TCP通信でオプション等は何も設定していません。
質問の意図を取り違えていたらすみません。
224:デフォルトの名無しさん
07/12/12 00:47:36
64bit毎のlongの配列のデータを12bit毎に処理をして64bitの配列に戻したいのですが、
どのようにすればいいでしょうか?
環境は、windowsでcygwinのgccのC++です。
配列の数は上から与えられます。12bit毎にデータの加工をして上に返します。
一応、途中まで考えたのですが、力技しか思いつかず、凄く長くなってしまいます。
関数は以下のような形です。
bool CLASS::exe(std::vector<signed long>&din, std::vector<signed long>&dout)
{
long in_data[3];
int data_12b[16];
long size = din.size();
for(int i=0; i<size; i+=3){
data[0] = din[i];
data[1] = din[i+1];
data[2] = din[i]+2;
// ここで12bitのデータにする
// ここで12bitのデータの処理
// ここでlong3つの変数に入れる
}
225:デフォルトの名無しさん
07/12/12 00:57:22
なんで12bitなんだろう
力業しかないんじゃない?
226:デフォルトの名無しさん
07/12/12 01:04:43
>>224
signed だとシフトが安全に使えないから無理な予感。符号はどうなってんの?
227:デフォルトの名無しさん
07/12/12 01:06:41
>>216
なんでメンバ関数にしたいの?関連のあるコードだからってことなら static メンバ関数に
すればよさそうだけど。
228:デフォルトの名無しさん
07/12/12 01:21:38
>>225
よく分からないのですが、16ビット×16コのデータをまいびいて圧縮して、
12ビット×16コにしてるみたいです。
力技だと
data_12b[0] = (data[0] >> 52) & 0x0FFF;
data_12b[1] = (data[0] >> 40) & 0x0FFF;
・・・
みたいな感じになるんでしょうか?
>>226
12bitのデータに符号はないです。なので符号のbitは符号として使ってません。
関数の呼び出し部分はunsignedにできるのでそっちにしてみます。
229:デフォルトの名無しさん
07/12/12 01:34:13
12bit + パディング4bt × 16コ にしてもらえ
230:デフォルトの名無しさん
07/12/12 01:49:20
>>229
天才現る!その考えはなかったわ。
うん、そうしよう。
ありがとうございました。
231:デフォルトの名無しさん
07/12/12 02:30:00
すいませんCの質問かどうか微妙なんですが、
同じ数字を繰り返す式例えば
while(){
int num++;
a = num % 3;
}であれば012012012とaの値が変化しますよね、
これと別に0121012101210って感じで変化する数字を作り出すやり方ってありますかね?
232:デフォルトの名無しさん
07/12/12 02:34:06
>>231
3行目、aじゃなくてnumな。あとnumのスコープが狭すぎ。
int num=0;
static int array[] = { 0, 1, 2, 1 };
while() {
int a = array[ num ];
num = ( num + 1 ) % 4;
}
テーブルで変換とかどう?
1の次が0になる場合と2になる場合があるから単純なステートマシンじゃ無理かと。
233:デフォルトの名無しさん
07/12/12 02:39:43
>>232
なるほど。おっしゃるとおりテーブル使ったほうがよさげですね。
実はこれ今作ってるゲームのアニメパターンの変化部分で使うんですよ。
グラデーションみたいなアニメなんで012012みたいな循環数字(?)じゃ気に入らなくて、、、
ありがとでした!!
234:デフォルトの名無しさん
07/12/12 02:53:15
>>221
TCPなら順序制御があるけど、何が問題なの?
少なくともトランスポート層以上では正しい
データになってるだろ。
アプリ層で60kByte取得するまで待てばいいんでは?
235:デフォルトの名無しさん
07/12/12 02:58:13
>>233
三角関数使うといいんじゃね?
236:デフォルトの名無しさん
07/12/12 03:39:42
int main(){
const int C = 100;
const double PI=3.1415f;
const double K = 10.0f;
double i=0.0f;
for(int r =0;r<C;r++){
double t=0;
for(double x=1.0f;x<K ; x=x+1.0f){
t = t + sin((x* PI )/2.0f ) * (sin( x * i))/(x*x);
}
cout << static_cast<int>(round(fabs(t*(8.0f/(PI*PI))) * 2)) << endl;;
r%4==0 ? i=0.0f:i=i+PI/4.0f;
}
return 0;
}
237:デフォルトの名無しさん
07/12/12 05:07:14
>>224
どうしてunion使わないの?
238:デフォルトの名無しさん
07/12/12 07:25:38
struct Foo {
double value;
char *name;
};
int main (int argc, char *argv[]){
int i;
for(i = 1;i < argc; i = i + 2)
struct Foo test[i] = {atof(argv[i]), argv[1+i]};
とやると、
.c:13: error: parse error before 'struct'
.c:17: error: 'test' undeclared (first use in this function)
.c:17: error: (Each undeclared identifier is reported only once
.c:17: error: for each function it appears in.)
ってコンパイルエラーが出てコンパイルできないんですけれど、
どうやれば構造体を宣言できるのか分からないので教えていただけないでしょうか?
239:デフォルトの名無しさん
07/12/12 07:44:39
>>238
for(i = 1;i < argc; i = i + 2)
struct Foo test[i] = {atof(argv[i]), argv[1+i]};
↑こんなことできん。
いったい何をしたいんだ?
240:デフォルトの名無しさん
07/12/12 08:10:40
>>239
できないんですか~。
残念。
正確にやりたいことを書くと、引数に「100,りんご,200,みかん,150,バナナ」みたいなものがあります。
でも引数の数は「100,りんご,200,みかん」かもしれないし、「100,りんご」かもしれないし、もしかしたら引数がないかもしれません、
で、まず構造体を作って、
struct Foo {
double value;
char *name;
};
int i;
for(i = 1;i < argc; i = i + 2)
struct Foo test[i/0] = {atof(argv[i]), argv[1+i]};
ってできないかなぁと思って。
241:240
07/12/12 08:12:12
struct Foo test[i/2] = {atof(argv[i]), argv[1+i]};
の間違いです。
242:デフォルトの名無しさん
07/12/12 10:06:49
>>236
それはやりすぎwww
243:デフォルトの名無しさん
07/12/12 10:31:57
i/0ってw
244:デフォルトの名無しさん
07/12/12 10:44:43
>>224
要素が12bitのように振舞うvector<signed long>のラッパー
vector<signed long>に12bitずつ格納するラッパー
イテレータも実装すればいろいろ応用できるだろう
245:デフォルトの名無しさん
07/12/12 11:12:50
>>240
造体の要素ごとに入れていくか、
コンストラクタつきの構造体(クラス)にして、引数にするとかじゃね?
っていうか、やりたい事を見ると、簡単な構文解析が必要なんじゃね?
246:デフォルトの名無しさん
07/12/12 11:51:50
>>221
MTU (最大転送単位)なんだから、MTUより大きなパケットは使えません。
なんで分割されると困るの?
247:デフォルトの名無しさん
07/12/12 13:23:24
if(!a)printf("hello world");
だとaが偽(0の時)の時printfを実行するという意味でしょうか
248:デフォルトの名無しさん
07/12/12 13:31:10
そうですよ。
249:デフォルトの名無しさん
07/12/12 13:34:02
>>247の質問をエスパーするとだな
真が0以外なのに正常終了が0なのはどうしてですか
ってことだと思う
250:デフォルトの名無しさん
07/12/12 13:42:26
#include <vector>
#include <sstream>
#include <algorithm>
struct Foo {
double value;
std::string name;
};
int main (int argc, char *argv[]){
{
std::vector<Foo> FooArray;
if (argc > 1) {
std::vector<char> str(argv[1], argv[1] + strlen(argv[1]) + 1);
std::replace(str.begin(), str.end(), ',', ' ');
std::stringstream buf(&str[0]);
Foo data;
while (buf >> data.value >> data.name)
FooArray.push_back(data);
}
return 0;
}
251:デフォルトの名無しさん
07/12/12 13:44:05
>>250は>>240へのレスね。ちなみにマルチバイト文字列だとバグるかも
252:デフォルトの名無しさん
07/12/12 13:50:44
>>250
240 を見る限り、実際にカンマ区切りのテキストを入力するわけじゃなくて
argv に2つずつ並んでるみたいだよ。そんなめんどくさいことしなくていいみたい。
253:デフォルトの名無しさん
07/12/12 14:01:09
#include <vector>
#include <string>
int main(int argc, char ** argv)
{
struct valname {
double value;
std::string name;
};
std::vector<valname> valnames;
for (int ic = 1; ic < argc; ic += 2) {
valname data = {atof(argv[ic]), argv[ic + 1]};
valnames.push_back(data);
}
for (std::vector<valname>::const_iterator it = valnames.begin(); it != valnames.end(); ++it) {
std::cout << it->value << ' ' << it->name << '\n';
}
return 0;
}
254:デフォルトの名無しさん
07/12/12 15:08:21
ポインタ配列は、一つ当たり32bit使いますか?
255:デフォルトの名無しさん
07/12/12 15:12:56
>>254
環境によります。
printf("%u\n", sizeof(void *))とでもしてバイト数を割り出してみてください。
大抵の環境では、その8倍がビット数になります。
256:デフォルトの名無しさん
07/12/12 15:14:39
サンクス
257:デフォルトの名無しさん
07/12/12 15:29:40
int ch;
while((ch=getchar())!=EOF){
if(if(isalpha(ch)) analysis(ch);
}
ってなってるところで11Fってやったらanalysis(ch)に11回Fをいれるようにしたいんですどどうすればいいですか?
analysis(ch)は他の関数です。
258:デフォルトの名無しさん
07/12/12 15:38:14
>>257
ループの外で count という変数を宣言して、0で初期化
ループの中で、isdigit() だったら count = count * 10 + ch-'0'
analysis() を呼ぶところで、count の回数だけ繰り返し
259:デフォルトの名無しさん
07/12/12 15:39:51
>>257
日本語とCでOK。
260:デフォルトの名無しさん
07/12/12 16:09:33
>>258
有難うございます、やってみます。
261:デフォルトの名無しさん
07/12/12 16:59:20
const int num = 5;
int a[num];
って、C++では、配列を宣言ってできるの?
これが出来たら、配列が動的に宣言できちゃうことにならない?
262:デフォルトの名無しさん
07/12/12 17:02:34
>>261
numはコンパイル時に確定しているから静的でないといけないC++でも問題ない。
Cの場合は、ローカル変数なら同じ方法で動的に宣言できる。
263:デフォルトの名無しさん
07/12/12 17:45:57
>>261
const は動的に書き換えられないので問題ない。
264:デフォルトの名無しさん
07/12/12 17:46:57
>>262
それはC99だろ
265:デフォルトの名無しさん
07/12/12 17:49:24
>>263
でも、変数の初期化時に動的な値で初期化できないかい?
const int num = f();
みたいな感じで
266:デフォルトの名無しさん
07/12/12 17:59:55
>>265
やってみろ。話はそれからだ。
>>264
C99はCではないとでも?
267:デフォルトの名無しさん
07/12/12 19:29:48
>>266
C99はCの一つ。だから、Cの場合は云々行った場合、
それがC99だろうと、C89だろうとかまわない内容でないとまずいだろ。
ちゃんとC99である事を明記するべきだといっているんだ
268:デフォルトの名無しさん
07/12/12 19:42:03
なに、じゃあいまさらK&R形式でやれと?
構造体の直接代入は禁止かい?
269:デフォルトの名無しさん
07/12/12 19:53:47
頭の悪い絡み方だが、本人的には鋭い突き上げなんだろうね。
270:266
07/12/12 20:19:43
いや、>268は私じゃないし。
271:デフォルトの名無しさん
07/12/12 20:21:03
いまの32bitx86用商用コンパイラってだいたいC++コンパイラだろ
C99をサポートした上記用Cコンパイラって何かある?
272:デフォルトの名無しさん
07/12/12 20:27:39
取り敢えず、icc, sun studioはc99だね。
273:デフォルトの名無しさん
07/12/12 20:52:11
そもそも32bit x86用商用コンパイラ、というカテゴリそのものがアレだなー。
274:デフォルトの名無しさん
07/12/12 21:26:35
まぁC99、あんま流行ってないしな。
275:デフォルトの名無しさん
07/12/12 22:02:47
>>274
まーね、C++のCの部分だけで十分なんだけどって感じかな。
俺としては、C99サポートよりC++TR1のサポートを要求するって感じだ。
>>272
やっぱ、銭にならん、あるいは、対応要求が強くないからかなサポートしないってことかな。
276:デフォルトの名無しさん
07/12/12 22:07:35
というか、「いまの32bitx86商用Cコンパイラ」をC99対応に関わらず
列挙してみろってば。
277:デフォルトの名無しさん
07/12/12 22:19:19
ググレカス
278:デフォルトの名無しさん
07/12/12 22:49:57
C++で typedef は何の為にあるんでしょうか。
自己満足以外の使い方を教えてください。
279:デフォルトの名無しさん
07/12/12 22:54:20
移植性と書きやすさ
280:デフォルトの名無しさん
07/12/12 23:06:02
>>275
>まーね、C++のCの部分だけで十分なんだけどって感じかな。
つーか、C89から使ってる人間からすると、C99でどうしても欲しい機能って無いのよ。
むしろC99に対応するより、ISOやらJISやらにC89の規格を閲覧出来るようにしろと要求したい。
281:デフォルトの名無しさん
07/12/12 23:11:36
>>278
traitsの表現
というか自己満足してるのはお前だけ
282:デフォルトの名無しさん
07/12/12 23:27:42
typedef無かったらめっちゃ不便やん?
テンプレート使うときとか後で変更される可能性のある型使うときとか
283:デフォルトの名無しさん
07/12/12 23:31:06 BE:335659853-2BP(35)
コードコンプリート第2版とModernC++Designまじおすすめ
284:デフォルトの名無しさん
07/12/13 00:13:25
VCのうにコードな時、TEXT("もじれつ")でWSTR[]が作れるけど、
文字からWCHARを作るにはどうすればいいの?
285:デフォルトの名無しさん
07/12/13 00:24:05
おまえらC#も使えるよな?
286:デフォルトの名無しさん
07/12/13 00:24:24
TEXT('も');
_T('じ');
287:デフォルトの名無しさん
07/12/13 00:35:32
VCのうにコードな時、TEXT("もじれつ")でWSTR[]が作れるけど、
いや無理だろ
288:デフォルトの名無しさん
07/12/13 00:45:21
>>284
C/C++言語で文字列をどうこう言う前に、自然言語で正しい(意味が伝わる)文字列を
扱えるようにするのが先だとは思わないかね?
289:デフォルトの名無しさん
07/12/13 19:15:14
vector配列の解放はどうやるんですか? resizeとかで縮めるしかないですか
290:デフォルトの名無しさん
07/12/13 19:17:53
自己解決しました clear();というのがありました
291:デフォルトの名無しさん
07/12/13 19:25:20
だめだ
解放されていない
292:デフォルトの名無しさん
07/12/13 19:26:46
reserve(0);でも解放されないよ どうしたら良いんですか
293:デフォルトの名無しさん
07/12/13 19:30:50
vectorの解放ってあんましピンとこないなー。
std::vector<T>( hoge ).swap( hoge )
でシュリンクできる、ってEffectiveSTLにあったけど、
そういう話?
294:デフォルトの名無しさん
07/12/13 19:34:25
解放できましたよ 標準でついてないのが良くないですね
main(){
int n;
vector<double> a(10000000,1);
vector<double>().swap(a);
scanf("%d",&n);
}
295:デフォルトの名無しさん
07/12/13 19:37:39
>>293
作業領域でたとえば100M使っていたとして、そのあとにもプログラムが続く場合
作業領域は消したいですよね 多分サブルーチンで確保したものは戻るときに消えていると思うのですが
そうでないと消したいわけなんですが・・標準でついてないです
296:デフォルトの名無しさん
07/12/13 19:44:52
そういう意味なら、スコープ抜けたら消えるでしょ。
vectorの定義から消したい場所までをブロックで囲めば。
297:デフォルトの名無しさん
07/12/13 19:47:29
万能解放命令できたよ
template<typename T>
void clear(T& t){ T().swap(t);}
main(){
int n;
string a; a.resize(100000000);
clear(a);
vector<double> b(10000000,1);
clear(b);
scanf("%d",&n);}
298:デフォルトの名無しさん
07/12/13 19:50:30
>>296
実験してみました ちゃんと解放しますね 勉強になりました
main(){
{vector<double> b(10000000,1); Sleep(1000);}
int n; scanf("%d",&n);
}
299:デフォルトの名無しさん
07/12/13 20:00:26
でも有効範囲を括弧で括るのは紛らわしいですね 他にも適用範囲の別の物がまじっていたら困ります
明示的に解放するほうが良さそうですね
300:デフォルトの名無しさん
07/12/13 21:00:51
vcはclearで解放しなかったかな
301:デフォルトの名無しさん
07/12/13 21:23:11
C99の複合リテラルに対応しているコンパイラって何がありますか?
302:デフォルトの名無しさん
07/12/13 21:40:38
gccって更新はやいんじやないの?
303:デフォルトの名無しさん
07/12/14 00:36:56
>>299
まともにスコープ切ってれば明示的な解放(ブロック作成)が要るようになることなんて
無いと思うよ。そうとう特殊な場合でしょ。
304:デフォルトの名無しさん
07/12/14 02:17:40
ImpersonateLoggedOnUser関数による偽装ログオンについて教えてください
アドミン権限で動いてるプログラムのうち、ユーザHOGEに偽装ログオンして
動かしたいA()という関数と、アドミン権限で動かしたいB()という関数があります。
このとき、
LogonUser(..., &hToken);
ImpersonateLoggedOnUser(hToken);
A();
B();
RevertToSelf();
CloseHandle(hToken);
としてしまうと、B()までHOGE権限で動いてしまうと思っています。ので、
LogonUser(..., &hToken);
ImpersonateLoggedOnUser(hToken); A(); RevertToSelf();
CloseHandle(hToken);
LogonUser(..., &hToken);
ImpersonateLoggedOnUser(hToken); A(); RevertToSelf();
CloseHandle(hToken);
B();
とするか、
LogonUser(..., &hToken);
ImpersonateLoggedOnUser(hToken); A(); RevertToSelf();
ImpersonateLoggedOnUser(hToken); A(); RevertToSelf();
B();
CloseHandle(hToken);
とするかだと思うのですが、A()、B()が何回か繰り返し呼び出されるとき、後者のように
LogonUser()を呼ぶのは一回だけにして、LogonUser()とCloseHandle()の間に複数回の
偽装・偽装解除・A()・B()を呼び出すのは問題ないでしょうか。
多分大丈夫なんじゃとは思うのですが、そういうサンプルコードが見あたらなかったので
決めかねている次第です。どなたか教えていただけると助かります。
305:デフォルトの名無しさん
07/12/14 11:44:17
文字列リテラルにスコープってある?
char *func(){
return "Hello,World!!!";
}
てあり?
306:デフォルトの名無しさん
07/12/14 11:56:07
>>305
大蟻。
つーか、常套手段。但し、const char *を返すべき。
307:306
07/12/14 11:58:04
>>305
書き忘れた。文字列リテラル自体の生存期間はstaticと同じく、プログラム開始時から終了時まで。
308:デフォルトの名無しさん
07/12/14 12:47:11
>>306-307
サンクス
そうかconstだったな
309:デフォルトの名無しさん
07/12/14 15:35:34
スコープ(名前の有効範囲。コンパイル時にチェックされる)と
寿命(変数を置く場所がその変数のための場所である期間。実行時の話)は
別の話だぞー。
310:デフォルトの名無しさん
07/12/14 22:33:52
参考書を見ながら独学でやっているプログラミング初心者です。
どうにもわからないことがあるので質問します。
#include<stdio.h>
int main(void){
int a = 1;
int b = 0;
printf("short int型のサイズは%dバイトです。\n",sizeof(short int));
printf("int型のサイズは%dバイトです。\n",sizeof(int));
printf("long int型のサイズは%dバイトです。\n",sizeof(long int));
printf("float型のサイズは%dバイトです。\n",sizeof(float));
printf("double型のサイズは%dバイトです。\n",sizeof(double));
printf("long double型のサイズは%dバイトです。\n",sizeof(long double));
printf("変数aのサイズは%dバイトです。\n",sizeof(a));
printf("式a+bのサイズは%dバイトです。\n",sizeof(a+b));
return 0;
}
でコンパイルするとlong doublのところが10バイトになるのですが
私の持っている参考書の{やさしいC}では8バイト表記になっています。
何度も見直していますが間違いがわかりませんでした。
よろしくお願いします
311:310
07/12/14 22:40:24
動作環境はWinXP
使用コンパイラはCpadというものです。
312:デフォルトの名無しさん
07/12/14 22:41:38
型のサイズは環境によって違う。
long double は 8, 10, 16 バイトの3種類くらい見たことがある。
313:310
07/12/14 22:57:54
>型のサイズは環境によって違う。
long double は 8, 10, 16 バイトの3種類くらい見たことがある。
環境の違いがあるということも頭に入れて勉強を進めたいと思います。
ありがとうございました。
314:デフォルトの名無しさん
07/12/14 23:39:03
GCCとVCくらいしか使わん身としては
10バイトってのは珍しいね
315:デフォルトの名無しさん
07/12/14 23:52:31
コンソールで画面整形というか画面操作というか、正しい呼称はわからないのですが
例えば複数行に渡って
1111111
2222222
3333333
4444444
などと表示した後、それに被せる、ないしは消して同じ位置に出力というのは不可能でしょうか?
自分で調べてみて大量の\r\bを並べてみてもうまくいかなく今は大量の\nでごまかしごまかしやっています
316:デフォルトの名無しさん
07/12/15 00:08:05
そんなあなたに ncurses
でもwin用ってあったけ?
317:デフォルトの名無しさん
07/12/15 00:12:19
調べてみると
利用可能OS
AIX
BeOS
Cygwin
Digital Unix (aka OSF1)
FreeBSD
GNU/Linux
HPUX
IRIX
OS/2
SCO OpenServer
Solaris
SunOS
あばばば、Cygwinか、いやしかし・・
318:デフォルトの名無しさん
07/12/15 00:14:37
PDCursesってのもあるでよ。
319:デフォルトの名無しさん
07/12/15 00:15:09
cursesならある。
VCか何かだったかな・・・。
でもそれよか、そのぐらいならエスケープシーケンス有功にした方が早いかもよ。
320:デフォルトの名無しさん
07/12/15 00:21:51
エスケープシーケンスっていうと自分のところでしか結局動かないことになっちゃうような・・?
PDCurses、なかなかいいページがみつからないのでちょっと試行錯誤してきてみます
321:デフォルトの名無しさん
07/12/15 00:33:06
fseek的なのほしかぁ、ありがとう
322:デフォルトの名無しさん
07/12/15 00:43:58
enum Foo { a = 0, b = 10, };
int main()
{
Foo x = Foo(3);
}
VC71ではこれがコンパイル出来るんだけど、
Foo xが列挙型Fooにない値を取り得るというのは正しい動作?
323:デフォルトの名無しさん
07/12/15 00:46:46
結局windows.hが入ってきましたとさ
324:デフォルトの名無しさん
07/12/15 01:29:51
>>322
xは11になったろ?
325:デフォルトの名無しさん
07/12/15 02:23:22
>>324
いや、int(x) == 3だった。
326:デフォルトの名無しさん
07/12/15 07:52:18
>>314
Intel 系の CPU は浮動小数点を 10 バイトで扱ってるから別に珍しくはない。
Intel 系の環境なら、16 バイトになってても 6 バイトはパディングが入ってるだけ。普通なら。
昔は Turbo C++ とか 10 バイトだったような。
>>315
Win ならコンソール系の関数があるのは知っている。
使った事無いから目的の操作ができるかどうかは知らんが。
URLリンク(msdn.microsoft.com)
327:デフォルトの名無しさん
07/12/15 10:06:17
>>322
列挙Fooの値の範囲は
下限が0で上限が15になる。
xがその範囲の値ならFoo(x)
はOK。
328:デフォルトの名無しさん
07/12/15 14:17:34
DLLでdosコマンドを呼び出すとき、ms-dosの標準ではないアプリなどですが
全くdos画面を出さずに呼び出すにはどうしたらいいですか? エラーが出るとdos画面が出てきてしまいます
329:デフォルトの名無しさん
07/12/15 14:23:54
>>328
SetStdHandle
330:デフォルトの名無しさん
07/12/15 14:43:49
>>329
サンクス
日本語サイト検索してもヒットが少ないんですけどどうやってその知識を得たんですが? 物知りさんですね
331:デフォルトの名無しさん
07/12/15 16:57:51
ソースの行数とかクラスの数とかを計測したいのですが
何かいいソフトはないでしょうか? Linuxです
332:デフォルトの名無しさん
07/12/15 17:10:37
>>331
行数は wc でいけるでしょ。クラスの数は grep でだいたいいけそうだけど、
doxygen とか使ったほうがいいかもね。
333:デフォルトの名無しさん
07/12/15 17:11:37
最近プログラミングをはじめたのですがWindowsXP+VC2005環境でexeファイルにtxtファイルをドラッグ&ドロップして
fstreamでファイル操作する簡単なプログラムを作ろうと思ったのですが
ifstream file;
file.open(argv[1]);
こんな感じでargv[1]からファイルパスを受け取ろうとしてるのですが
平仮名片仮名がフルパスやファイル名に含まれているとエラーが出て開けません
argv[1]からフルパス受け取ると2バイト文字は扱えないのでしょうか?
ユニコード文字、マルチバイト文字の二つのコンパイルを試しましたが駄目でした。
334:デフォルトの名無しさん
07/12/15 17:17:06
受け取れる
ドラックや入力する時点で空白で分離されているのでは
335:デフォルトの名無しさん
07/12/15 17:18:51
>>332
空行やコメントのみの行を除外したり、
関数の中身のみの行数を数えたり、とか、
いろいろしたいとなると wc だけじゃ辛いかもね。
336:デフォルトの名無しさん
07/12/15 17:19:58
>>333
VC2005 の fstream には日本語ファイル開けないバグがある。
URLリンク(www.google.co.jp)
337:333
07/12/15 17:23:09
>>334 >>336
回答ありがとうございます。
VC2005特有の症状ってことですかね、検索しても全然わからないで困り果てていたので助かりました。
338:331
07/12/15 17:29:46
>>332>>335
ありがとう。なんとかなった
339:デフォルトの名無しさん
07/12/15 17:30:57
>>327
200でも-1でも0x7fffffffでもint n;Foo(n);でもコンパイル通ったよ。
ちなみにsizeof(Foo) == 4だった。
やっぱ列挙型引数でも範囲外チェックしなければいかんのかね…
340:デフォルトの名無しさん
07/12/15 18:28:20
>>339
>>327で書いたのは規格の話。
コンパイルが通ろうが実行できようが、規格上はは未定義。
つまり0~15以外の値については実装依存。
341:デフォルトの名無しさん
07/12/15 18:50:13
列挙子って、少なくとも int 以上のサイズになるんじゃなかったっけ? 規格上は。
342:デフォルトの名無しさん
07/12/15 18:51:31
規格の話してるんなら C か C++ か、章番号とか、ちゃんと示してくれ。
343:デフォルトの名無しさん
07/12/15 19:05:39
それを言うなら >340 だって
344:デフォルトの名無しさん
07/12/15 19:07:00
>>343
文盲乙
345:デフォルトの名無しさん
07/12/15 19:09:23
アンカを付けないなら誤解される事は覚悟しなきゃダメだ。
346:デフォルトの名無しさん
07/12/15 19:10:15
まあ>>342は規格の話してるんなら、って明言してるわけだし文盲乙は適当だな
347:デフォルトの名無しさん
07/12/15 19:17:16
そもそも >341 のみに対するレスか >340-341 の両方に対するレスかが不明
348:デフォルトの名無しさん
07/12/15 19:19:51
規格の話って言ってるじゃん
両方というかすべてに対してとるべきだし、本人はとられることに文句は言えないと
349:デフォルトの名無しさん
07/12/15 19:27:34
VC2005でwcoutに出力しています。
全角などが含まれているとそれ以降wcoutが動作しなくなる問題があって
>>333さんの問題と同じ原因かと思うのですが、
特定のスレッドのみC++ロケールを変更するにはどうしたらよいのでしょうか?
std::locale::global(std::locale(""));
すると全スレッドに適用されてしまうので今回は使えません
350:デフォルトの名無しさん
07/12/15 19:32:13
wcoutを使わずcoutで処理する
351:デフォルトの名無しさん
07/12/15 19:32:50
locale 関連ってホンマ実装がいい加減なコンパイラが多くて困る。
352:デフォルトの名無しさん
07/12/15 19:33:36
外国人が作っているからな゜
353:339
07/12/15 19:35:14
>>340
VCが規格違反しているわけではないってことでいいのかな?
まあどちらにしてもコンパイル通る以上対策はせなあかんということだが…
ともかくサンクス。
354:デフォルトの名無しさん
07/12/15 19:36:24
strがワイド文字のときの出力法
int n=WideCharToMultiByte(CP_ACP, 0, str, -1,NULL,0,NULL,NULL);
char *putf = new char[n+1];
n=WideCharToMultiByte(CP_ACP,0,str,-1,putf,n,NULL,NULL);
cout<<putf<<endl;
355:デフォルトの名無しさん
07/12/15 19:40:56
シャンピーとどいたー\(^o^)/
356:デフォルトの名無しさん
07/12/15 19:41:28
ごばくー/(^o^)\
357:349
07/12/15 19:53:53
cout << "うはwwwおkww";
ありがとうございます orz
358:デフォルトの名無しさん
07/12/15 20:09:37
初心者ですお願いします
何も入力されてないの(エンターーのみ)をデータとして扱うにはどうしたらいいでしょうか?
初歩的ですいません
359:デフォルトの名無しさん
07/12/15 20:15:00
>>358
scanf("%d",・・・); みたいにしてるとか?
360:デフォルトの名無しさん
07/12/15 20:26:53
getch()の戻り値はエンターの時どうなんだろ
361:デフォルトの名無しさん
07/12/15 20:32:50
シャンピーとどいたー\(^o^)/
362:デフォルトの名無しさん
07/12/15 20:33:44
ごばくー/(^o^)\
363:デフォルトの名無しさん
07/12/15 20:41:01
>>359
yes
364:デフォルトの名無しさん
07/12/15 20:45:02
エンターいれっと普通に13返ってくるな
365:デフォルトの名無しさん
07/12/15 20:45:45
>>363
int n;
char line[100];
fgets(line, sizeof(line), stdin);
if (line[0] == '\n') {
// エンターだけ
}
else {
sscanf(line, "%d", &n)
}
366:デフォルトの名無しさん
07/12/15 21:14:43
>>365
thanx
367:デフォルトの名無しさん
07/12/15 22:59:08
>>353
規格違反ではないね。実装依存だから何でもアリ。
VCの実装がそういうふうに対応しているという
だけのことだね。
368:デフォルトの名無しさん
07/12/16 05:51:11
質問です。
OSはMacOS X 104.11です。
#include <stdio.h>
int main (int argc, char *argv[]){
fprintf(stdout, "%s¥n", argv[1]);
return;
}
というプログラムを書いたのですが、
いざ実行させるときに、引数に
桜木 花道とやると、桜木 花道
桜木 花道とやると、桜木
しか出力されません。
なんとか回避したいのですが、どのようにすれば良いでしょうか?
369:デフォルトの名無しさん
07/12/16 05:55:25
半角空白は区切られる
あきらめろ
370:デフォルトの名無しさん
07/12/16 05:56:15
argv[2]
も出力する
371:デフォルトの名無しさん
07/12/16 05:59:50
ああ、マジですかorz
それって、OSのバグとかじゃなくて
C言語の文字列の表現の仕様ですかね?
半角を入れると
桜木'¥0' 花道'¥0'
ってなるんでしょうか?
372:デフォルトの名無しさん
07/12/16 06:15:23
そういうことだな
373:デフォルトの名無しさん
07/12/16 06:19:36
うはー、せっかくここまでプログラム書いて、バグつぶししていたときに、
こんな問題に出会うとは!
どうしよう。鬱だ。寝よう。
374:デフォルトの名無しさん
07/12/16 08:13:42
>>368
program "桜木 花道"
375:デフォルトの名無しさん
07/12/16 08:47:55
>>371
C言語の文字列の表現の問題というよりは、コンソールの仕様(コマンドラインに入力した文字列を
半角で引数を区切る)かな。
自分でシェルを作って、引数の区切りを半角文字以外で指示できれば argv[1] = "桜木 花道" も可能だよ。
argv[]にどういう文字列が渡されるかもC言語の規格の範疇だっけ?
376:デフォルトの名無しさん
07/12/16 09:09:48
>>375
JIS規格見てみたが、「文字列へのポインタでなければならない」としか書いてないな。
377:375
07/12/16 09:20:01
>>374に書いてあるように、わざわざ自前シェルを作らなくても
たいていのプラットフォームでは "" で囲めば事足りるね。なぜか忘れてたorz
378:デフォルトの名無しさん
07/12/16 09:40:06
>>373
program "安西 先生"
379:デフォルトの名無しさん
07/12/16 10:06:12
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[]){
if (strcmp("安西 先生", argv[1]) == 0) {
fprintf(stdout, "あきらめたら?\n");
} else {
fprintf(stdout, "%s\n", argv[1]);
}
return 0; //mainの戻り値をint指定したら戻り値返さないとコンパイルエラー
}
380:デフォルトの名無しさん
07/12/16 10:19:34
今時のコンパイラはエラーになるのか
381:デフォルトの名無しさん
07/12/16 10:23:58
>>373
> うはー、せっかくここまでプログラム書いて、バグつぶししていたときに、
> こんな問題に出会うとは!
> どうしよう。鬱だ。寝よう。
>
>>368 のプログラムでそれは大げさだろ。>>370 がまっとうな解答だと思うが。
argc に情報あるんだし。
382:デフォルトの名無しさん
07/12/16 11:42:47
VS2005MFCですが、OnKeyDown()関数で受け取ったint型のアスキーコードを、
元の文字に変換してstd::string型の変数に代入するにはどうしたらいいですか?
int n = 0x30; //キーボードの0を押下して得られるアスキーコード
nをstring型の0に変換したい
intからCString型の例は結構あちこちで、散見してるんですが・・・・
383:デフォルトの名無しさん
07/12/16 11:57:01
382です自己解決しましたがもっといい方法があったら教えてください
#include <iostream>
#include "stdio.h"
#include <string>
int main()
{
int n = 0x30;
std::string str;
str = ( char )n;
std::cout << str << std::endl;
return 0;
}
384:デフォルトの名無しさん
07/12/16 11:58:44
>>382
代入: s.assign(1, static_cast<char>(n))
変換: std::string(1, static_cast<char>(n))
385:デフォルトの名無しさん
07/12/16 12:00:25
str = static_cast<char>(n) が正解だね。これに何か不満でもあるの?
386:デフォルトの名無しさん
07/12/16 12:05:56
>>384
>>385
サンクス
387:デフォルトの名無しさん
07/12/16 16:24:32
C一通りやったつもりでいるし解説も読んだんだけど未だよくわからない、その過程過程が載っているとこでもないだろうか
int main (int argc, char *argv[]){←こいつなんですが
エントリポイントの引数ってことは解説サイト等見たところでもプログラムが実行させる時に渡されるものだというのはわかりました。
また、形態が文字列で、スペースで区切られ、argv[]の要素数がargcに入るのもわかりました。
でもその、プログラムが実行するときに渡される、という意味がさっぱりわかりません
例えばなんらかのソフトウェアをダウンロードし、自身で使うとき(ブラウザでもマルチメディアプレーヤでもなんでも)
.exeのファイルをクリックした際何かが渡っているんでしょうか?
ダブルクリックをして起動するだけですし、だとすると明示的にint argc, char *argv[]と書かなくてもいいことになってしまいそうで
すんごいこんがらがってます
int main (int argc, char *argv[]){でぐぐると解説が結構出るのですがもうさっぱりです
388:デフォルトの名無しさん
07/12/16 16:42:53
>>387
例えばアイコンにファイルをD&Dして起動した場合、
argvにはそのファイルのパスが渡される。
コマンドプロンプトから起動する場合は、
任意のオプションを文字列として渡すことができる。
389:デフォルトの名無しさん
07/12/16 16:48:55
コマンドプロンプトやファイル名を指定して実行では、
hege.exe /x /yのように実行ファイルの後に文字列(コマンドライン引数)を指定できる。
これがCのプログラムでは、mainの引数で受け取れるということ。
Windowsでは関連付け起動、実行ファイルへのドロップ&ドロップ起動などでもコマンドライン引数が使われる。
390:デフォルトの名無しさん
07/12/16 16:59:43
>>388-389
早々にありがとうございます。
つまり先ほど例に出したものだと
WebブラウザならばそいつにhtmlファイルをD&Dするとそのhtmlファイルのパスが渡り、ブラウザが起動し、そのhtmlの内容を表示するとか
マルチメディアプレーヤなら音楽ファイルをD&Dするとその音楽ファイルのパスが渡り、プレーヤが起動し、その音楽が再生されるとか
といった具合でしょうか
391:デフォルトの名無しさん
07/12/16 17:14:11
そういうこと。
ただし、ウインドウへのD&Dは全く別の仕組みなんで混同しないでね。
392:デフォルトの名無しさん
07/12/16 17:50:31
UNIX使うと良くわかる。
#include <stdio.h>
int main (int argc, char *argv[]){
int i;
printf("argc = %d¥n",argc);
for(i = 0; i < argc;i++)
printf("argv[%d]=%s¥n",i,argv[i]);
}
exit(0);
}
ちなみにここ最近でargv[]で何が出来ないこれが出来ないと質問してるのは俺!
みんなありがとう!
393:デフォルトの名無しさん
07/12/16 17:53:31
returnいらないの?exitの定義知らないんであれだけど
394:デフォルトの名無しさん
07/12/16 18:04:39
exit()使ってるのにstdlib.hをインクルードしてないな。
ってか普通は return 0; だろ。
395:デフォルトの名無しさん
07/12/16 18:06:46
つかエスケープ文字が全角だったり
396:デフォルトの名無しさん
07/12/16 19:49:45
C++の入門書をやり終えました。
ですがいまいち、クラスの利点がわかりません。
部品化して便利になるというイメージはあるのですが。
まだC言語っぽい書き方をしてしまいます(C++っぽい書き方もいまいちわかりませんが)。
クラスの利点やC++の書き方について書かれた書籍ってありますか?
397:デフォルトの名無しさん
07/12/16 20:14:03
>>396
>クラスの利点がわかりません。
まずは標準ライブラリを使いこなすところから始めたら?
そうしてクラスの利点が分かれば、自分で作ろうという気にもなるだろう
398:デフォルトの名無しさん
07/12/16 20:14:27
>>396
適切な本を薦められなくて申し訳ないけど、まずは本で勉強するだけでなく
実際に書いてみて試行錯誤することが大切だと思うよ。
基本文法さえ分かったなら、あとはとりあえず自分であれこれ書いてみて、
まずいクラス設計をして使いにくいと感じたり、エラーが起きて原因を解決したり、
こういうことをしたいけどどう書いていいか分からないと悩んだり、
そういうことを経験したほうが深く理解できるよ。
そのうち、こういうことをするとうまくまとめて書きやすい、分かりやすい、などの利点が見えてくるはず。
本に載っている「正しいやり方」だけを学んでそれをなぞるだけだと、
理解したつもりになっていて実は分かっていない、ということになりがち。
仕事なら早く身につける必要があるだろうけど、学生や趣味でやるなら時間をかけてもいいんじゃない?
399:デフォルトの名無しさん
07/12/16 20:28:34
クラスの勉強と思って簡単なゲームを作ってみたんだけれども、クラス間のやり取りが面倒すぎてやめた
あるAクラス内の配列をBクラスのメンバ関数から参照したいとき、とか
friendってのもあったがそんなこというと全部のクラスにfriendつける必要でるし、
クラスのうまい利用の仕方とか載ってる本探すべきっぽいなぁ
400:デフォルトの名無しさん
07/12/16 20:43:17
C++でnewしたヤツをdeleteする時、
newした時の型のままのポインタをdeleteしないとダメ?
キャストされて別の型になってるポインタをdeleteしても
大丈夫?
401:デフォルトの名無しさん
07/12/16 20:44:45
>>400
virtual
402:デフォルトの名無しさん
07/12/16 20:57:41
>>400
new したときのクラスの基底クラスにキャストされてるポインタは、その基底クラスが
virtual なデストラクタを持っていれば delete できる。
403:デフォルトの名無しさん
07/12/17 00:14:23
>>399
何がやりたかったのかわからんが、多分それはクラス設計ミス。
404:デフォルトの名無しさん
07/12/17 00:16:01
>>399
参照するだけなら、クラスAの配列の要素にアクセスするメンバ関数をinlineで作るとか
405:デフォルトの名無しさん
07/12/17 03:59:03
クラスの設計って難しいよねぇ。
PDO(PHPね)とか使うと、オブジェクト指向すげぇ!って感動するけれど、
自分でいざ、クラス設計してねって言われると、Orz。
何かコツがあるのかしらん?
Cのライブラリでも、構造体使ってうまくオブジェクト指向っぽいもの?を実現しているのを見ると、
感激する!
406:デフォルトの名無しさん
07/12/17 06:07:46
もっとレベルの高い環境に触れないとわからんよ
407:399
07/12/17 09:21:57
クラス設計、やっぱそういう本探してこよう・・
一応やってたのは、配列にフィールドというかマップのフラグみたいなものを格納したいた。
配列の要素内には数値が入っていて、それによってその1マスがどういう状態なのか示すように。
で、よくわからずクラスをマップごとに分けてたんだ、例えばドラクエでいうと宿屋の中と町の中が別クラス
そんな状態で宿屋で休むと町の様子が変化したりetcをやろうとして爆発した
408:デフォルトの名無しさん
07/12/17 11:46:43
>>396
個人的には398に同意だけど、初学者向けの本であれば
「ゼロから学ぶ C++」(日経BP)って本に、CからC++への
移行時の要点ということで、クラスや継承を使うと便利な
ケースと使わない方がいいケースとか、is-a、has-a関係
とかの基本的な話が簡潔に載ってた気がするので、
立ち読みしてみてもいいかも。
ただかなり平易なので、ネットで効率よく検索できれば
不必要(または物足りない)かもしれないけど。
409:デフォルトの名無しさん
07/12/17 11:47:57
長文失礼、ちょっとC++プログラムのコーディングでいい方法があれば誰か教えて下さい。
今、簡単なライブラリ的なクラスを作りました。それは継承されることを前提として
います。仮にそれをKihonとしておきます。
今、Kihonの派生クラスHaseiを作りました。HaseiからKihonを使う方法ですがまず、Kihonの
メンバ関数を通じて必要なパラメータ(privateな変数)を設定します。次にHaseiに
double func(double x)なメンバ関数を定義します。これはKihonクラスでvirtual関数として
宣言されているものです。その後、Kihonのrunを実行するとHaseiのfuncが利用されて
処理が行われるというものです。一回のrunでfuncは何度も呼ばれます。
問題なのはHaseiで異なる二つの処理をKihonのrunにさせるにはどうしたらいいものかということ
です。つまり、異なる相異なる2関数に対してKihonのrunを実行するにはどうすればいいのかと
いうことです。しかも後に実行されるrunが前に実行されたrunの結果を使う必要があります。
初心者なりに考えた方法ですと・・・
0, Haseiのオブジェクトh0を作る。
1, Haseiのfunc関数を作る。この関数内で別のクラス、__Haseiのオブジェクトh1を作る。__Haseiは
Kihonを継承している。
2, 最初のrunで必要なメンバ関数funcを__Haseiで定義する。
3, Haseiのfunc関数からh1.runとして最初のrunを行う。
4, h0.runとして二度目のrunを行う。
(メンバ変数の設定に関しては説明略)。
実際、この方法だととりあえずは動作するのですが次のような問題点があります。
・__HaseiからHaseiのプライベートメンバにアクセスできない。(friendでは次項が解決不能…)
・実はHasei自体もライブラリ的に実装を隠蔽してしまいたいため、__Haseiのfuncを変更
出来るようにしたい。(ちなみにHaseiのfuncは固定。)
多重継承をうまく使うと解決できそうにも思えるのですが賢い、実装方法はないでしょうか。
お力をいただけると幸いです。根本的にKihonの設計に対する指摘でもお願いします。
410:デフォルトの名無しさん
07/12/17 11:59:51
>>409
いろいろわからん。コード書け。あと __ は使うな。
411:デフォルトの名無しさん
07/12/17 12:25:04
>>409
適当に思い浮かんだ単語
スレッド
static メンバー
boost
412:デフォルトの名無しさん
07/12/17 12:54:23
「初心者なりに考えた方法ですと・・・」の部分、ただしコードを全部書くとさらに長大になってしまうので
掻い摘んで。(409のHasei→Hasei0、__Hasei→Hasei1とした)
class Kihon{
virtual double func(double x){return 0.0;} /* =0としてしまってもよい */
public:
double run()
{
... /* runの実装部分 */
for (j = 1; j <= n; j++)
func (x); /* funcは何度も呼ばれる */
return ret; /* 計算結果を返す */
}
};
class Hasei1: public Kihon
{
double y;
double func(double x){return x*sin(x+y);} /* 計算対象 */
public:
void set_y(double y){this->y = y;}
};
413:デフォルトの名無しさん
07/12/17 12:54:54
class Hasei0: public Kihon
{
double func(double x){
Hasei1 h1;
h1.set_y(x);
... /* h1のprivate変数を設定など */
return 1.0 - h1.run();
}
};
int main()
{
Hasei0 h0;
.....
cout << h0.run();
.....
}
例えばx*sin(x+y)の多重積分を想定している感じです。実際にはこれ以外にもたくさんありますが。
本来ですと計算対象は(例えば別のクラスを宣言することや、関数へのポインタでもいいですが)自由に変更出来ること、
そもそもHasei0も1も実装は隠蔽してしまいたい、計算対象はパラメータを含んでいるので本当はクラスとして実装
したいというのがありますが恐らく、これでは無理でしょうからいいアイディアはあるでしょうかという意味です。
よろしくお願いします。
414:デフォルトの名無しさん
07/12/17 13:01:11
boostって知りませんでした。ちょっと調べてみます。
415:デフォルトの名無しさん
07/12/17 13:01:37
>>409
多重継承だけは使うな。
あとでワケわかんなくなる。
416:デフォルトの名無しさん
07/12/17 15:15:36
>>413
ようわからんがtemplateとかboost::bind(std::bind1st, std::bind2nd)使えばよさそうな気がする。ファンクタも調べた方がいいかも。
試しに同じような事するの書いてみた。
template<typename Func> double kihon(Func func)
{
for (j = 1; j <= n; j++)
func(x);
return ret;
}
double hasei1(double x, double y) { return return x*sin(x+y); }
double hasei0(double x) { return 1.0 - kihon(boost::bind(&hasei1, _1, x)); }
int main()
{
kihon(&hasei0);
}
417:デフォルトの名無しさん
07/12/17 16:17:11
>>416
本当にどうもありがとうございます。まだ、自分のプログラムでは解決していませんが言わんとしていることが
よくわかります。たしかにテンプレートを関数のポインターに使えば解決しそうです。C++は初めてなので
参考になります。重ね重ね、ありがとうございます。
418:デフォルトの名無しさん
07/12/17 18:05:37
あるライブラリ(A)をラップした、全く同一のインターフェイスが使えるDLL(B)を作りたいのです。
つまり、DLL(B)はライブラリ(A)のすべての関数をエクスポートします。
これを実現するために(とりあえずwin32環境限定の話)
ライブラリ(A)をDLL(B)にスタティックリンクさせ、ライブラリ(A)の各関数宣言に
__declspec(dllexport)をつけたファイルをDLL(B)からインクルードさせたのですが、
どうもこれでは上手くいかないようで、DLL(B)からライブラリ(A)の関数がエクスポートされていませんでした。
そこで質問なのですが、DLLからライブラリを直接エクスポートすることは可能なのでしょうか?
もし可能ならやり方を教えていただけるとありがたいです。
(ライブラリ(A)をDLLにするという方法はとりあえず却下でお願いします。
今は別の方法としてライブラリ(A)のソースファイルを直接DLL(B)に追加しています)
419:デフォルトの名無しさん
07/12/17 18:48:06
VC++2005StandardでMFC使おうとしてるんですが
ウェブで調べてもVC6.0系の使い方ばかりで全然分かりません
2005のMFCの入門的なサイトってないですか?
できればopengl を絡めたところがいいんですが
420:デフォルトの名無しさん
07/12/17 18:55:07
MFCはマイクロソフトファンダメンタルクラスだろ? バージョンによって言語(クラス)の使い方が変わるかよ
6用でも関係ないだろ
421:デフォルトの名無しさん
07/12/17 19:05:27
クラスウィザードとかを使うのに、IDEのどこのボタン押して、どの選択肢を選べばいいのか?
・・・ってのを知りたいのじゃね?
422:デフォルトの名無しさん
07/12/17 19:53:19
そういやVC2008EEが来るな
423:デフォルトの名無しさん
07/12/17 20:02:56
VC2005でもういいです
424:デフォルトの名無しさん
07/12/17 21:09:24
Hoge hoge1;
Hoge *hoge2 = new Hoge();
の違いがよくわからないのですが
newした場合、普通に宣言するより良いことがあったりしますか?
425:デフォルトの名無しさん
07/12/17 21:15:06
>>424
絵に描いたような初心者か、釣りか、のどっちかだな
426:デフォルトの名無しさん
07/12/17 21:17:47
ヒープ領域は量が多い (ハードディスクもメモリ代わりになる)
自分で変数の領域を開放できる
ヒープに確保すれば、高速な動作が必要な変数をスタック領域、レジスタ領域に割り当てられやすくなる
427:デフォルトの名無しさん
07/12/17 21:19:40
大量にメモリ食うやつは全部newとかにしておけばよい
実メモリを多く空けておくことが大事
428:デフォルトの名無しさん
07/12/17 21:21:41
STL 頼ってるから最近 new 使ってないな…
429:デフォルトの名無しさん
07/12/17 21:27:03
メモリどうこうより、初心者には寿命の違いを説明した方がいいのではなかろうか
430:デフォルトの名無しさん
07/12/17 21:27:30
調べてきたけど、スタック領域はコンパイル時に決定されるらしい
メモリ食うやつは、動的に確保しないとプログラム終了までスタック領域として確保されっぱなしってことだ
他のプログラムや自分のプログラム内でもメモリ確保が難しくなるということだ
431:デフォルトの名無しさん
07/12/17 21:31:08
30バイト以上の確保は動的確保にしようぜ newやvectorやstringを使おう
432:デフォルトの名無しさん
07/12/17 21:31:23
>>424
Hoge hoge1;
の場合、hoge1の寿命がその関数(あるいはブロック)に縛られる。
関数を抜けた後もhoge1を維持することは出来ないし、関数を抜ける前にhoge1を消すことも出来ない。
Hoge *hoge2 = new Hoge();
の場合、hoge2の寿命は自分でコントロールできる。
関数を抜けようが抜けなかろうが、deleteするまでは消えないし、deleteすればいつでも消せる。
433:デフォルトの名無しさん
07/12/17 21:35:35
配列は動的確保、自動開放するvectorがあるけど 変数は動的確保、自動開放する命令ってないよね?
Hogeクラスが5Mとか使うとは想像していないのだろうか?
434:デフォルトの名無しさん
07/12/17 21:36:37
auto_ptrのことか?ちょっと違うか?
435:デフォルトの名無しさん
07/12/17 21:57:06
class Hoge{ char x[10000]; };
auto_ptr< Hoge > hog(new Hoge);
こうやって使うのか 勉強になった でもアクセスが*付けないと駄目で不便だよね
436:デフォルトの名無しさん
07/12/17 22:02:26
そんなあなたに
boost::scoped_array
boost::shared_array
437:424
07/12/17 22:06:21
しょうもない質問に答えてくれてありがとうございます
とりあえず普通に宣言しておけば大丈夫だ
なんて思ってた自分が馬鹿でした・・・
しっかりdeleteする必要がありますが、
なるべく動的確保にしておいた方が良いんですね
もうすこし自分でも調べてみようと思います
ありがとうございました
438:デフォルトの名無しさん
07/12/17 22:10:48
int型やchar型やdouble型の変数を動的確保するのは止めよう
あとループの変数も動的確保するのは止めよう
判断基準は、メモリを消費するかどうかだろう
439:!=438
07/12/17 22:27:09
>>438
判断基準に「(ループ内など)速度が必要か否か」も加えるといいかも。
10万回、100万回のループになると毎回newするのも…
まぁ、その場合は最初にnewして使いまわせ、って話になるわけだが。
440:デフォルトの名無しさん
07/12/17 22:30:32
ループ内で毎回な別領域の確保が必要な場合はあるけどね・・・
流用できるなら内部でしたらだめだな
441:デフォルトの名無しさん
07/12/17 22:38:19
基本的にループの変数は直前に確保した方が良いのかなあ
以前から使っている変数だと、レジスタにのっている可能性は低いし、ループで使うからと言って移動はしないよね?
for( int )だと最適化されそう
442:デフォルトの名無しさん
07/12/17 23:12:40
>>441
変数の用途が明確な方が最適化対象になりやすい。
443:デフォルトの名無しさん
07/12/17 23:42:33
別のスレッドで返答がもらえなかったのでこちらで。
なぜcallocは2引数関数なのでしょうか。ゼロクリアするだけならmallocのように1引数でも可能だとおもいます。
2引数のほうが最適化しやすいからだときいたことがありますが、具体的にはどのような最適化が考えられるでしょうか?
444:デフォルトの名無しさん
07/12/17 23:51:31
callocのcて何て意味?
445:デフォルトの名無しさん
07/12/17 23:52:34
>>443
例えば80486以降のインテル系CPUはSTOSB STOSW STOSDという三つの命令があり、
それぞれバイト、ワード、ダブルバイト単位でレジスタから転送を行う。
他のCPUでもサイズに応じた専用のインストラクションを持っていることはよくある。
そのどれを使うかとかいったヒントになる可能性があると思う。
446:デフォルトの名無しさん
07/12/17 23:53:00
clear?
447:445
07/12/17 23:53:15
ダブルバイトってなんだよ。ダブルワードの間違いな。
448:デフォルトの名無しさん
07/12/17 23:56:16
>>445
なるほど。ありがとうございます。
しかしその程度なら、要求されたサイズの下位数ビットを見れば判断できる気もするが・・・。
449:デフォルトの名無しさん
07/12/18 00:05:43
>>443
callocは一応「配列を確保する関数」だからじゃない?
最適化に関しては↓がヒントになるかも。
URLリンク(www.bohyoh.com)
450:デフォルトの名無しさん
07/12/18 00:09:54
>>449
最適化については何も解説していないような・・・
451:デフォルトの名無しさん
07/12/18 01:03:49
>>420
ファンダメンタルかよ
452:デフォルトの名無しさん
07/12/18 02:16:52
signed型へ<<や>>演算したときの結果の符号ビットや符号拡張有無って
規格で決まっていますか?
453:デフォルトの名無しさん
07/12/18 02:32:06
>>452 いいえ。
454:デフォルトの名無しさん
07/12/18 09:57:37
C++ 初心者です。C++ でこんなコードを見かけたのですが、 struct S { S( int x ) : x_( x ) {} int x() { return x_; } int x_; }; 2 行目の意味がわかりません。とくに x_( x ) {} の部分が頭の中でパーズできないんですが、これは何を定義しているの?
455:デフォルトの名無しさん
07/12/18 09:59:38
: x_( x ) だな
x_をxで初期化している
コンストラクタ初期化子とかでぐぐると幸せになるかも
456:デフォルトの名無しさん
07/12/18 10:37:10
この書き方で「2行目の意味が」ってのも凄いな
ナチュラルな喧嘩の売り方するなぁと感心したw
457:デフォルトの名無しさん
07/12/18 10:42:22
コンストラクタの初期化子で配列の初期化ってできる?
458:デフォルトの名無しさん
07/12/18 11:07:46
>>457
組み込み配列についてはできません。 std::vector ならできます。
459:デフォルトの名無しさん
07/12/18 11:26:54
>>458
ありがとう
じゃあコンストラクタ内で普通に代入するか
もう一つ質問
固定長配列にvectorを使う意味ってある?
あるとしたら何?
460:デフォルトの名無しさん
07/12/18 11:34:14
>>459
サイズの管理も一緒にしてくれる。
未来永劫何があってもサイズが変わらない場合を除けば、この利点は小さくない。
461:デフォルトの名無しさん
07/12/18 11:35:23
>>459
多くの実装では assert() などでデバッグ用の範囲チェックが入っている。
begin(), end() があるので標準アルゴリズムが使いやすい。
要素の比較に基づく比較演算子が定義されている。
安全で軽い swap() が使える。
462:デフォルトの名無しさん
07/12/18 12:02:09
C言語でvoid型の関数を任意の場所で終了させるにはどうすればいいのでしょうか?
何か値を返せる関数ならreturnすればいいと思うのですが
voidなのでreturnをすると怒られてしまいました
463:デフォルトの名無しさん
07/12/18 12:04:39
return;
464:デフォルトの名無しさん
07/12/18 12:05:52
>>462
void func(){
return;
}
465:デフォルトの名無しさん
07/12/18 12:09:42
>>462
void func()
{
...;
goto end;
...;
end:
}
or
void func()
{
...;
if (0) {
...;
}
}
466:デフォルトの名無しさん
07/12/18 12:15:41
>>460-461
サンクス
467:デフォルトの名無しさん
07/12/18 12:16:11
ああ、なるほど
値さえ返さなきゃ怒られないんですね
0を返しておりました
468:デフォルトの名無しさん
07/12/18 12:20:25
>>460
static const int foo[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
みたいな固定長配列なら、sizeof(foo) / sizeof(* foo)でsize()相当だと思うが、それでもメリットだと?
469:デフォルトの名無しさん
07/12/18 12:23:26
STLのコンテナとして使える
470:デフォルトの名無しさん
07/12/18 12:26:16
boost::array
471:デフォルトの名無しさん
07/12/18 12:50:19
じゃあそれポートして使いまする
472:デフォルトの名無しさん
07/12/18 12:51:25
固定長配列テンプレートはいいよね
余分な領域取らないし
473:デフォルトの名無しさん
07/12/18 12:59:15
boost::checked_deleteってそんなに役に立つか?
474:デフォルトの名無しさん
07/12/18 13:03:58
初心者でも何か作れる物はないだろうか?
475:デフォルトの名無しさん
07/12/18 13:05:18
>>474
アドレス帳
ノベルゲーム
etc
476:デフォルトの名無しさん
07/12/18 13:07:47
>>475
ノベルゲームを作れるお勧めのwindows上で動く
アプリとかありませんかね。
477:デフォルトの名無しさん
07/12/18 13:20:59
C言語でいいじゃん
printfとscanfで作れるぞ
478:デフォルトの名無しさん
07/12/18 13:25:14
おまえらって何が目的でC言語使ってんの?
479:デフォルトの名無しさん
07/12/18 13:29:21
>>473
なんで役に立たないと思うの?
あと、 boost スレに行ったほうがいいかもね。
480:デフォルトの名無しさん
07/12/18 13:45:48
>>478
プログラミングするのが楽しいから
481:デフォルトの名無しさん
07/12/18 15:18:50
まともに仕事で使おうとすると、
boostなんてフリーのライブラリは、
使用許可がおりない件について
誰が責任もてるの、って怒られるぜよ
482:デフォルトの名無しさん
07/12/18 15:34:04
boostからポートした自作ライブラリを使うんだよ
483:デフォルトの名無しさん
07/12/18 15:36:43
それを言い出すと、gccや下手すればLinuxそのものも使えなくなる罠。
484:デフォルトの名無しさん
07/12/18 15:41:40
>>483
プロジェクトの種類や客の流儀とかなんとかで、
そのとおりな制約がつく仕事も実際、けっこうある。
・・・いや、あった。もう地獄から永久に開放されて
こんな時間に2chしてる俺にはどうでもいい話
485:デフォルトの名無しさん
07/12/18 15:46:46
参照のつかいかたがよくわからないので教えてください。POCO::Loggerというライブラリをつかっています。
hasがLoggerのポインタを返して、getが参照を返します。createで作ります。
POCO::Logger* buff = POCO::Logger::has("hoge");
if (buff == NULL) {
// 無いから作る
POCO::Logger& logger = POCO::Logger::create("hoge");
logger.information("@@@@@");
} else {
// あるから使う
POCO:Logger& logger = POCO::Logger:get("hoge");
logger.information("@@@@@");
}
// @ほんとはここでlogger.information("@@@@@")にして、↑の@@@@@出力部分は消して共通化したい
というコードは動くんですが、最終行で出力する処理を入れて
共通化したいんですけど、参照ってポインタみたいにいれないでおくとかができないと思っています。
このような実装はみなさんどのようにされていますか?
486:デフォルトの名無しさん
07/12/18 15:51:11
>>481
フリーとは言っても誰が作ってると思う?
使用許可を出さない奴本人に
『おまえが判断できる程のレベルかよ?』
って言い返す。
487:デフォルトの名無しさん
07/12/18 15:52:29
>>479
不完全型のチェックにしか使えないよね。
全く役に立たないとは思わないけど、あえて使う意味はあるのかと。
488:デフォルトの名無しさん
07/12/18 16:13:45
>>485
POCO::Logger & logger = buff == NULL ? POCO::Logger::create() : POCO::Logger::get();
logger.information();
489:デフォルトの名無しさん
07/12/18 16:22:40
>>488
ぉぉすばらしい。ありがとうございます。そのような発想はありませんでした。
ちょっとトリッキーな気がするのですが、C++で参照を使うときは常識ですか?
490:デフォルトの名無しさん
07/12/18 16:45:28
C++と言わず参照と言わず、割と使うけど。
Cでもこんなのとか。
FILE * fp = fileName == NULL ? stdin : fopen(fileName, "r");
491:デフォルトの名無しさん
07/12/18 17:52:49
>>490 の
FILE * fp = fileName == NULL ? stdin : fopen(fileName, "r");
って どのように分解(解釈)されるの?
492:デフォルトの名無しさん
07/12/18 17:57:10
>>491
fileNameがNULLだったらstdin、そうでなければfileNameをfopen()した結果をfpに代入。
493:デフォルトの名無しさん
07/12/18 18:05:23
>>492
有難うございます。日本語ではそうなるのですか。
すみません、この1行をC言語に1行ごと(ステップ)に分解して書いたらどうなるのですか?
494:デフォルトの名無しさん
07/12/18 18:11:18
FILE *fp ;
if( fileName == NULL )
{
fp = stdin ;
}
else
{
fp = fopen(fileName,"r");
}
495:デフォルトの名無しさん
07/12/18 18:12:19
まあ、参照は初期化必須だから、>>488を分割して書く事は出来ないがな。
496:デフォルトの名無しさん
07/12/18 18:12:26
FILE * fp =
fileName == NULL
? stdin
: fopen(fileName, "r");
497:デフォルトの名無しさん
07/12/18 18:13:39
boost::optionalをパクればいい
498:デフォルトの名無しさん
07/12/18 18:23:44
>>494
有難うございました
そうなるのですか、なんか>>490だと読みにくいですね
>>495
となると、参照のときは読みにくい構文使うしかないということですね
499:デフォルトの名無しさん
07/12/18 18:56:32
>>498
俺が三項演算子を使うときは、条件部を必ず(単項式であっても)括弧で括ってる。
>>490の例の場合は、
FILE * fp = (fileName == NULL) ? stdin : fopen(fileName, "r");
まぁ、この辺は各々のスタイルの問題。
読みにくさについては内容の複雑さによりけりで、たとえば
int n = (hoge) ? 10 : 20;
程度の内容をif-else文で書くと、俺の感覚だと「無駄に物々しい」感じがして、逆にわかりにくいかな。
500:デフォルトの名無しさん
07/12/18 19:12:34
三項演算子は禁止、
って、けっこうコーディングルールにされることが多い
501:デフォルトの名無しさん
07/12/18 19:18:45
生粋の三項演算子erな漏れには辛い職場だ
502:デフォルトの名無しさん
07/12/18 19:29:24
>>498
こんなんでもいんじゃね?
POCO::Logger* buff = POCO::Logger::has("hoge"), *logger;
if (buff == NULL) {
// 無いから作る
logger = &POCO::Logger::create("hoge");
} else {
// あるから使う
logger = &POCO::Logger:get("hoge");
}
logger->information("@@@@@");
というかhas()が返すアドレスの実体はgetで得られるインスタンスとは別物なん?
同一ならそのまま使えるだろうけど
503:デフォルトの名無しさん
07/12/18 19:29:27
ff
504:デフォルトの名無しさん
07/12/18 19:36:13
例外処理のthrowのメリットは?
普通に関数にとばすのはだめなのかい
505:デフォルトの名無しさん
07/12/18 20:21:22
普通に関数に飛ばすとは、どういうやり方?
throwは関数の呼び出し元の呼び出し元の呼び出し元の・・・にずーっと遡っていけるところに意味がある
506:デフォルトの名無しさん
07/12/18 20:23:41
昔のCのように、abort()を呼ぶとかそういう話?
507:デフォルトの名無しさん
07/12/18 20:53:58
>>504の考える例外的な事態というのは、その場でプログラムを終了するタイプ「のみ」なんじゃないかな。
確かに、すぐ終了するのであれば、例外処理の存在意義である「簡潔かつ強力に特定の段取りまで戻る」
能力は要らないからね。
>>504
でも、例外発生後もまだプログラムを続行させる場合、「関数に飛ばして」例外処理を実現しようとすると、
結構面倒というか、入り組んでしまうことがある。
f1()から呼んだf2()から呼んだf3()から呼んだf4()の中で何か「例外的な状態」になった場合、f4()内に
if (失敗したという証拠) {
例外処理();
return 失敗したという合図;
}
を書くだけでなく、場合によってはf2()やf3()も、その「合図」がちゃんとf1()のもとへ帰っていけるよう、
バケツリレーのような構造の実現に協力しなくちゃならなくなったりするわけだ。
その例外は、自分とは直接関係ないことなのにね。
508:デフォルトの名無しさん
07/12/18 21:01:10
ただやっぱり、Joelもいってるように、例外はきちんと
ハンドリング出来ているかが、コード面を眺めたくらいでは
すぐには判らないという弱点があるね。
戻り値ベース:
fp = fopen(filename, "w");
fwrite( var, 1,len,fp ); //ププ。エラー処理忘れやがんの。
例外ベース:
fs = new FileStream( filename, WRITE );
fs.Write( var ); //ファイル無かったら例外投げるから、
//呼ぶ側で対処しろと言うことかな~?
509:デフォルトの名無しさん
07/12/18 21:07:30
>>420
インターフェースが結構違うのでわからないんです
参考に見た6.0の解説を上げてみると
~~~
左フレームのFileメタブをクリックして、Source FileのGlSampleView.cppファイルを開く
右のフレームに現れるソースファイル上で、右クリック。表示メニューのClassWizardを選択する←この時点で分からない
ここでViewクラスのメッセージ処理をカスタマイズする。
メッセージ欄から「WM_CREATE」を選択して関数追加ボタンをクリックする。
するとOnCreate()関数がGlSampleView.cppファイルに自動的に追加される。
~~~
クラスウィザードのようなものは別の方法で見つけたんですがすると4行目のWM_CREATEが無い
といったように前に進みません
510:339
07/12/18 22:32:05
1>index.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall std::ios_base::Init::Init(void)" (??0Init@ios_base@std@@QAE@XZ) が
関数 "void __cdecl std::`dynamic initializer for '_Ios_init''(void)" (??__E_Ios_init@std@@YAXXZ) で参照されました。
1>index.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall std::ios_base::Init::~Init(void)" (??1Init@ios_base@std@@QAE@XZ) が
関数 "void __cdecl std::`dynamic atexit destructor for '_Ios_init''(void)" (??__F_Ios_init@std@@YAXXZ) で参照されました。
1>D:\ta\c\works\online\Debug\dos.exe : fatal error LNK1120: 外部参照 2 が未解決です。
===index.cpp====
#include <iostream>
int main() {
std::cout << "Kitty on your lap";
return 0;
}
===============
/O2 /D "_MBCS" /FD /EHsc /MT /Fo"Debug\\" /Fd"Debug\vc80.pdb" /nologo /c /TP /errorReport:prompt
/OUT:"D:\ta\c\works\online\Debug\dos.exe" /NOLOGO /MANIFEST /MANIFESTFILE:"Debug\dos.exe.intermediate.manifest"
/SUBSYSTEM:CONSOLE /ERRORREPORT:PROMPT kernel32.lib
リンクがうまくいってないってことかな?
ちゃんとライブラリフォルダをC:\Program Files\Microsoft Platform SDK\Libに設定しているのだが・・。
511:デフォルトの名無しさん
07/12/18 23:00:25
たまに見かけるけとKitty on your lapて何なん?
調べてみたらゲームみたいだけどあれが元ネタ?
512:デフォルトの名無しさん
07/12/18 23:35:44
>>510
iostreamってSDKじゃないだろ。
513:デフォルトの名無しさん
07/12/18 23:36:20
猫でも分かるの人がサンプル文字列に使ってたな。
さらなる元ネタはよくわからないが。
514:デフォルトの名無しさん
07/12/19 00:07:13
古いギャルゲーのタイトル
515:デフォルトの名無しさん
07/12/19 01:29:06
問題分が
以下の手順を従い、経路選択アルゴリズムを評価せよ。
通信の発生:ランダムに送受信ノードを決定する。
通信の確定:与えられた送受信ノードの経路を決定し、その経路上のリンクの空き容量を1Mbpsだけ減少させる。
ただし、空き容量のないリンクが存在する場合、この通信は確立しなかったものとして、何も行わない。
通信の終了:n回前に発生した通信の経路上の空き容量を1Mbpsだけ増加させる。ただし、その通信が確立していなかった場合には何も行わない。
評価:10000回の通信を発生させ、そのうちで確立できなかった通信の割合を求める。
試行の繰り返し:nの値を変えながら、上記の試行を繰り返す
プログラム自体(URLリンク(kansai2channeler.hp.infoseek.co.jp))は拾ってこれたのですが
どこにグラフを入力していいのか分からなく困っています。
ちなみにグラフは以下に書きます
URLリンク(kansai2channeler.hp.infoseek.co.jp)
左と中央がノードで右がそれをつなぐリンクの容量です。
516:デフォルトの名無しさん
07/12/19 01:38:58
宿題スレへ
517:デフォルトの名無しさん
07/12/19 02:08:39
>>508
戻り値だってコード面見てエラー処理の抜けは気づきにくい。
Joel とかが言ってるのは、エラー処理に問題のあるコードと
適切なコードとの違いが微妙すぎるって言う問題。まぁこっちの問題も
一緒といえば一緒なんだけどな。処理の順番とか。
518:デフォルトの名無しさん
07/12/19 09:00:37
VC++ 2005での関数インライン化について教えてください。
通常、インライン関数は定義をヘッダに書かないとコンパイル
できませんが、/LTCGオプションでリンク時のモジュール間
インラインを指定すると以下のようなコードがビルド可能
だと思ったのですが、実際はリンクエラーとなります。
もちろんinlineキーワードを外すとビルドできます。
/LTCGを指定してもinlineキーワードを付けるとインライン
対象関数の定義は呼び出しソースファイルから可視でなくて
はいけないのでしょうか?/LTCGのリンク時モジュール間
インラインの正しい使用法を教えてください。
//aaa.hヘッダーファイル
double MySquare(double);
//aaa.cppソースファイル
inline double MySquare(double d)
{
return d * d;
}
//bbb.cppソースファイル
#include "aaa.h"
int main()
{
double d = MySqiare(3.14);
}
519:デフォルトの名無しさん
07/12/19 09:15:43
よく空間的局所性の高いコードは速いとかいいますけど、最近のx86で
あるアドレスの値を読み込むと、その先何バイト位がキャッシュに載るんですか?
520:デフォルトの名無しさん
07/12/19 09:46:40
VC8(VC2005)で
template<class T>
std::list<T>::iterator MoveListItr(std::list<T> *pLst)
~略~
というSTLのイテレータを返すテンプレートが、イテレータの記述部分
(std::list<T>::iterator)で「型ではない」とエラーが出ます。
VC7まではこれで通ったのですが、文法に問題があるのでしょうか?
それともVCの問題なのでしょうか?
521:デフォルトの名無しさん
07/12/19 09:53:01
template<class T>
typename std::list<T>::iterator MoveListItr(std::list<T> *pLst)
522:デフォルトの名無しさん
07/12/19 10:00:51
>>520
typename std::list<T>::iterator MoveListItr(std::list<T> *pLst)
って書けばいいんじゃないかな。
いわゆる特殊化ってやつがあるせいで、classname<T>::hogeという記述だけでは、
hogeが値なのか型名なのか断定できない。
そういう場合、「これは型名ですよ」というのをコンパイラに教えるために、typenameを書く。
今回のVC7と8の違いは、「ここは関数の戻り値の型を書く場所だから、型名に決まってるよな」
とコンパイラが判断したか否か、の違いだと思うんだけど、
VC7の気が利いているのか、VC8が「VC7が無視した何らかの可能性」を見て断定を避けたのか、
どっちなのかは俺にはわからないや。
523:デフォルトの名無しさん
07/12/19 10:03:56
単に規格に準拠するようにしただけじゃねえの?
524:デフォルトの名無しさん
07/12/19 10:12:15
>いわゆる特殊化ってやつがあるせいで
特殊化は無関係
525:デフォルトの名無しさん
07/12/19 10:13:50
>>521-523
なるほど、そうだったんですか。
おかげで解決しました、ありがとうございます。
526:りょう ◆RyOrlro88Q
07/12/19 10:46:02
ループが止まりません><
#include<stdio.h>
#define N 20
main(){
char ch[N],a,word='^';
int num,i,j;
j=0;
printf("Input your name.(When the input is finished,type ^.)\n");
for(num=0;ch[num]!=word;num++){
printf("ch[%d]=",num);
scanf(" %s",&ch[num]);
}
printf("target:");
scanf(" %c",&a);
for(i=0;i<num;i++){
if(ch[i]==a){
j++;
}
printf("%c=%d\n",a,j);
}
}
527:デフォルトの名無しさん
07/12/19 11:04:06
>>526
最初のループの終了条件がおかしい。
528:りょう ◆RyOrlro88Q
07/12/19 11:09:43
ループは自己解決><
次は判定に問題が…><
529:りょう ◆RyOrlro88Q
07/12/19 11:30:49
jが増えない><
#include<stdio.h>
#define N 20
main(){
char ch[N],a,word='^';
int num,i,j;
j=0;
printf("Input your name.(When the input is finished,type ^.)\n");
for(num=0;ch[num]!=word;num++){
printf("ch[%d]=",num);
scanf(" %s",&ch[num]);
if(ch[num]==word){
break;
}
}
printf("target:");
scanf(" %c",&a);
for(i=0;i<num;i++){
if(ch[i]==a){
j++;
}
}
printf("%c=%d\n",a,j);
}
530:デフォルトの名無しさん
07/12/19 11:34:56
ちったあ自分で考えないと成長しないぜ
531:りょう ◆RyOrlro88Q
07/12/19 11:40:58
考えてるけどわからないんです><
532:デフォルトの名無しさん
07/12/19 11:43:39
>>528
他にも色色問題が。scanf()で一文字ずつ入力なんて阿呆なことしないで、
fgets()で1行分まるっと入力してしまえばいいじゃん。
あと、'^'による終了判定も無意味。
533:デフォルトの名無しさん
07/12/19 11:45:26
つーか、>529ではループの判定条件がバグったままじゃんw
534:デフォルトの名無しさん
07/12/19 11:46:26
何故増えないんだと思う?
具体的な場所はともかく、どの辺が間違ってそうな気がする?
本当はデバッガを使うのが良いんだろうが、printfデバッグっていう手法だってある。
それっぽい箇所にprintfを挿入するだけで見えてくるかもよ。
535:デフォルトの名無しさん
07/12/19 11:47:57
ブロックの前後や中で満たすべき条件を式のかたちで書き出してみてはどうか
536:デフォルトの名無しさん
07/12/19 11:51:01
紙と鉛筆使って机上でプログラムを実行してみるのもいい。
どこで意図しない動作になっているかすぐ分かる。
537:デフォルトの名無しさん
07/12/19 11:53:22
>>518について詳しい人いませんか?
538:りょう ◆RyOrlro88Q
07/12/19 11:57:29
解決できました><
ありがとうございましたm(__)m
>>532
それが指定なんですよ><
>>534
そんな方法なんて知りませんでした><
539:デフォルトの名無しさん
07/12/19 12:01:09
ほほぉ。それじゃ、スレよごしの罰として完成したソースを貼ってもらおうか。
540:デフォルトの名無しさん
07/12/19 12:06:58
>>118
URLリンク(ml.tietew.jp)
541:デフォルトの名無しさん
07/12/19 12:07:22
>>537
inline指定無しでも最適化でインライン展開してくれるんじゃないの?
明示的にinline指定したい積極的な理由でもあるなら兎も角、そうでないならコンパイラに任せたら?
つーか、iccだとinline指定をつけると却ってコンパイラが混乱するみたいだ。
542:デフォルトの名無しさん
07/12/19 12:11:03
>>540
番号間違ってる。
しかし、そのリンク先のエピたんの弁によれば、
inline指定してある関数を別の翻訳単位から見つけてくるiccはおかしなことになるね。
543:デフォルトの名無しさん
07/12/19 12:22:09
7.1.2.4を見てextern inlineにしたら通った
544:デフォルトの名無しさん
07/12/19 13:00:43
// aaa.h
extern inline double MySquare(double);
// aaa.cpp
double MySquare(double d){...}
// main.cpp
#include "aaa.h"
int main() {
double d = MySquare(3.14);
}
一応gcc3.4とvc8でいけた
external linkageなinline指定つきの関数宣言がどうたらこうたら書いてあるけど理屈はよくわかんね
545:デフォルトの名無しさん
07/12/19 13:28:11
>>540
>>541
>>542
>>543
ストラップ本にはinline定義とあるので、おそらく
無理なんでしょうね。
extern inline定義にしたらVC 2005では実行できましたが、
g++ v4では無理でした。移植性考えたらやはり素直にヘッダーに
定義を書いたほうが無難ですね。
546:デフォルトの名無しさん
07/12/19 13:30:36
>>544
extern inlineを宣言につけるんですか。
試して見ます。
547:デフォルトの名無しさん
07/12/19 13:37:55
>>544
g++ v4でもリンクできましたが、
定義にinlineつけないとインライン展開されて
ないかもしれないですね。
548:デフォルトの名無しさん
07/12/19 13:55:07
VC++ 2008でもテンプレートのexport定義はサポート
されてないんだな
549:デフォルトの名無しさん
07/12/19 13:58:09
>>548
別に規格に違反してないからね
550:デフォルトの名無しさん
07/12/19 14:35:53
kernel: pid xxxx (a.out), uid yyyy: exited on signal 11 (core dumped)
というメッセージがログに残っている場合は何を調べればいいのでしょうか?
551:デフォルトの名無しさん
07/12/19 14:38:34
VCEEにMFCついてないかー/(^o^)\
552:デフォルトの名無しさん
07/12/19 14:52:40
>>50
coreファイルを調べるのが王道
553:デフォルトの名無しさん
07/12/19 14:58:45
>>550
signal 11はSEGVだから、要はセグメンテーションフォルトを起こしたってこった。
まぁ、メモリアクセス周りでバグってるんだろ。
554:デフォルトの名無しさん
07/12/19 15:02:26
>>551
TurboC++ExpressだったらMFC付いてたかもしれん。
555:デフォルトの名無しさん
07/12/19 15:32:15
>>554
把握した、WinAPI直接とか死にそうだからVB.NETかC#いじってくる
556:デフォルトの名無しさん
07/12/19 15:36:26
どっちもとか正規表現あるから戻ってこれなくなりそう
557:デフォルトの名無しさん
07/12/19 16:20:06
bitsetよりvector<bool>のほうが性能が上のことが判明した
#include <iostream>
#include <vector>
#include <bitset>
#include <time.h>
using namespace std;
main(){
#define N 8200000
int n,m,cl;
cl=clock();
bitset<N> a;
for(m=0;m<10;m++)for(n=0;n<N;n++)a[n]=1;
cl=clock()-cl;cout<<cl<<endl;
cl=clock();
vector<bool> b(N);
for(m=0;m<10;m++)for(n=0;n<N;n++)b[n]=1;
cl=clock()-cl;cout<<cl<<endl;
}
558:デフォルトの名無しさん
07/12/19 16:30:20
自前の関数のほうが断トツで早かった
#include <iostream>
#include <vector>
#include "crc.h"
#include <bitset>
#include <time.h>
using namespace std;
main(){
#define N 8200000
int n,m,cl;
char *rnd =new char[N];
for(n=0;n<N;n++)rnd[n]=rand()&1;
cl=clock();
bitset<N> a;
for(m=0;m<10;m++)for(n=0;n<N;n++)a[n]=rnd[n];
cl=clock()-cl;cout<<cl<<endl;
cl=clock();
vector<bool> b(N);
for(m=0;m<10;m++)for(n=0;n<N;n++)b[n]=rnd[n];
cl=clock()-cl;cout<<cl<<endl;
cl=clock();
unsigned int k,l, *c=new unsigned int [1+(N>>5)];
for(n=0;n<(N>>5);n++)c[0]=0;
for(m=0;m<10;m++)for(n=0;n<N;n++){
k=n>>5; l=n&31; c[k] |= (rnd[n]<<l);}
cl=clock()-cl;cout<<cl<<endl;
}
559:デフォルトの名無しさん
07/12/19 16:30:52
>>557
うちの環境ではbitsetの方が5倍速いんだが
bitset -> 143
vector -> 890
VC2005, C2D E6850
560:デフォルトの名無しさん
07/12/19 16:37:09
>>559
MinGWやVCCで計ってみたけど、環境によって変わるらしいね でも自前のビット演算が最速だった
558のcrc.hはいりません
561:デフォルトの名無しさん
07/12/19 16:41:06
>>560
gcc 3.4.4(cygming special)でもbitsetのほうが早かった
bitset -> 171
vector -> 687
自作は知らん
562:デフォルトの名無しさん
07/12/19 16:42:41
>>558のほうでやってくれ 最適化されてループしていない可能性がある 初めのやつでは
563:デフォルトの名無しさん
07/12/19 16:45:57
VC2005
bitset -> 460
vector -> 1876
自前 -> 137
やはりbitsetaのが早い
564:デフォルトの名無しさん
07/12/19 16:49:50
でも、どの環境でも自前でビット演算するのが一番みたいだね
565:デフォルトの名無しさん
07/12/19 16:58:54
まあ問題領域によるだろう
早さだけを求めるならbitsetに限らず自分で書いた方がことが多いだろうね
566:デフォルトの名無しさん
07/12/19 16:59:00
>>557
./a.gcc.O3
220000
400000
./a.gcc.O3.msse2
150000
390000
./a.gcc.O3.msse2.funroll-loops
150000
420000
./a.icc.xT.O3.ipo
140000
260000
./a.icc.fast
140000
250000
567:566
07/12/19 17:03:18
おっと、書き忘れた。Xeon5160@3.00GHzね。
で、>558のほう。
--
./a.gcc.O3
440000
1010000
120000
./a.gcc.O3.msse2
410000
1010000
120000
./a.gcc.O3.msse2.funroll-loops
400000
1010000
130000
./a.icc.fast
420000
570000
130000
./a.icc.xT.O3.ipo
420000
570000
130000