【初心者歓迎】C/C++室 Ver.49【環境依存OK】
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/02/20(水) 12:33:41ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。
【前スレ】
【初心者歓迎】C/C++室 Ver.48【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1202141921/
【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
0697デフォルトの名無しさん
2008/02/25(月) 14:35:18置換前より後の文字列のほうが長い場合、
単純にその場で書き換えていくと、1ヶ所置換が行われる度に
置換部分以降をずらしたり、時にメモリの伸張をしたりで時間がかかる。
最近のOSはメモリの扱いも上手になっているし、
そもそもPCのメモリ搭載量も大きくなっているから、
新しいメモリに書き込んでいくも選択肢として捨てたものではない。
0698デフォルトの名無しさん
2008/02/25(月) 14:38:10VC++ 2008でしか試してない。オーバーロード解決は規格に従って
いるんだが。コンパイラがテンプレート規則に対応していないのかね。
0699デフォルトの名無しさん
2008/02/25(月) 14:48:28stringにコピーするのが一番なんですかね?
関数で作業領域を確保しようとするので 初めの3倍必要になります
コピー無しなら2倍ですみます 300メガとかだと動作に支障出ないですかね・・
>>698
うちのコンパイラだと全滅しました MinGWの最新版 、DMC、VC++6.0、bcc5.5.1
0700デフォルトの名無しさん
2008/02/25(月) 14:51:462番の方向で行こうとしているところだったんです
定数なら書き換え可能な領域を確保しようとしたら、その判別がコンパイラでできないのでここで質問していたんです
0701デフォルトの名無しさん
2008/02/25(月) 14:51:46new char[]せずに最初からstringの中にデータを作ればコピーを減らせる
int N=300*1024*1024;
string str2;
str2.resize(N);
for(int n=0;n<N;n++)str2[n]=n; //巨大なバイナリ配列
replace(str2, "geho", "(^_^)");
0702デフォルトの名無しさん
2008/02/25(月) 14:57:26stringに直接挿入する方向で行こうと思います
巨大な入力があるのはファイルからなので、自作して直接stringに入れるようにします
0703デフォルトの名無しさん
2008/02/25(月) 15:00:35>コピー無しなら2倍ですみます 300メガとかだと動作に支障出ないですかね・・
stringの操作云々よりも、その情報量をどう扱うかと言うアルゴリズムの方が問題になりそうな希ガス。
少なくとも、GiBオーダ未満のメモリくらい今時普通に扱えるよ。
>>696
どう、機能していないのさ。
0704デフォルトの名無しさん
2008/02/25(月) 15:01:190705692
2008/02/25(月) 15:03:09俺の場合、その判別は自分でやる。
必要なら自分でメモリ確保してmemcpyか何かでコピーしてから置換する関数へ渡すと言うこと。
メモリ確保その他をstringに任せているという点が違うけど、695案と同系統のアイデア。
0706デフォルトの名無しさん
2008/02/25(月) 15:04:31関数突入を探すwhileの条件がcount != 1だから、関数突入後に中括弧を見つけるとcountが2になって脱出できなくなる罠。
0707デフォルトの名無しさん
2008/02/25(月) 15:10:50>706に加えて、内側のwhileは両方ともifでいいだろよ。
つまり、最初のwhileは if (count == 0)で、次のwhileはif (count > 0)。
んで、fin >> bufferだと単語単位でしか入力できないから工夫が必要。
# 行単位入力すればいいのかな? 仕様がわからんからなんとも言えんが。
0708デフォルトの名無しさん
2008/02/25(月) 15:13:01ポインタのポインタとかやっているうちに動かない場合があることに気づき修復不可能になりました
そしてC++で参照や型判定して作ろうとしたらこれも上手くいきませんでした
簡明なプログラムが大事ですね
0709デフォルトの名無しさん
2008/02/25(月) 15:20:04#define strconv(q, p) _memconv(&q, &p, strlen(p))
#define memconv(q, p, n) _memconv(&q, &p, n)
#define strconstconv(q, p) _strconstconv(&q, p)
_memconv(strdata *q, char **p, int n){
char **chend =(char **)malloc(sizeof(char **));
q->start=p; *chend=&(*p)[n]; q->end = &(*chend);}
0710デフォルトの名無しさん
2008/02/25(月) 15:52:07無理して難しく書いても、あとあとメンテナンスやデバッグのことを考えると、シンプルに書いた方がいい場合が多い
メモリを何MBか余計に使ったり、実行時間が何分か伸びたところで、なんだというんだ
ややこしいコードは書くのもデバッグも何日もかかる
それだけの価値があればやってもいいが、たいていは割に合わない
0711デフォルトの名無しさん
2008/02/25(月) 17:21:33一日でマスターするのは無理なのかなぁ・・・
0712デフォルトの名無しさん
2008/02/25(月) 17:26:040713デフォルトの名無しさん
2008/02/25(月) 17:39:36とか言いたいけど最低10年とかいう意見もあるし
やね某が何年か前に提唱した半年ぐらいで勘弁しておいてやろう
0714デフォルトの名無しさん
2008/02/25(月) 18:04:09"aa\0aa" + "bbbbb"はどのコンパイラでも、
"aa\0aabbbbb"ですよね?
0715デフォルトの名無しさん
2008/02/25(月) 18:38:410716デフォルトの名無しさん
2008/02/25(月) 18:39:190717デフォルトの名無しさん
2008/02/25(月) 18:43:10>>714はC++でもNGだろ。C文字列同士だぞ。
0718デフォルトの名無しさん
2008/02/25(月) 18:45:360719デフォルトの名無しさん
2008/02/25(月) 18:48:480720デフォルトの名無しさん
2008/02/25(月) 19:21:16アイアイ
0721デフォルトの名無しさん
2008/02/25(月) 19:30:23これって、AUTO変数と比べてより便利な点ってあるのでしょうか?
0722デフォルトの名無しさん
2008/02/25(月) 19:36:53○std::auto_ptrが破棄されたときインスタンスも自動的に開放
0723デフォルトの名無しさん
2008/02/25(月) 19:37:01・スタックに置くには適さない巨大なデータも置ける
・最初はNULLにしておいて必要になってからnewできる
・ブロックを出るまで待たなくても好きなタイミングで削除できる
・releaseで手放せばブロックを出ても削除しないことも出来る
0724デフォルトの名無しさん
2008/02/25(月) 19:39:100725デフォルトの名無しさん
2008/02/25(月) 19:41:51string func1() {
string s = "Hello";
return s;
}
void func2(string s) {
cout << s << endl;
}
int main() {
func2(func1());
}
この渡し方って解放されなかったり破壊されたりしますか?
処理系によりけりですか?
0726デフォルトの名無しさん
2008/02/25(月) 19:43:39しません。
どの処理系でも平気。
0727デフォルトの名無しさん
2008/02/25(月) 19:59:12ありがとうです。
ところで、testは適当なクラスとして、
int main()
{
std::auto_ptr<test> tp(new test);
tp.release();
return 0;
}
とすると、メモリリークが検出されてしまうのですが、tp.release()をしないようにすると
大丈夫でした。これってrelease()の使い方が間違ってますか?
あと、最初にauto_ptr<test>だけ宣言しておいて、途中でnew testする方法もわかりません。
もうちょっとだけ教えてくださいな。
0728デフォルトの名無しさん
2008/02/25(月) 20:05:080729デフォルトの名無しさん
2008/02/25(月) 20:14:08最初は、
std::auto_ptr<test> tp(new test);
tp.release();
test* tp2 = tp.get();
delete tp2;
としていたのですが、以下のようにしなければならないということですね。
std::auto_ptr<test> tp(new test);
delete tp.release();
ありがとうございました。
0730デフォルトの名無しさん
2008/02/25(月) 20:27:13tp.reset();
0731デフォルトの名無しさん
2008/02/25(月) 20:44:230732デフォルトの名無しさん
2008/02/25(月) 20:52:38729のようなことをしていないか不安。
0733デフォルトの名無しさん
2008/02/25(月) 20:58:49例えばコンストラクタとデストラクタで確保&解放を行う為に全体をそれに合わせたり
それの為にメソッドやクラスを用意したり等々
確かに見通しもよくなりますし、わかりやすくなるとは思うのですが、
それらを犠牲にすれば短く出来たりオーバーヘッドを減らせたり出来るんじゃないか?と考えてしまいます
つまりコード全体の見易さ、転じてメンテナンスが容易になるなどのメリットと
速度を犠牲にするというデメリットがあると思います
とはいえ後者は今時気にするほどでもなく、詳しくないのですがここを気にするのは組み込み系と呼ばれる分野くらいなのかなとも思います
実際はやはり見易さ等を気にした手法(なんていうんだろう?)を用いて設計を行うべきなんでしょうか?
うまく表現できなく、長くなってしまってすみません
0734デフォルトの名無しさん
2008/02/25(月) 21:01:160735デフォルトの名無しさん
2008/02/25(月) 21:04:18フルパス指定しなくて読み込めるんですか?
C:\Program Files\Microsoft Visual Studio 8\VC\include
でOK?
0736デフォルトの名無しさん
2008/02/25(月) 21:06:29ソースファイルと同じ場所なら
#include"hoge.h"
でおk
0737デフォルトの名無しさん
2008/02/25(月) 21:09:06大丈夫
君よりコンパイラのほうが賢いから
0738デフォルトの名無しさん
2008/02/25(月) 21:09:180739デフォルトの名無しさん
2008/02/25(月) 21:10:010740デフォルトの名無しさん
2008/02/25(月) 21:11:48std::sort が qsort より概して速くなる、というみたいに、
インライン化されると問題ないことも多い。
0741デフォルトの名無しさん
2008/02/25(月) 21:14:36色んな分野があるって前提で考えてるんだろう?
お前は組み込み系とビジネスソフト開発が同じだと思っているのか?
それにプログラミングしてればみんなプログラマって思考が気持ち悪い
お前見たいのは答える側に回るな
0742デフォルトの名無しさん
2008/02/25(月) 21:14:59でもやっぱり速度は気にしちゃいけないところですか、無駄だと思ってしまうところから直す必要がありそうですね
コンパイラの最適化というのも知らない分野ですし、当分は見通しの良いプログラムを目指してみようと思います
0743デフォルトの名無しさん
2008/02/25(月) 21:18:54そして遅ければ改善する。
この順だな。
0744696
2008/02/25(月) 21:19:34先ほどのプログラムを訂正したら、
一行ほどしか出力されませんでした。
どこが間違っているのでしょうか。
ttp://www.borujoa.org/upload/source/upload17009.txt
0745デフォルトの名無しさん
2008/02/25(月) 21:26:58いまいち組み方がわかりません。環境はLinuxでコンパイラはgccです。
#includeは省略
#define max 50
using namespace std;
class hist{
private:
string buffer;
int count;
int mat[max],i,j;
public:
int func(char *argv[]);};
int hist::func(char *argv[]){
ifstream fin(argv[1]);
if(!fin)return 0;
for(i=0;i<max;i++)mat[i]=0;
while(fin>>buffer){
count=strlen(buffer.c_str());
for(i=1;i<max;i++){
if(i==count)mat[i]=mat[i]+1; }
}
for(i=1;i<max;i++){
cout<<i;
for(j=0;j<mat[i];j++)cout<<"*";
cout<<'\n'; }
return 0;}
int main(int argc,char *argv[]){
hist hoge;
hoge.func(argv);
return 0;
}
0746696
2008/02/25(月) 21:28:43どなたか教えてください。
0747デフォルトの名無しさん
2008/02/25(月) 21:32:490748744
2008/02/25(月) 21:37:58そんなソフトがあったんですかw
ありがとうございます。
しかしそれではコーディングトレーニングにならないので、
ソースコードでよろしくお願いいたします。
どう考えてもイメージがわかないもので質問した次第です。
0749デフォルトの名無しさん
2008/02/25(月) 21:44:30C++でプログラミングをしようと思っているのですが
開発環境等をどうしようか迷っています
将来的には
■ゲームを動かすプログラム(同人やエロゲのアプリ程度)
■補助ソフトやパッチ
■データを暗号化して格納するプログラム
等を作りたいと思っています
何かアドバイスがあればお願いします
0750デフォルトの名無しさん
2008/02/25(月) 21:45:47タダだし
0751744
2008/02/25(月) 21:48:04「C++の勉強したいんだがどの本買って勉強したらいいんですか?」
って聞いてるのと一緒だべ?
0752デフォルトの名無しさん
2008/02/25(月) 21:50:19私にもそんな時期がありました(マジで)
0753デフォルトの名無しさん
2008/02/25(月) 21:51:50プロファイルとってそこだけしぼって最適化すればいい。
最初から保守性犠牲にしてまでパフォーマンスチューニングが必要な分野って
限られてると思うよ。
0754デフォルトの名無しさん
2008/02/25(月) 21:55:02今からC++勉強するよりもおまいは吉里吉里勉強したほうが幸せになれると思う
0755744
2008/02/25(月) 22:06:01エニバディー、ティーチ ミーしてくれませんか?
0756デフォルトの名無しさん
2008/02/25(月) 22:16:44理解できずに挫折したか。
0757デフォルトの名無しさん
2008/02/25(月) 22:16:590758デフォルトの名無しさん
2008/02/25(月) 22:18:58関係はないが、とりあえずバッファを buffer_size しか確保してないのに
fgets で filesize 読もうとしてるのはヤバい。
0759デフォルトの名無しさん
2008/02/25(月) 22:28:27else if(count > 0)
0760744
2008/02/25(月) 22:29:05bufferはstring型でいこうとおもったんですが、
fin>>buffer;でやると、単語読み込みで一行読み込みにはならないし、
fgets(buffer.c_str(),filesize,fin);はコンパイラに怒られるし、
どうしようもないんで駆け込み寺としてここにきました。
たぶんこれも慣れた人なら簡単に直せるんだとは思いますが、
いままでC言語ばっかりやってたもんで、変な癖ついてるんです。
0761デフォルトの名無しさん
2008/02/25(月) 22:30:580762744
2008/02/25(月) 22:32:36K&Rにも載ってたんで知ってます。
0763デフォルトの名無しさん
2008/02/25(月) 22:32:53よくわからんが、
一行よむなら、std::.getline( fin, buffer );だが。むろん、finはifstream辺りの必要はある。
初めて"{"が存在する行をみつけたとき、上のifでcount++になって、
下のifも成立してでcount++で2になるんだが、そういうものなのかね?
0764デフォルトの名無しさん
2008/02/25(月) 22:33:420765デフォルトの名無しさん
2008/02/25(月) 22:35:10あと必要な物はやる気と根気ですかね?
>>751
"だべ"ってどういう意味ですか?
マルチリンガーじゃないので日本語以外わからないんです、本当にごめんなさい。
0766デフォルトの名無しさん
2008/02/25(月) 22:36:48キモス
0767744
2008/02/25(月) 22:43:14else ifですか。基本的なところ躓きました。
ありがとうございます。勉強になりました。
>>763
そんな関数があったんですか。
ちょっとgetlineの中をのぞいて使わせてもらいます。
>>764
Cアンサーブックのほうです。
バイブル本とか釣られてやってみたけど、
糞面白んないんで解くのやめました。
0768デフォルトの名無しさん
2008/02/25(月) 22:44:52string buf (n, '\0' );
&buf0]; ← これはchar*のところへ入れられる
と使うと便利だ 自動で消滅するし
0769744
2008/02/25(月) 23:06:24下のほうhtmlのタグみたいですね。
奥の手っぽいんでどうしようもないときに使ってみます。
ありがとうございました。
0770デフォルトの名無しさん
2008/02/25(月) 23:48:16さっき、恐らくは想定したと思われる仕様を完璧に満たすソースを書いたんだが、
反応がなかったから会社に置いてきちゃった。次に会社に出るのは3日後なんで、
後で寝ちゃわなければ軽く再現してみるよ。
0771デフォルトの名無しさん
2008/02/25(月) 23:57:46>次に会社に出るのは3日後なんで
何でだ?
0772デフォルトの名無しさん
2008/02/26(火) 00:01:47続きそうな文章だなw
0773デフォルトの名無しさん
2008/02/26(火) 00:08:58本体 > VC++
開発用ユーティリティ > TurboC++ Exploer (BCB)
でいいんでないの?
VC++はGUIアプリの構築はそれなりに手間かかるし、BCBは紙芝居の開発じゃ全然VCLの長所が生かせない。
0774デフォルトの名無しさん
2008/02/26(火) 00:16:21単に、明日明後日は客先直行直帰だから。
>>744
手直ししながら、「クラスにする必要ないじゃん」とか
「変数は極力局在化しろよな」とか「マクロシンボルは大文字だろ」とか
「入力にfgets()を使うなら出力はfputs()じゃないか」なんて乗りで
修正してたらこうなった。
#include <cstdio> #include <cstring>
#define BUFFER_SIZE 1000
int func(char *argv[]) {
FILE * fin = fopen(argv[1],"r");
if (fin == NULL) return 1;
unsigned count = 0;
char buffer[BUFFER_SIZE];
while(fgets(buffer, sizeof(buffer), fin)!=NULL) {
if (count == 0) {
if (strchr(buffer,'{') != NULL) {
fputs(buffer, stdout);
count++;
}
} else if (count > 0) {
if (strchr(buffer,'{') != NULL) count++;
if (strchr(buffer,'}') != NULL) count--;
fputs(buffer, stdout);
}
}
fclose(fin);
return 0;
}
int main(int argc,char *argv[]) {
return func(argv);
}
0775744
2008/02/26(火) 00:36:44まぁ人には癖があるからね。
ありがとう。
人と自分のソースを比較するのが、
一番勉強になるよ。
0776デフォルトの名無しさん
2008/02/26(火) 00:45:12>774は常套句の宝庫だと思うよ。fgets(buffer, sizeof(buffer), fin)とか。
>744のクラスは、変数をばら撒くだけでクラスとしては何もしない無意味な設計だったし。
後はあれだな、関数に渡すのはconst char *にしてmain()で予めargcのチェックと
argv[1]の抽出位しておくのが常套手段か。
0777744
2008/02/26(火) 00:57:36途中で配列にしたら楽だろうなぁとかは思ったが、
配列だと途中でサイズの変更が利かないから。
ポインタだと動的メモリの割り当てで適当なサイズに
割り当てできるし、と思っただけです。
別に機能さえあってればどのやりかたでもいいんだけど、
個人的には
stdoutの使い方がいまいちわかんなかったから、
そこが勉強になったのと、マクロの名前が大文字ね。
それ完全に忘れてたから勉強になった。
ありがとうってのは主にそこかなぁ・・・。
クラスは再利用に機能を発揮するから今の段階では必要としていないけど、
あとあと拡張していくにあたって必要になってくるから残しておきました。
確かにこの辺は言わんとわからんかったかもしれない。
突っ込まれたんで補足しておきました。
0778デフォルトの名無しさん
2008/02/26(火) 05:08:28ありがとう、ちょっと不安だったんだ。
名前も無いまま渡されるオブジェクトってどうなるんだろ、って。
0779デフォルトの名無しさん
2008/02/26(火) 05:56:26返してもらうにはどう書けばよいのでしょう?
BOOL hoge( HOGE *ptr )
{
…略
ptr = address;
return TRUE;
}
としても上手く動かないようです。
0780デフォルトの名無しさん
2008/02/26(火) 06:00:17整数を受け取るには整数のポインタを渡す必要がある。
構造体を受け取るには構造体のポインタを渡す必要がある。
構造体のポインタを受け取るには構造体のポインタのポインタを渡す必要がある。
0781デフォルトの名無しさん
2008/02/26(火) 06:03:19BOOL hoge( HOGE **ptr )
ちなみにC++なのですが、参照渡しを使ってこれは良いのでしょうか?
BOOL hoge( HOGE *&ptr )
一応コンパイルは通るのですが…
0782デフォルトの名無しさん
2008/02/26(火) 07:25:270783デフォルトの名無しさん
2008/02/26(火) 11:34:24ある場合には、親オブジェクトから子オブジェクトを通して親オブジェクトのprivateデータを
参照できたのですが、これってこういうもの?
#include <iostream>
using namespace std;
class test2;
class test {
public:
void func(const test2 &a);
private:
int p;
};
class test2 : public test {
public:
void func2(const test2 &a);
};
void test::func(const test2 &a) {
cout << a.p << endl;
}
test2 T2;
int main()
{
test t;
t.func(T2);
return 0;
}
0784デフォルトの名無しさん
2008/02/26(火) 11:37:480785デフォルトの名無しさん
2008/02/26(火) 11:40:09というか出来ないとまずいだろ。
コピーコンストラクタとか代入演算子の定義が出来なくなってしまうよ。
0786デフォルトの名無しさん
2008/02/26(火) 12:06:040787デフォルトの名無しさん
2008/02/26(火) 12:22:230788デフォルトの名無しさん
2008/02/26(火) 13:01:03機能のスタティックリンクできるライブラリをご存じないでしょうか?
環境はVisualC++.net2003です。
0789デフォルトの名無しさん
2008/02/26(火) 13:07:03zlib
0790デフォルトの名無しさん
2008/02/26(火) 13:30:25同じクラスのインスタンスへの参照やポインタを持つとアクセス権限ブッチぎれちゃうのか
なんかカプセル化とかそういう面で考えると気持ち悪いというかなんというか
仕様上出来ないと仕方ないと言うのも分かるのだが・・・
0791デフォルトの名無しさん
2008/02/26(火) 13:33:530792デフォルトの名無しさん
2008/02/26(火) 13:34:460793デフォルトの名無しさん
2008/02/26(火) 14:02:36すみません、寝てました。返答有難うございます。
ちなみに「ポインタ変数を参照で渡す」と言う意味ならむしろ
BOOL hoge( HOGE &*ptr )
のような気がするのですが、なんで*&ptrなのでしょう?
それが仕様と言われればそこまでですが。
0794デフォルトの名無しさん
2008/02/26(火) 14:24:18http://kmaebashi.com/programmer/pointer.html
これの応用。
ptrのほうからreference to pointer to HOGEと読める。
0795デフォルトの名無しさん
2008/02/26(火) 14:26:03typedef HOGE * HOGE_PTRしてみれば判る。
0796デフォルトの名無しさん
2008/02/26(火) 14:37:54なるほど。正直きちんと理解できたかは自信ないですが、ちゃんと法則が
あってそうなっているのは分かりました。
どうも有難うございましたm(__)m
■ このスレッドは過去ログ倉庫に格納されています