C言語なら俺に聞け! Part 112
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2005/08/08(月) 01:32:01質問する前には最低限検索を。
GUIなどの標準Cではできない事の質問は使用している開発環境のスレへGo! (←ここ注目)
ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへさようなら。
エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。
C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/
C言語なら俺に聞け! Part 111
http://pc8.2ch.net/test/read.cgi/tech/1121657911/
他の過去ログはここに
http://nssearch.hp.infoseek.co.jp/clang/
0294293
2005/08/13(土) 22:12:310295デフォルトの名無しさん
2005/08/13(土) 22:27:14>>1
0296デフォルトの名無しさん
2005/08/13(土) 22:42:50argv[]は単なる文字列へのポインタ。
その文字列が、ファイル名かディレクトリ名か、
あるいは、その他の意味を持つ文字列かは、
コマンドラインで実行した本人以外は誰もわからん。
その文字列と同じ名前のファイルやディレクトリが
存在するか確認する方法はOS依存。
まあ、拡張子が付いていたらファイル、それ以外はディレクトリ、
ファイル名、ディレクトリ名に使用できない文字があったらエラーとか、
ファイルをオープンしにいって、成功したらファイル、それ以外はディレクトリとか、
そんな安易な実装でいいんだったら、純粋なCでも可能だけど。
0297デフォルトの名無しさん
2005/08/13(土) 23:04:40そんな安易な実装について聞いているんだろ
OS依存といってもPOSIX準拠な方法があるんだから
もうstatでいいじゃん。面倒くさい。
0298デフォルトの名無しさん
2005/08/13(土) 23:10:160299293
2005/08/13(土) 23:42:56statをmsdnで調べて出来ました!
ありがとうございました。
>>296
決して安易という訳ではないんですが、
こういうシステム依存の部分て調べ辛くて…
文法とかアルゴリズムは良く見つかるんですけどね。
>>295
言いたいことはよく分かるのですが、
正直、1のリンクからは見つけられませんでした。
0300デフォルトの名無しさん
2005/08/13(土) 23:55:13>>296みたいなのは長々と書いてるだけで何の情報も無い
長文結構だが、その中にこっそり情報混ぜてやれよ
こういう>>293みたいなやつにはヒントをあげるだけでいいんだよ。
問題はそのヒントのセンス。
0301デフォルトの名無しさん
2005/08/14(日) 00:13:280302デフォルトの名無しさん
2005/08/14(日) 03:45:390303デフォルトの名無しさん
2005/08/14(日) 04:25:250304デフォルトの名無しさん
2005/08/14(日) 05:51:39俺だって勉強してると言わんばかりに
とくいげに無駄話ばかり続ける状態。
0305デフォルトの名無しさん
2005/08/14(日) 12:03:390306デフォルトの名無しさん
2005/08/14(日) 12:06:270307デフォルトの名無しさん
2005/08/14(日) 12:06:43%x使うのが一番楽。
0308デフォルトの名無しさん
2005/08/14(日) 12:11:280309デフォルトの名無しさん
2005/08/14(日) 12:12:16勉強しようとしたんですが、わからない事があります。
Microsoft Visual C++ .NET にて
/*hello.c*/
#include <stdio.h>
int main()
{
printf(
"Hello ""World\n");
return 0;
}
というのをビルドしたんですが
error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 _WinMainCRTStartup で参照されました。
fatal error LNK1120: 外部参照 1 が未解決です。
と、エラーが二つでます。 どうしたらいいのでしょうか?
設定があるのですか? それともソースを変えなきゃ行けないのでしょうか?
0310デフォルトの名無しさん
2005/08/14(日) 12:15:280311デフォルトの名無しさん
2005/08/14(日) 13:50:55Windowsプログラミングのスレで聞いてくださいね
0312デフォルトの名無しさん
2005/08/14(日) 14:05:2216で割った余りを調べて10-15をa-fに変換して配列に入れる
商が0になるまで続ける
配列を%sで出力
0313デフォルトの名無しさん
2005/08/14(日) 14:09:22ttp://www.kumei.ne.jp/c_lang/
そしてここを見て設定しなおせ
ttp://www.kumei.ne.jp/c_lang/net/index.html
0314デフォルトの名無しさん
2005/08/14(日) 14:10:05>>309な
0315305
2005/08/14(日) 16:00:43ありがとうございます。
ファイルからデータ読み込む方法はfgetcを使用してるんですが、
漢字が上手く取り込めません。16進数表示部が文字化けしてしまいます。
0316デフォルトの名無しさん
2005/08/14(日) 16:07:41宿題スレでコードで解答もらってんじゃん
0317デフォルトの名無しさん
2005/08/14(日) 16:11:55文字化け…?
fgetcの戻り値はただの整数だから化けることはないと思うけど。
言い忘れたけど配列の最後には必ずNULLを入れること。
0318デフォルトの名無しさん
2005/08/14(日) 19:09:320319デフォルトの名無しさん
2005/08/14(日) 19:18:27ライブラリに依存する
0320デフォルトの名無しさん
2005/08/14(日) 19:18:42じゃなくてコンパイラ付属のライブラリ
(あれ?winな環境だとAPIとかでOSなのか?)
0321デフォルトの名無しさん
2005/08/14(日) 19:34:12ないない。
UNIX系なら仮想ファイルで乱数取得が可能かも知れんけど
0322デフォルトの名無しさん
2005/08/14(日) 20:36:23typedef func_t (*func_t)(obj_t *obj);
func_t func1(obj_t *obj);
func_t func2(obj_t *obj);
func_t func3(obj_t *obj);
のように。(実際にはこうは書けない)
typedef void *(*func_t)(obj_t *obj);
void *func1(obj_t *obj);
...
こんな感じに書いて、あとは必要に応じてキャストすれば済むには済むんですが、気になったもので……。
0323デフォルトの名無しさん
2005/08/14(日) 21:03:59できませんC++でtemplate使いなさい
0324デフォルトの名無しさん
2005/08/14(日) 22:53:04挿入ソートが他の2つよりも3倍以上早かったんですがそんなものなんでしょうか?
3つともO(n^2)とどこかでみたのですが
0325324
2005/08/14(日) 22:53:350326デフォルトの名無しさん
2005/08/14(日) 22:55:27実は効率よく終わるように考慮されているロジックであれば一番速かったりする
0327デフォルトの名無しさん
2005/08/14(日) 22:59:20こんな感じなのですが、これが基本形ですよね?
void bubble(int *d,int n)
{
int i,j;
for(i=0;i<n-1;i++){
for(j=n-1;j>i;j--)
if(d[j]<d[j-1]) swap(d[j],d[j-1]);
}
}
void insert(int *d,int n)
{
int i,j;
for(i=1;i<n;i++){
int temp=d[i];
for(j=i;j>0 && d[j-1]>temp;j--)
d[j]=d[j-1];
d[j]=temp;
}
}
0328デフォルトの名無しさん
2005/08/14(日) 23:36:370329デフォルトの名無しさん
2005/08/14(日) 23:41:02Oは問題の大きさに対して計算量がどう増加するかを表わすもので、
計算量そのものを表わすものじゃないし。
0330デフォルトの名無しさん
2005/08/14(日) 23:42:58たとえば昇順にソートしたいとき、降順にソート済みの入力でためしとけ
0331デフォルトの名無しさん
2005/08/15(月) 04:17:310332デフォルトの名無しさん
2005/08/15(月) 09:18:140333デフォルトの名無しさん
2005/08/15(月) 09:43:50ウソです。
0334デフォルトの名無しさん
2005/08/15(月) 09:56:35そうですか
レス乙です
ヤッパリ老舗のCが良いんですか?
0335デフォルトの名無しさん
2005/08/15(月) 10:00:070336デフォルトの名無しさん
2005/08/15(月) 10:03:390337デフォルトの名無しさん
2005/08/15(月) 10:06:28ググったらマジで有りましたオメガですか・・・
0338デフォルトの名無しさん
2005/08/15(月) 10:08:440339デフォルトの名無しさん
2005/08/15(月) 10:14:300340デフォルトの名無しさん
2005/08/15(月) 10:24:520341デフォルトの名無しさん
2005/08/15(月) 10:25:00頼むからJavaに移ってくれ…という香具師もいる
0342デフォルトの名無しさん
2005/08/15(月) 10:33:25なんでもかんでもCで作る時代は MS-DOS の時代に終った。
0343デフォルトの名無しさん
2005/08/15(月) 10:41:16付けてバンク切り替えで記憶容量は増やすことが出来たがそれでも数M
だった。CPUクロックも 16MHz, 33MHz, 66MHz など、MHz 単位で
3桁に満たなかった。そのような状態だったので当時あらゆる開発に
C言語を使うことは現実的な選択だったのだ。C言語であれば容量が小さく
高速なプログラムがアセンブラで組むよりはるかに楽に作れたからだ。
0344デフォルトの名無しさん
2005/08/15(月) 10:54:48初心者はC++・C#よりCから始めた方が良いのでしょうか
0345デフォルトの名無しさん
2005/08/15(月) 11:45:50なんでも質問すれとか初心者歓迎C/C++スレとかあるだろ。
0346デフォルトの名無しさん
2005/08/15(月) 11:53:28でも答えてくれて、あんがと
0347デフォルトの名無しさん
2005/08/15(月) 12:13:440348デフォルトの名無しさん
2005/08/15(月) 14:45:42DOSでCが使われるようになったってのも、90年代に入ってからで、
それ以前はアセンブラが多かったとおもう。
0349デフォルトの名無しさん
2005/08/15(月) 14:53:41TURBO PASCAL がかなり使われてた。その後はLattice C。
MSCが使われだしたのはWindows3.x以降、コンパイラがDPMIなしじゃまともに動かなかった。
0350デフォルトの名無しさん
2005/08/15(月) 15:00:49VZがasmだったのは確かだけど。
0351デフォルトの名無しさん
2005/08/15(月) 18:00:57すぐにTurboCをはじめ低価格Cコンパイラで、Cブームに。
0352デフォルトの名無しさん
2005/08/15(月) 18:44:40TURBO PASCALが一番使われてたのはCP/MからMS-DOS2.11あたりの時代。
フロッピーディスクベースでエディタ+高速コンパイルが売りだった。
まだN88DISK-BASICと張り合ってた。
MS-DOS3,1まではMicrosoftもDOSの外部コマンドの作成などにLattice-Cを使ってた。
MS-Cが登場し、TurboCなどの低価格Cブームが来るのはこの後。
0353デフォルトの名無しさん
2005/08/15(月) 19:06:570354デフォルトの名無しさん
2005/08/15(月) 19:23:36盂蘭盆会で地獄の釜が開いてるんだ、今日は大目に見てくれ。
0355デフォルトの名無しさん
2005/08/15(月) 19:50:43Cの初心者、宿題系に、軒並みバカがはりついてるみたいだからそこに帰れ。
0356デフォルトの名無しさん
2005/08/15(月) 21:00:56int main(void)
{
float fbuff,ftmp;
int i;
for (i = 5;i <= 8;i++){
ftmp = 0;
switch(i){
case 5:
ftmp = 10 * i;
break;
case 6:
ftmp = 1 * i;
break;
case 7:
ftmp = 0.1 * i;
break;
case 8:
ftmp = 0.01 * i;
break;
}
if (i == 0){
fbuff = 0;
}
fbuff = fbuff + ftmp;
printf("ftmp = %f\n",ftmp);
printf("fbuff = %f ftmp = %f\n",fbuff,ftmp);
}
return 0;
}
実行結果が下記になる理由を教えて下さい。どうして「0.000003」多くなるのでしょうか?
fbuff = 56.780003 ftmp = 0.080000
0357デフォルトの名無しさん
2005/08/15(月) 21:09:230358デフォルトの名無しさん
2005/08/15(月) 21:20:44一般的にfloatの精度は23ビット、即ち高々7桁しかない。
従って、有効なのはは56.78000までが関の山。
%fの代わりに%gを使うことで、誤差を余り見ないで済むかもしれない。
尤も、素直にdoubleを使っとけと言う話になるが。
0359356
2005/08/15(月) 21:22:01ありがとうございました。
0360デフォルトの名無しさん
2005/08/16(火) 10:54:11ファイル内のバイナリの数字の羅列に対して、CSV処理するコマンドを作りたいです。
コマンドの引数として、別のファイルの定数一覧からCSVの区切り文字数を受け取って
処理させるものを作りたいと思っていますが、どう作っていけばいいのか分かりません。
どんな感じで作る物なのか、ヒントかもしくは
参考にしやすいサンプルソースを見れるサイトがあったら教えていただきたいです。
0361デフォルトの名無しさん
2005/08/16(火) 12:12:25>ファイル内のバイナリの数字の羅列に対して、CSV処理するコマンドを作りたいです。
具体例をあげて何がしたいのか説明して。
0362デフォルトの名無しさん
2005/08/16(火) 12:16:53#include <stdio.h>
#defineN 1000 /* Nまでの素数を求める*/
#defineTRUE 1 /* 真:素数である */
#defineFALSE 0 /* 偽:素数でない */
charis_prime[ N+1 ]; /* 結果を格納する配列*/
int main( void )
{
int i, j;
/* 配列を初期化 */
for( i = 1; i <= N; i++ )
{
is_prime[ i ] = TRUE; /* 最初はすべて「素数」とする */
}
is_prime[ 1 ] = FALSE;
/* エラトステネスのふるい */
for( i = 2; i*i <= N; i++ )
if ( is_prime[ i ] )
for( j = i*2; j <= N; j += i )
is_prime[ j ] = FALSE; /* この倍数は「素数」でない */
/* 結果の出力 */
printf( "%dまでの素数は、\n", N );
for( i = 1; i <= N; i++ )
if ( is_prime[ i ] )
printf( "%d ", i );
return 0;
}
0363デフォルトの名無しさん
2005/08/16(火) 12:19:48>>1読め。ここは「C言語」自身に関して、だから
プログラムの組み方、等は激しくスレ違い。
0364デフォルトの名無しさん
2005/08/16(火) 12:22:16最初のfor文のi*iの意味、次のif文に論理演算子がないこと、次のfor文のi*2の意味
がわかりません。
そこがわからないので結果の出力のfor文とif文もわからないです。
ネットでも調べたり本でも調べたんですけど、他のソースは別の書き方をしていて
そのやり方なら理解できるのですが、このソースはちょっとわからないのでよろしくお願いします。
0365デフォルトの名無しさん
2005/08/16(火) 12:42:25>最初の for の i*i の意味
ある数の約数の片方は必ず平方根以下であるから。
逆に考えると、約数( = i )の2乗が合成数以下。
>次の if 文に論理演算子がない
C の条件判断は、0 以外で真。
つまり、#define された TRUE が入ってれば真になる。
そもそも C には本当の意味での bool 型がないから整数で代用してる。
>その次の for の i*2 の意味
さらにその次の行のコメントのとおり、
素数の *2 *3 *4 …を約数でないとするため、
i*2 i*3 i*4…の数列を作るための for 文。
こんな感じでどうよ?
0366デフォルトの名無しさん
2005/08/16(火) 13:14:29ある数の約数の片方は必ず平方根以下であるから。
逆に考えると、約数( = i )の2乗が合成数以下。
これはわかりました。
>、#define された TRUE が入ってれば真になる。
そもそも C には本当の意味での bool 型がないから整数で代用してる。
if文のis_prime[i]が整数で代用してるってことですか?ここら辺がちょっとわからないんですけど。
s_prime[i]は確かに整数・・・ああ、なんとなくわかってきた気がします。
s_prime[i]の要素の整数とif文の条件判断で使う1,0の整数と整数は二つありますね。
1,0の整数のことですね。ただif ( is_prime[ i ] ) の括弧の中がis_prime[ i ] !=0とかとなっていないのがわからないです。
何かの省略なんでしょうか?
>素数の *2 *3 *4 …を約数でないとするため、
i*2 i*3 i*4…の数列を作るための for 文。
i*2の2がわからないです。jがカウントアップしていきますよね。
そのときに2が変数でカウントアップしていかないと常に2の倍数になってしまうと思うのですが、
すぐ答えていただきありがとうございます。できればもうちょっとだけ上記のヒントを下さい。
0367デフォルトの名無しさん
2005/08/16(火) 13:50:06つ[if文の定義]
0368365
2005/08/16(火) 14:14:47>if ( is_prime[ i ] ) の括弧の中がis_prime[ i ] !=0とかとなっていないのがわからないです。
if 文は 真/偽 を判断する、と考えてるとそういう思考に陥ります。
まず定義として if 文は、条件として与えるものは整数で、「0 か否か」を「偽 or 真」として判断します。
そして、!= とか == などの演算子は、0 かそれ以外の値をとる整数値になります。
よって、 たとえば (12 == 13) という条件文は「偽」ではなく 0 という "整数" をとります。
>そのときに2が変数でカウントアップしていかないと常に2の倍数になってしまうと思う
2が変数ってどういうことでしょうか?
for( j = i*2; j <= N; j += i )
i*2 は最初の j の値で、二週目以降 i ずつ増えます。
つまり、i*2、i*2+i、i*2+i+i、…となるわけで、i*2 i*3 i*4…となるわけです。
0369デフォルトの名無しさん
2005/08/16(火) 15:27:07いつ開放されるのでしょうか。
関数の中で新たにヒープに割り当てて、そのアドレスを返したりしているのだったら、
あとでfreeなどで開放してやらないとマズイと思うのですが、
標準関数のlocaltimeなんかはそんなことしませんし。
その辺の解説してもらえるとありがたいです。
0370デフォルトの名無しさん
2005/08/16(火) 15:48:410371デフォルトの名無しさん
2005/08/16(火) 15:53:48libc の localtime は、static な構造体へのポインタを返したり、
内部で自動確保&終了時に自動破棄しています。
そのため、受け取ったポインタを明示的に破棄する必要はありません。
ただし、前者はマルチスレッドの時に問題を引き起こす可能性がある
( 排他処理すればいいけどね ) ので、あまりおすすめはされない手法です。
そんなわけで生存期間は実装依存になるため、
あまり離れると移植性の点で問題になるかもしれません。
すぐに手元のローカル変数などにコピーするのがベターです。
ちなみに自分で関数を書く場合には、
struct tm *localtime_r(const time_t *timep, struct tm *result);
この result 引数のように、バッファを渡してもらう形にすると
余計なことを考えなくて済むのでベストです。
0372369
2005/08/16(火) 16:09:02回答ありがとう。
書き方が悪くてすみません。
localtimeは開放しない関数の例として挙げました。
一般に内部しようの分からない関数だったり、自分で作ったりしたときの当該問題における
寿命についての質問です。
0373369
2005/08/16(火) 16:16:29あらたな回答ありがと。
localtimeの仕様は了解しました。
さっきの質問、書き方が悪かったのですが、自分で作った関数内でメモリを割り当てて
そのポインタを返した場合はどうのようにするのが、適切なんでしょうか。
例えば、調べてて、見つけたのですが下記のようなプログラムは非常にマズイと思います。
ttp://c-production.com/contents/c/sec11.html#15
0374デフォルトの名無しさん
2005/08/16(火) 16:30:49その例がマズイと思えるなら特に言及する必要はなさそうね。
>>371 の最後に書いてあるように、特に何か事情がない限りは
バッファは呼び出し側が用意するのが一番いいかな。
new で確保して free() で解放するようなバグをなくすためにも。
どうしても関数内でメモリを確保しなきゃならないときは、
malloc で確保したら free、new で確保したら delete・・・
というルールを忠実に守ればOK。
0375デフォルトの名無しさん
2005/08/16(火) 16:31:14fopen()とfclose()みたいに、リソースを確保する関数と開放する関数を作って、
必ず両方呼び出してくださいとすればいいと思う。
(直接「free()を呼び出して下さい」でもいいと思うけど)
そのリンク先は、引数は値渡しなんだから、リターンも値で返せばいいのにな。
0376デフォルトの名無しさん
2005/08/16(火) 16:41:01よくわかりました。
そのルールを徹底します。
丁寧な解説ありがとうございました。
0377デフォルトの名無しさん
2005/08/16(火) 16:52:11夏厨で申し訳ないんですが・・・orz
0378デフォルトの名無しさん
2005/08/16(火) 16:57:37変数 st のスコープが関数 p_output() 内に限られてるため、
st のメモリ領域は関数を抜けた時点で無効になる。
だから main() でこのポインタの先にアクセスしちゃだめ。
0379デフォルトの名無しさん
2005/08/16(火) 17:00:22#include<stdio.h>
struct st_samp{
int x;
int y;
int z;
};
struct st_samp *p_output(struct st_samp st);
int main()
{
struct st_samp s1={2,3,0}, s2={4,5,0};
struct st_samp *p_st;
p_st = p_output(s1);
p_output(s2);
printf("%d * %d = %d\n",p_st->x,p_st->y,p_st->z);
return 0;
}
struct st_samp *p_output(struct st_samp st)
{
st.z = st.x * st.y;
return &st;
}
0380デフォルトの名無しさん
2005/08/16(火) 19:01:35a_positionの位置から、配列の後>前へとhoge処理を行いたいのですが
これをfor文だけで綺麗に記述することは可能でしょうか
if( a_position == 0 )
hoge( *array );
else
for( int i = a_position; i >= 0; --i ) hoge( array[i] );
0381デフォルトの名無しさん
2005/08/16(火) 19:02:45これで何が問題?
0382デフォルトの名無しさん
2005/08/16(火) 19:09:300383380
2005/08/16(火) 19:13:05申し訳ないです、仰るとおりっす
これと間違えていました…
if( a_position == 0 )
hoge( *array );
else
for( unsigned long i = a_position; i >= 0; --i ) hoge( array[i] );
0385デフォルトの名無しさん
2005/08/16(火) 19:21:06for( unsigned long i = a_position+1;i--;)hoge( array[i] );
0386380
2005/08/16(火) 19:27:45unsigned long a_position = 0;
do{
hoge( array[i] );
}while( array_pos-- != 0 );
と、思ったら>>385さんのスマートなレスが!
やっぱり聞いて良かった、ありがとうございました。
ループは前置って刷り込みが駄目でした orz
0387デフォルトの名無しさん
2005/08/16(火) 19:29:42do{
hoge( array[a_position] );
}while( a_position-- != 0 );
もう寝よう…
0388デフォルトの名無しさん
2005/08/16(火) 20:48:18含めて意味ないしすべてスレ違いだと思う。
>>385 境界条件 a_position = ULONG_MAX のふるまいは無視なのか?
0389360
2005/08/16(火) 21:01:21具体的に言うとファイル内に
「1234567890」
等の数字(バイナリ)が入っていて、
また別のファイルに
「3,4,3」
のように数字が入っていて、
これを
「123,4567,890」
に変える処理でう。
>>Cでプログラムを作るのですが、
Cの仕様に関する質問じゃないとダメでしょうか?
0390360
2005/08/16(火) 21:02:30下段のは「>>363」です。
0391385
2005/08/16(火) 21:08:29a_position = ULONG_MAX のときは、
array の配列長が ULONG_MAX より大きいということになるから無視ということで。
無視してもそんな馬鹿でかい配列は滅多に無いですし、実用上は問題ないでしょう。
一応それも回避するなら >>386(の間違いを直したやつ)で
unsigned long i = a_position;
do hoge(array[i]);while(i-- != 0);
0392デフォルトの名無しさん
2005/08/16(火) 21:09:02バイナリを連呼しているが、「バイナリ」と「区切り文字数」という二つの単語は矛盾しているよ。
ファイルには単に十進数字文字が入っているだけだろ
0393360
2005/08/16(火) 21:11:58すみません、ちょっと抜けてました。
元のファイルはバイナリで、
それをテキストファイルに、特定の箇所に「,」を入れて出力する感じになります。
■ このスレッドは過去ログ倉庫に格納されています