>>300 マクロを使うか
C++でテンプレートを使うか
>>300 何がしたいかよくわからんけど共用体使えないの?
引数の型が違う同名の関数を作れたような……?
304 :
デフォルトの名無しさん:2011/03/18(金) 17:53:10.28
307 :
デフォルトの名無しさん:2011/03/18(金) 18:34:31.62
C言語が難しすぎる。
310 :
デフォルトの名無しさん:2011/03/18(金) 20:29:25.67
>>308 openモードが間違っている
ios::app で OR を取りましょう
appで開くとシークが不可能になって、先頭にデータの個数を
出力できないと思うのですが・・・
312 :
デフォルトの名無しさん:2011/03/18(金) 22:16:06.23
>>311 appは書き込みの時のみファイルの最後に自動的にシークされます
読み込みもしたいのならios::inもORしておけばよいです
問題のプログラムはios::ateでopenしているので、ファイルを開いた
後にファイルの最後にseekするようになっています
Jout.seekp(0, ios::end);
で、自分でファイルの最後にseekしてから書き込みしているので、
既に書いた部分の上書きはされないと思います
app は書き込みポインタを移動しても必ず最後に書き込まれるフラグですよね
でもそれじゃ困ります
ファイルをオープンした後、ファイルの一番最初にシークして
データの個数を書き込んでから、また最後にシークして新たなデータを追加しなければいけないので
具体的に説明すると、例えば一回目のデータを書き込むと
1
『追加データ1』
2回目は
2
『追加データ1』
『追加データ2』
って感じです
ただ単にデータを追加するのではなく、一番最初にデータの個数を書き込みます
データを表示させるときに、このデータの個数を読み込んで、個数分while文で表示するためです
だから僕はあえてateにしてるんだと解釈してるんですが、違うんでしょうか?
C言語スレで続けるなよw
315 :
デフォルトの名無しさん:2011/03/19(土) 00:31:35.56
あと最後に一つだけ
ios::nocreateは非標準ですので、動作は環境依存なので使わない方が無難です
C++で書かれたソースをCで書き直したいのですが、
ダブルコロンの置き換えがよく分かりません。
何の機能がCでは何に当たるのか、を調べる方法ありませんか。
c++覚えたほうが早いんじゃね?
>>317 当たるものはないよ
しいて言うなら命名規則で
アンダーバーやキャメル、プリフィックス、サフィックスなどで
工夫するぐらいしかない
CSTLなどありものの作法に倣うのが楽じゃないかな
>>317 C++ の :: は名前空間
C で名前空間相当の処理を行う場合は接頭辞を使う
接頭辞というのは、gtk_init(), gtk_main() の様に先頭の数文字を同じ単語で揃える事
接頭辞とそれ以外の部分は _ で繋ぐ
つまり、C++ の foo::bar は C で接頭辞を使うと foo_bar になる
ただし std::vector を C で std_vector とした所でそのまま動く訳じゃないよ
std_vector というのは C には存在していないから、自分で実装する必要がある
自分で実装するのは面倒なので、C++ から一行ずつ置き換えるという考えはやめて、
ファイル単位で大体似た様な処理を一から書いて行った方が良いと思われ
みなさんありがとう
>>309 298です。
2ちゃんねる使うの初めてだから、これでいいのだろうか。
レスありがとうございます。
ダウンロードしてみます
323 :
デフォルトの名無しさん:2011/03/19(土) 14:54:38.87
どういたしまして
内部リンケージのグローバル変数を関数越しに値が変更できるのって変に思うんだけど普通?
普通。
そっか。
327 :
313:2011/03/19(土) 17:16:03.23
313です
ちゃんと
>>1を読んでいませんでした
本当に申し訳ないです
>>315さんの紹介してくださったスレで再度質問したいと思います
僕の質問に回答してくださった方、ありがとうございました
とても参考になりました
内部リンケージのグローバル変数 = private変数
ポインタってどんなときでも
*があれば「そのアドレスにある値の操作」で
なければ「アドレスそのものに対する操作」を
意味するという理解でいいのですか。
>329
だいぶ用語が粗っぽくて、何も理解できていないのではないかと思う。
単に「ポインタ」といっても、型、変数、値があることを意識しなくてはならない。
しかし、普通は文脈で判る場合が多く、単に「ポインタ」と言われる。
前の文章を書き直すと
「ポインタの値」に対して「前置単項演算子*」を適用して評価すると、
評価結果はポインタが指すオブジェクトである。
相手に理解させる気のない知識の垂れ流しってただのオナニーだよね
332 :
デフォルトの名無しさん:2011/03/20(日) 14:18:11.86
>>329 「どんなときでも」ではないが、当初それでいい
あとで出てくる char **argv; などは * があってもアドレスだったりするし
void *ptr; は * で値にすることができない
誰とは言わんが
> 「ポインタの値」に対して「前置単項演算子*」を適用して評価すると、
前置でない単項はないから安心しろ
こいつ冗長な形容で小難しく書き直しているだけで
話がほとんどピーマンだよ
おまわりさんこっちです
散!!!
336 :
デフォルトの名無しさん:2011/03/20(日) 15:45:13.95
消防レベルの自分にC言語がすごい分かりやすい
サイトなどを教えてください。
関数とかわけわかりませんw
関数ってのは計算をしてくれる機械
y=f(x) のfだね
339 :
デフォルトの名無しさん:2011/03/20(日) 16:10:00.12
C
341 :
デフォルトの名無しさん:2011/03/20(日) 22:17:45.98
ポインタでつまづいてる初学者なんですけど、
勉強しながらある程度少しは実用的なプログラム習得できる書籍かサイトご存じでしょうか?
AmazonのC言語関連書籍一通り見ましたが、しっくりくるのがなかったので。
仕事はプログラミング全く関係ないです。
ポインタの用法
第一ステップ:引数をポインタにして、関数で参照渡しに相当することが
出来るようになろう。
第二ステップ:malloc/freeで変数を動的に生成しよう。NULLの使い方も
学ぼう
第三ステップ:配列とポインタの意図的混同に関連する慣習を
学ぼう
第四ステップ:構造体のメンバにポインタを用いることにより
リストや木などの高度なデータ型を取り扱えるようになろう。
第五ステップ:◆QZaw55cn4cのように皆に嫌われ者になろう。
344 :
330:2011/03/21(月) 00:14:55.51
>331>332
たしかにいきなり小難しい説明をしてしまった。あとで読み返して、
まずったとおもった。申し訳ない。
しかし、正しい用語を使うことは正しい理解につながると思って、
あのような表現になっている。もう少し噛み砕くべきだった。
>329>332
>ポインタってどんなときでも*があれば
>前置でない単項はないから安心しろ
たしかに単行*は前置しか無いから冗長な表現だった。
しかし*は、(前置)単項演算子、二項演算子、ポインタ宣言子
として登場するので、意識してもらうために明示した。
>char **argv; などは * があってもアドレスだったりするし
char **argv;の場合、
argvはchar *を指すポインタ
それに間接演算子*を適用すると、評価結果は指している
オブジェクトとなるので、その型がchar *になるだけで、
全く話は同じ。
>void *ptr; は * で値にすることができない
void *のことは失念していた。指しているオブジェクトサイズが
不定である場合は演算子*,[]を適用できない。
×皆に嫌われ者になろう。
○皆に嫌われる者になろう。
bitter smile
メモリ管理って誰がやんの?
OS?
ほしたら何でCでmallocしたメモリはフラングメントすんの?
ガベージコレクションが必要な理由は?
言語?
言語は単にOSに頼んでメモリ割り当てしてもらっただけで
それもなんか違う気もする
350 :
デフォルトの名無しさん:2011/03/21(月) 04:07:05.89
ていうか誰がメモリの本当のサイズを知ってるんだろうか
確保と開放を繰り返すとフラグメントする、ということは
確保されたぶんがそっくりそのまま開放されるというわけではないわけだ
いくらか少ない量、ってことだろ
このサイズは誰が知ってんの
プログラマがmallocでサイズを数値で見れても信用ならないって事だろ
>>349 >メモリ管理って誰がやんの?
主に OS
ただし、malloc() に関してはリンクされたライブラリもかかわっている。
>ほしたら何でCでmallocしたメモリはフラングメントすんの?
malloc() したメモリは普通 OS には返さない。
そう仮定した場合、「malloc() したメモリがフラグメントを起こす」のなら、その原因は malloc() のアルゴリズム。
>言語は単にOSに頼んでメモリ割り当てしてもらっただけで
メモリは OS からもらうが、再利用は malloc() が管理する。
Mr.マロック (うっうっうっううー)
353 :
デフォルトの名無しさん:2011/03/21(月) 07:34:41.81
わりにこっちには、な〜〜〜んも教えてくれんよな
肝心なことなのに
どうすんのさ
354 :
デフォルトの名無しさん:2011/03/21(月) 07:36:54.78
自分でやれってちゅうのもいいが、WindowsやLinuxだとサンダースがやらしてくれんだろ
355 :
デフォルトの名無しさん:2011/03/21(月) 07:43:28.44
やっぱし何ちゅうの?
メモリは1ビットたりとも無駄にしたくないわけやん。
しないほうがよい。
「できないからやらない、知る必要がない」ではポロろgグラマー失格なわけやん。
こういうとき組み込みなら、iTronだなんだのメモリ管理には世話になっても
自分でできる下地があるわけで、軽減は出来る。
ならWindowsやその他でもそうすべきだ。
356 :
デフォルトの名無しさん:2011/03/21(月) 10:26:43.26
>>355 Windows はもともと、そういう思想だったんだよ
>>347 自分の頭が悪い点にズバリ切り込まれるとjokeって事にするのですね。
どこまで馬鹿なんだお前は
お前らみずほ銀行のくそシステム組やがってどうにかしやがれ!
再帰関数について質問です。
void merge(int first int last int *A)
{
if(){
center=(first+last)/2@
void merge(first center *A)A・・・前半起点マージ
B
void merge(center+1 last *A )C・・・後半起点マージ
}}
mainで呼び出した関数で中に二つの自分と同じ関数がある再帰構造を持ってます。
で良く分からないのですが
Cのcenterは、@、Aのcenterの値と一致するのでしょうか?(※まぁlastもなんですが置いときます。)
再帰関数だからA→□1→□2→・□n→・・→□2→□1→Bと戻ってきて次にCの作業
をするので、Cのcenterの値は□1の部分の作業で設定されたcenterの値じゃないんでしょうか?
そうなると帰納的にcenter=一定値になると思うのですが、何か違いますか?再帰関数がややこしくて仕方ありません・・・
>>358 少なくとも、俺は関わってない。
また、銀行系のシステムで、この手のトラブルの原因となるコードが
Cで実装されてることは、滅多にないと思われ。
>>361 はいC言語です、お願いします。
マージソートのプログラムで、centerは真ん中の配列の添え字ですかね。
再帰関数によって分けて分けて、で作業の末端までいったら
今度はくっつけてくっつけて戻ってくるというプログラムです。たぶん・・
>>359 よくわからんが
>Cのcenterは、@、Aのcenterの値と一致するのでしょうか?(※まぁlastもなんですが置いときます。)
一致する
>Cのcenterの値は□1の部分の作業で設定されたcenterの値じゃないんでしょうか?
merge が呼ばれるたびに新しく center が作られる
printf("%d %d %d\n", first, last, center);を追加してどういう順番で呼び出されてるか見ればいいだろ
無駄な比較が多いな
>>359 void merge( int first, int last, int *A ) {
if() {
int center; // static int center; // ではない
center = ( first + last ) / 2; // @
void merge( first, center, A ); // A・・・前半起点マージ
// B
void merge( center + 1, last, A ); // C・・・後半起点マージ
}
}
だと仮定して
>Cのcenterは、@、Aのcenterの値と一致するのでしょうか?(※まぁlastもなんですが置いときます。)
一致します
>再帰関数だからA→□1→□2→・□n→・・→□2→□1→Bと戻ってきて次にCの作業
>をするので、Cのcenterの値は□1の部分の作業で設定されたcenterの値じゃないんでしょうか?
centerの型がstaticの場合、再起先と呼出元のcenterの値の格納先が同じ場所となり、
あなたの予想通り、値を上書きしてしまいますが、
今回の場合、staticは使用しないと考えられるので、再起先のcenterの値の格納先と
呼出元のcenterの値の格納先は異なる場所となるため、@・AはCと一致します。
Mr.マロック (うっうっうっううー)
while (!feof(f1)) {
ch = fgetc(f1);
if (!feof(f1))
fputc(ch, temp);
}
教本を読んでいてファイルの入出力の章でこのようなコードが出てきたのですが、
これだと例えば今f1はファイルの最後の文字の位置にあるとすると、
ch = fgetc(f1);でf1が示す位置が1つ先にずれEOFとなり、その後if(!feof(f1))でfputc(ch, temp);をするか判定しているので
最後の1文字がtempに出力されないで終わってしまう気がするのですがどうなんでしょうか。
実際コンパイルしてみると最後の文字までちゃんと出力されていたのですが……
全ソースはこちらに上げておきました tp://ideone.com/pVv1S
宜しくお願いします。
>371
何故f1の全ての内容がtempに書きこまれるのかがわかりません。
>370にも書いたのですが、if(!feof(f1))があるとその前にfgetc(f1)でf1が示す位置が既に1つ先に進んでいるので、
if文の中のfputc(ch, temp)が実行される回数が1回足りないで処理が終了してしまう気がします。
自分がこの部分を書こうと思って以下のようなコードを書いたのですが(色々違うものが挟まってますが)、
これだとtempにf1の内容のあとFF 00 00 00....(tempのバイト数が4KBになるまで)まで出力してしまいました。
なぜfputc(ch, temp)を実行する前にif(!eof(f1))を判定しなければならないのか教えて頂ければと思います。
while (!feof(f1)) {
ch = fgetc(f1);
if(ferror(f1)) {
puts("FILE1の読み込みエラー");
exit(2);
}
fputc(ch, temp);
if(ferror(temp)) {
puts("tempファイルの書き込みエラー");
exit(2);
}
}
1> screensource00103.cpp
1>d:\ワークステーション\ゲーム開発プロジェクト\rxz project laboratory\programs\rxz_ver0.01\screensource00103.cpp(40): error C2144: 構文エラー : 'void' は ';' によって先行されなければなりません。
該当の場所
・
・
・
(40)void bg_ctrl(){
(41) DrawGraph( 0 , 0 , Stage_BG , FALSE ) ;
(42)} /* リファレンス注釈7参照 */
(43)
・
・
・
すいません。
誤爆です。すいません。
よく見てませんでしたすいません><;
feofは最後の一文字を読み込んだときじゃなくて、EOFを読み込んだときに1を返すから
>373
あー…これは読み込んでいるファイルの末端にEOFがないってことです…かね?
しかしEOFがないのにどうやってfeof()で判断してるんでしょうか、わけがわからなく…
>376
EOFはどんなファイルの最後にもあるという勘違いをしてたようです、ありがとうございます
改めて考え直したのですが、そうするとif文は
if (!feof(f1))ではなくif(!ferror(f1))ではないのでしょうか
こうすればファイルの末端を超えたときその前のch = fgetc(f1);でエラーがでているはずで、処理を止めることができるという感じに
これはまた違うのでしょうか、申し訳ないのですがが宜しくお願いします。
っとすいません、if(error(f1))でした…
feofはファイルを最後まで読み込んだかを判定する、つまりEOFを読み込んだかどうかを判定する関数
fgetc()でchにEOFが入った後じゃないとfeofは1を返さない
>380
例えばテキストファイルで今末端の位置にいるとき、
<1回目>
while (!feof(f1)) { /* ファイルの末端での判定、当然実行される */
ch = fgetc(f1); /* chにファイルの末端の文字を代入*/
if (!feof(f1)) /* このときf1はファイルの末端の次にあるが、その読み出しはされていないのでfeof()は0を返す */
fputc(ch, temp); /* fputc()は行われる */
}
<2回目>
while (!feof(f1)) { /* ファイルの末端の次での判定、しかし上記と同様にしてfeof()は0を返し実行される */
ch = fgetc(f1); /* chにf1を代入しようとするが、末端を超えているので失敗し、EOF指示子がセットされる */
if (!feof(f1)) /* ここでfeof()はEOF指示子があるので1を返し、fputc()はスキップされる */
fputc(ch, temp);
}
<3回目>
上記と同様にして、while文は実行されず次の処理にうつる
こういうことでよろしいでしょうか……
>>370 while (1) {
if (feof(f1))
break;
ch = fgetc(f1);
fputc(ch, temp);
}
>382
前の処理がファイルの末端の文字だったとして、いまf1、tempがファイルの末端の次の位置になっているとしますと、
<1回目>
while (1) {
if (feof(f1)) /* EOF指定子がないのでfeof()は0を返し、実行されない */
break;
ch = fgetc(f1);
/* f1はファイルの末端の次なのでch = fgetc(f1)が実行されchにEOF(-1)が代入され(調べ直したら失敗するわけではないですね)、
EOF指定子がセットされる */
fputc(ch, temp); /* fputc(ch, temp)は実行され、tempにEOFが書きこまれる */
}
<2回目>
if(feof(f1))で条件が真となり、while文を抜ける
この場合だと結果的に>370でできるファイルの末尾にEOFが付加された形になるんでしょうか、解釈があっていればよいのですが
>>383 規格書読んで分からないなら
1つの標準関数ごとにデバッガ使ってトレースして
振る舞いを確かめるといいよ
IDEをつかえばコマンド覚えることなく誰にでも簡単に扱えるから。
>384
なるほど、了解です
一度落ち着いて整理し直し、色々試してみることにします
>>382 これはまずいです。
>>383 のような誤解を招きます。
for (;;) {
ch = fgetc(f1)
if (feof(f1))
break;
fputsc(ch, tmp);
}
とすべきです。読む→テストする→書く、というです。
C言語を始めたばかりの超初心者ですが、質問です。
strtokの返すアドレスというのは実質、文章の終わりまで置き換えが終わったかどうか確認するためだけに使うようなものなのでしょうか?
他の使い方もあります。と言うか他の使い方の方がメイン
そうなんですか
区切った記号までの文字列の先頭アドレスを返すと聞いたのですが、
例えばどのようなときに使うのでしょうか?
よかったらお願いします
>>387 等価じゃないと思いますよ。
>>382 ビットパターン 0xff をディスクリプタ tmp に書いてしまいますよ。
ビットパターン0xff は EOF を示すascii 制御コードですらなく、
オリジナルのディスクリプタ f の指すファイルの内容とは、変わってしまいますよ。
>>381,383
その解釈であっています。
>>370 のリンク先は、致命的に間違っています。
char ch; ではなく int ch; が正しい。
あと while(!eof())うんぬんは、教科書によくあらわれる書き方です。(たとえば、ハーバードシルト先生は信念があるのかいつもこう書きます。)
while() を無理に使うとこう書かざるを得ないのですが、私見では、残念ながら eof() が重複してしまい無駄ですね。
てか、これってC言語の話題?
C言語の標準ライブラリの仕様の話しだが、
今時C標準ライブラリが外部言語処理系に非公開な
プラットフォームってまずない。
だからこれは微妙にこれはOSの標準ストリームの
仕様の話になりそうな件
関係ないよ。eof()を使うのがタコ。
int ch;
while ((ch = fgetc(f1)) != EOF) {
fputc(ch, tmp);
}
>>383 EOFはファイルに書いてある値じゃないよ
既にファイルの最後まで読んでいるのになお更に読もうとした時にfgetc()が返してくる値
ファイルに書いてある値以外の値でEOFを表現しなければならないので、fgetc()の型はunsigned charじゃなくてint
ch = fgetc(f1);の次に即fputc(ch, temp);するのはまずい
>>395 アスキーコードのEOFにも対応しといてください。お願いします。
99BASIC
C言語において時間計算量について質問です。
マージソートの計算量は何故nlognなんですか?
例えば要素数16とします。
全て一つだけの配列に分けて、それを二つ配列にする比較回数が8回
二配列を四配列にする比較回数が3×4=12回
四配列を8配列 2×7=14回
最後8配列同士を比較して 15回
で合計49回ですよね?
n=16のとき
nlogn=1.2×16=19・・計算量19?
49とかけ離れてますよね?