1 名前:デフォルトの名無しさん mailto:sage [2007/11/07(水) 06:24:18 ] C言語の入門者向け解説スレです。 ・C++言語はスレ違いです。 ・分からない事をなるべく詳しく書いて下さい。 ・ソースコードを晒すと答えやすくなるかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。 前スレ C言語なら俺に聞け(入門篇) Part 20 pc11.2ch.net/test/read.cgi/tech/1192455273/ 教えて欲しいのではなく丸投げしたいならこちらへ C/C++の宿題を片付けます 99代目 pc11.2ch.net/test/read.cgi/tech/1194262698/
552 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 21:35:19 ] 光あれと1と戻すだけ。 受け取る者がいなければ、 次のクロックで虚無に消える。
553 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 21:35:20 ] return 1って異常終了じゃないっけか? exit(1)と同じだと認識してる・・・
554 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 21:39:37 ] 受け取る側で判断するから異常とは限らないな
555 名前:デフォルトの名無しさん [2007/11/21(水) 22:01:01 ] >>549 そうです。それがよく分からないんです。 正常終了したかどうかはコンピュータが判断することでは? 「これは正常終了したことにします」って人間が決めちゃうんですか? 「正常終了」の意味が分かってないんだと思います。 main()関数は引数として0か1を渡してあげないといけないということでしょうか? 1を渡した場合、どうなるのでしょうか?
556 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:03:03 ] 2とか3とかも渡せるぞ
557 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:09:00 ] >>555 OSが何なのか分かってないのでは?
558 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:13:03 ] >>555 別にプログラムから1が返ってきたからってコンピュータはどうもしないけど、 シェルスクリプトやバッチファイルでコマンドの終了状態で処理を分岐したりだとか、 make中にコンパイルが失敗した時に処理を中断したりだとか、 そういう場面で使う。 俺的には「1つのプログラムで処理が完結する場合ばっかりじゃないので、 一応お約束が決まってます」ってぐらいだと思ってるけど。
559 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:14:25 ] >>555 コンピュータがどうやって「正常終了」の判断をするのかkwsk
560 名前:555 mailto:sage [2007/11/21(水) 22:19:56 ] スマン適当に言っただけだ。流してくれ。
561 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:21:03 ] >>555 main関数からどんな値を返そうと、WindowsやUnixなど大抵のOSは何も行わない。 ただ、その値を「欲しがっているところ」に引き渡すだけ。 「欲しがっているところ」とは、単に別のプログラム、大抵はバッチファイルやシェルスクリプト。 0が正常終了というのは、シェルスクリプトらとプログラムとの間の暗黙の了解。 当時の資料を探せば何か根拠が出てくるかもしれない。 Cはそれを標準規格へ取り込んだ。
562 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:32:10 ] 正しいか正しくないかは人間がきめること。 CPUはただクロックを数えるのみ。
563 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:40:55 ] 自己参照構造体のポインタの動きで頭がこんがらがりまくる・・・ 繋ぎなおして先頭アドレスをmainに返すってのはわかるんだけど、 か、書けねえ・・・ なんかコツとかありますか('A`)
564 名前:デフォルトの名無しさん [2007/11/21(水) 22:44:19 ] >>557-558 、>>561 ありがとうございます。 どうやら return 0; が何かを理解するのに必要な知識がだいぶ不足しているようです。 OSが何なのかや「make中」などが分かりません。 あてどもなくググってみたところ、 www.mech.utsunomiya-u.ac.jp/ozaki/education/c/text.html の下の方の記述を見つけ、ようやっと、「一応お約束」や「暗黙の了解」 という意味が分かりました。 ただ、 return 0; を書いた段階でプログラムが終わってしまうのは知りませんでしたが、 引数を返した時点で関数というのはそれ以上見なくなってしまうものなんですね。 もう少し勉強が必要です。少し知識を身につけてから、また皆さんの書き込み を見たら意味が理解できるのかもしれません。ありがとうございました。
565 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:44:37 ] 紙に書いて考えれば?
566 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 22:45:22 ] >>563 構造体を四角、ポインタの指す方向を線で、紙に書いてやってみそ。 慣れたら、頭の中でできるようになる。
567 名前:デフォルトの名無しさん [2007/11/21(水) 22:52:16 ] www.mech.utsunomiya-u.ac.jp/ozaki/education/c/text.html の下の方のところ、貼っておきます。 ------------------------------------ return 0 とは,プログラムの正常終了を意味している.とはいえ,これは UNIX 上でないとほとんど意味をなさないかもしれない. UNIXでは,シェル(shell)と呼ばれるインタフェースプログラムを介してプログラムの実行が行われる. return 0 はこのシェルに よってプログラムの終了状態に合わせた処理を行わせることができる.たとえば,Bash(Linux の標準シェル)の場合, if program; then echo "OK"; else echo "ERROR"; fi と記述することによって, program という名前のプログラムを実行し,もしそのプログラムが正常に終了した場合は OK を表示し, 正常に終了しなかった場合には ERROR を表示するようにすることができる. 正常に終了しなかった場合を表すには,たとえば次のよう記述する. #include <stdio.h> int main() { int a, b, c; if (c != 0) { a = b / 0; } else { printf("c = 0 なので割れません\n"); exit(1); /* 異常終了として1を返してプログラムを終了する */ } return 0; } このプログラムでは, 0で割算を行わないように,まず変数 c がゼロでないかチェックし,もし変数 c がゼロのときには異常を 示してプログラムを終了する. exit() はプログラムを終了させるための関数で,引数の値が返される.一般的には,正常に終了 した場合には 0 を返すことにし,正常に終了しなかった場合には他の値を返すことになっている.だから,return 0 は プログラムの正常終了を示すために必要なのである.また,main() の前の int は 0 や 異常終了の値の型を表している.
568 名前:デフォルトの名無しさん [2007/11/21(水) 23:11:09 ] おそらく>>297 は皆を困らせようとして書いただけだよ
569 名前:デフォルトの名無しさん mailto:sage [2007/11/21(水) 23:50:47 ] xor eax, eax ret
570 名前:デフォルトの名無しさん [2007/11/21(水) 23:59:44 ] >>564 process.h のsystem関数で外部exeを実行できるんだけど、 system関数の戻り値がintでそのプログラムが返した値を返す。 最後にreturn 0;だったら0。return 10;だったら10。 void main()だと不定っぽい。
571 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 00:04:12 ] //child.c #include <stdio.h> int main(){ printf("hogeeeeeeee!!\n"); return 10; } //parent.c #include <stdio.h> #include <process.h> int main(){ printf("system::%d", system("child")); return 0; } 二つをコンパイルしてparentを実行した結果 >hogeeeeeeee!! >system::10 と出るはず。
572 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 01:13:16 ] プログラムの正常終了は0だが、各関数の正常終了も0を返すようにしてる? if文やwhile文が0以外を真としたりするので、0を返しちゃうと判定で偽になるよね? みんなは省略形は使わずに、必ず==で何かと比較してますか?
573 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 01:16:40 ] 俺はmain以外の関数の場合、<ctype.h>のisナントカに合わせて0以外を真と見做すことにしている。 ほかの言語 (C++, Java, C#)でもtrueは1で、falseは0に相当するし。
574 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 02:05:04 ] 自分はファイル分割をする際、main.hなどと命名したヘッダファイル にプロジェクトで使う全ての関数をプロトタイプ宣言しています。 例えば、 <<main.hの中身>> #include "proj1.h" extern void test1(void); extern int test2(int); : // 以下色々な宣言等を列挙 といった具合です。 今までプロトタイプ宣言している関数の頭にはとりあえずexternを 書く必要があるのだろうと思っていました。 しかし、このexternを書かなくても正常にビルド出来てしまいます。 環境がVisualStudioだからでしょうか? このextern宣言は邪魔くさいのでこれからは外して記述しようと思う のですが、externが無い場合困るケースとしてどのような事が考えられますか?
575 名前:デフォルトの名無しさん [2007/11/22(木) 02:50:24 ] ヤメレ
576 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 04:51:07 ] 関数の宣言は暗黙にexternだから別に構わないけど、 変数は定義になるから、extern必須。 普通は両方つけて揃えるはず。
577 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 05:19:54 ] 関数にexternをつけてるソースは、殆ど見た事が無いなぁ。
578 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 07:20:44 ] >574 直接関係無いけど、なんでもかんでもグローバル関数にしないこと。
579 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 11:05:55 ] static でプロトタイプ宣言するのと区別するのに、 外部参照なんだから extern つければ?
580 名前:デフォルトの名無しさん [2007/11/22(木) 11:53:53 ] ビットマップの画像を平行移動させるプログラムを作っているのですが、 出力が真っ黒になってしまい、うまく動作しません。 単純なバグだと思うのですが、教えていただけると大変助かります。よろしくお願いします。 /* 画像の平行移動 */ void image_shift( unsigned char out2[Y_SIZE][X_SIZE][3], unsigned char out[Y_SIZE][X_SIZE][3] ) { unsigned int i,j,sx,sy,x,y; sx=148; // X方向のシフト量 sy=128; // Y方向のシフト量 for(i=0;i<biHeight;i++){ for(j=0;j<biWidth;j++){ y=i+sy; x=j+sx; out2[y][x][0]=out[i][j][0]; out2[y][x][1]=out[i][j][1]; out2[y][x][2]=out[i][j][2]; } } }
581 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 13:43:27 ] OPENGLを使えばいいと思うよ>< あとBMPがちゃんと確保されてるか確認した?
582 名前:デフォルトの名無しさん [2007/11/22(木) 13:50:06 ] 回答ありがとうございます! BMPはちゃんと確保されてます。そのまま出力もできますし・・・ OpenGLも考えてみます。
583 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 13:51:19 ] >>580 取り敢えずシフト量を0にして試してみたら?
584 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 14:04:32 ] シフト量を0 そのあと1とか小さい値にして デバッグモードで確認して
585 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 14:07:41 ] シフトした分だけあふれてるような気がするんだけど。
586 名前:デフォルトの名無しさん [2007/11/22(木) 14:11:17 ] みなさんのおっしゃるとおりです。 シフト量を0にすると、ちゃんと元の画像が出るんです。 ずらすと真っ黒になったりするんです。マイナス方向にずらすとエラーで止まってしまいますし・・・。
587 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 14:15:36 ] >>マイナス方向にずらすとエラーで止まってしまいますし・・・。 それout2の領域外に書き込んでないか? つまり配列の添え字がマイナスになったりX_SIZEやY_SIZEをオーバーしたり…
588 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 14:19:34 ] for(i=0; i<biHeight; i++) { for(j=0; j<biWidth; j++) { y = (i+sy) % biHeight; x = (i+sx) % biWidth; ってしてみれば?
589 名前:デフォルトの名無しさん [2007/11/22(木) 14:19:53 ] ありがとうございます! やっと解決しました。 大きな理由はビットマップのビット深さを間違えてました。 どうもお手数おかけしてすいません。ありがとうございました!
590 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 14:38:34 ] アチャー
591 名前:デフォルトの名無しさん [2007/11/22(木) 14:47:41 ] なんかC言語の配列って何度も呼び出すと鈍くならない? なんで a = x[y[z[n]]]; みたいな感じ a=z[n];a=y[a];a=x[a]; のほうが速くない?
592 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 14:56:24 ] 計ってみれば?
593 名前:デフォルトの名無しさん [2007/11/22(木) 15:05:40 ] 計ってみたよ 配列に何度も入れた方がわずかに速いようだ #include <iostream> #include <time.h> #define N 900000 using namespace std; main(){ unsigned int n,k,c,sum; unsigned int *x,*y,*z,*v,*w; x=new unsigned int [N]; y=new unsigned int [N]; z=new unsigned int [N]; v=new unsigned int [N]; w=new unsigned int [N]; for(n=0;n<N;n++){x[n]=rand()%10;y[n]=rand()%N;z[n]=rand()%N;v[n]=rand()%N;w[n]=rand()%N;} sum=0; c=clock(); for(n=0;n<N;n++){k=w[n];k=v[k];k=z[k];k=y[k];sum+=x[k];} c=clock()-c; cout<<c<<" clock "<<sum<<endl; sum=0; c=clock(); for(n=0;n<N;n++)sum+=x[y[z[v[w[n]]]]]; c=clock()-c; cout<<c<<" clock "<<sum<<endl; }
594 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:30:37 ] >>593 手元のiccでは全く同じコードにコンパイルされたよ。 -- movl (%rbx,%rcx,4), %ecx #15.20 movl (%rbp,%rcx,4), %edi #15.27 movl (%r12,%rdi,4), %r8d #15.34 movl (%r13,%r8,4), %r9d #15.41 addl $1, %edx #15.13 movl %edx, %ecx #15.13 addl (%r10,%r9,4), %r15d #15.46 movl %ecx, %edx #15.1 cmpl $900000, %edx #15.1 jb ..B1.15 # Prob 99% #15.1 -- movl (%rbx,%rcx,4), %ecx #19.30 movl (%rbp,%rcx,4), %esi #19.28 movl (%r12,%rsi,4), %edi #19.26 movl (%r13,%rdi,4), %r8d #19.24 addl $1, %edx #19.13 movl %edx, %ecx #19.13 addl (%r9,%r8,4), %r15d #19.17 movl %ecx, %edx #19.1 cmpl $900000, %edx #19.1 jb ..B1.23 # Prob 99% #19.1 --
595 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:31:30 ] 処で、>593はなんでC++でコンパイルしているんだ?
596 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:34:55 ] 仮想関数を利用する上での注意点があれば教えて下さい。
597 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:40:00 ] iccだとmovlにしてくれるのか VCだとmov,mov,...ってのにしかならない
598 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 15:44:40 ] >593以下速度の話題 C/C++スレか速度スレ、或いは最適化スレへどうぞ。 >>596 あんたもスレ違い。
599 名前:デフォルトの名無しさん [2007/11/22(木) 21:02:53 ] for(i=10;i>=0;i--)printf("%d\n"i); っていうコード unsigned にするとやばいね 全然気づかなかったよ
600 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 21:11:23 ] 処理系依存になるってこと?
601 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 21:17:31 ] unsigned int iに対してi>=0は常に真だべ
602 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 21:20:46 ] なるほど どうもありがとう
603 名前:デフォルトの名無しさん [2007/11/22(木) 22:37:22 ] ポインタが指してる内容を配列に入れたいのですがどうしたらいいですか? 例えば、 char *a="ABC"; char b[4]; このとき、 b[0]=A,b[1]=B,b[2]=C にしたいです。
604 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 22:39:15 ] strcpy(b,a);
605 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 22:41:18 ] memmove(b,a,3);
606 名前:603 mailto:sage [2007/11/22(木) 23:01:19 ] >>604 ,>>605 できました。 ありがとうございます。
607 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:01:27 ] for(i=0;b[i]=a[i];i++);
608 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:16:00 ] 昨日自己参照構造体でのリストについてかけねーって嘆いてた者だけど、 今日紙に書きつつ、これがこーなるから次はこうなるだろーってソース書いてったら無事動きました!
609 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:28:12 ] 二次方程式の解の公式を求めるプログラムを作れとの課題が出たので考えてみたのですが 思うようにうまくいきません。 #include <stdio.h> #include <math.h> int main() { double x1 ,x2, a, b, c; printf( "a = " ); scanf("%lf" , &a); printf( "b = " ); scanf("%lf" , &b); printf( "c = " ); scanf("%lf" , &c); x1 = -b+sqrt(b*b-4.0*a*c)/2.0*a; x2 = -b-sqrt(b*b-4.0*a*c)/2.0*a; printf("x1= %lf x2= %lf\n", x1, x2); } までできたのですが、 x1= -1.#IND00 x2= -1.#IND00 何を入力してもこの答えになってしまいます。 自分なりに見直してみたのですが間違いが分かりません。 どなたかご教示いただけたら幸いです。
610 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:32:03 ] そもそも式が違うじゃん
611 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:39:05 ] かけざんとわりざんはたしざんやひきざんよりもさきにけいさんします。
612 名前:609 mailto:sage [2007/11/22(木) 23:40:33 ] 式からして間違ってるのでしょうか? 今の式じゃ-bがが最後に計算されてしまうってことですかね?
613 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:43:51 ] >>609 あなたが書いている式は √(b^2 - 4ac) x1 = -b + ------------- * a 2 こんなだよ
614 名前:609 mailto:sage [2007/11/22(木) 23:44:12 ] x1 = (-b+sqrt(b*b-4.0*a*c))/2.0*a; x2 = (-b-sqrt(b*b-4.0*a*c))/2.0*a; こんな感じでいいんでしょうか?あと warning C4996: 'scanf' が古い形式として宣言されました。 というエラーが発生してるんですがこれが原因でしょうか? 習ったとおりに書いてみたのですが。
615 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:46:11 ] printfで%lfは標準じゃなかった気がする。 独自拡張とかC99とかならいけたかもしれんけど。
616 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:47:57 ] >>613 最後のaは分母にかかりますよね? >>615 そうなんですか・・・家と学校じゃ環境が違うのでそのせいかもしれません。 他に間違ってるところありますかね?
617 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:09 ] >>614 それは警告であってエラーじゃない
618 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:11 ] >>614 (...)/2*aじゃなくて(...)/(2*a)
619 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:15 ] それだと -b + √(b^2 - 4ac) x1 = ----------------- * a 2 だな >warning C4996: 'scanf' が古い形式として宣言されました。 warning C4996 でぐぐれ
620 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:48:46 ] >>616 かからねーよwww
621 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:51:39 ] >>618-620 なるほど・・・()付けない限り数字同士はくっ付かないんですか ご指摘ありがとうございます。修正してみましたが、相変わらず答えは変わりません。 他に間違っているところがないのであれば家の環境が悪いということで諦めます。
622 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:53:55 ] 入力してる値が悪いのでは?実数解を持つ値を入れてみ
623 名前:デフォルトの名無しさん mailto:sage [2007/11/22(木) 23:59:22 ] >>622 答えがでました。適当に値を入れていたのが原因でしたか・・・ こんな基礎の問題に答えてくれて助かりました。 もっと勉強しないと駄目なようです、ありがとうございました。
624 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:02:47 ] 適当にいれんなよwwwwwwwwwwww
625 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:05:03 ] Cに一番大事なのはとにかく基礎。 応用なんてものは後回しでとにかく基礎だぜ。
626 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:06:46 ] AもBもすっとばしていきなりCやるとはたかれるってことですよねー
627 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:11:14 ] たまにする背伸びは楽しいけどな 良い気分転換になる
628 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 00:12:09 ] fizzbuzzもかけない段階でchaos pp使ってメタプログラミングしたりな
629 名前:助けてBOYZ [2007/11/23(金) 02:27:55 ] 今日からの連休中に3つの課題を出されました。 ポインタ大嫌いです。 どなたか助けて下さい。 この問題が一つ目です。 【問】数字文字列を数値化する関数を作成して下さい。 <関数仕様> 書式 :short *AtoS(char *pStr, int *pRetCode); 戻り値:数字文字列のポインタ 引数 :char *pStr → 文字列の先頭アドレス :int *pRetCode → 動作の成否を返す (正常なら:0,エラー時は-1) ※但し、NULLの時は返さない 処理 :pStrで与えられた文字列をshort型の数値に変換する ※負数(マイナス)にも対応 <考慮必要事項> ・short型の範囲外の数値文字列 ・非数字文字列 ・数字文字列と非数字文字列の混在(先頭の'-')は除く ・空文字列 ・NULL 以上の5つはpRetCodeの示す領域にはエラーを返す、戻り値は0
630 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 02:28:53 ] >>629 いつまで逃げ続けられるの? 終わりはあるの?
631 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 02:40:04 ] >>629 自分で考える気がないなら宿題スレへ pc11.2ch.net/test/read.cgi/tech/1195668114/
632 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:03:04 ] >>609 printf("x1= %f x2= %f\n", x1, x2); で試したのか? どうみてこうだと思うんだが
633 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:05:05 ] >>632 そういう問題じゃないから
634 名前:助けてBOYZ [2007/11/23(金) 03:11:41 ] 何とか自分で作ってみました。 だけど戻り値?とか関数の意味がよく分からないし、何だかグダグダと 長いプログラムになってしまいました。 ポインタ&関数を理解するコツを教えて下さい。
635 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:15:18 ] 戻り値ってshort*なの?
636 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 03:15:18 ] そもそも問題がおかしいのにどうしろと 文字列を数値化するのに文字列へのポインタ返してどうしろと
637 名前:助けてBOYZ [2007/11/23(金) 03:22:30 ] 戻り値はshortみたいです。 一応表示はされたんですけど… ちょっとチェックして下さい。 おかしいところ教えて下さい。
638 名前:助けてBOYZ [2007/11/23(金) 03:26:42 ] #include <stdio.h> short AtoS(char *pStr, int *pRetCode); int main(void) { short val; int ret = 0; val = AtoS("1234", &ret); printf("%d\n", val); val = AtoS("-789", &ret); printf("%d\n", val); val = AtoS("atai", &ret); if (-1 == ret) { printf("数値文字列でないデータが渡されました。\n"); } return 0;
639 名前:助けてBOYZ [2007/11/23(金) 03:27:56 ] 改行が多くて入りませんでした。 間違ってるところあれば教えて下さい。 short AtoS(char *pStr, int *pRetCode) { int *p; int i; int sum; short goukei; goukei = 0; if (pStr[0] == '-') { for (i = 1; pStr[i] != '\0'; i++) { /* p[0]に'-'が入力された */ pStr[i] = pStr[i] - '0'; goukei = pStr[i] + (goukei * 10); } goukei = goukei - (goukei * 2); return goukei; } goukei = 0; for (i = 0; pStr[i] != '\0'; i++) { /* p[0]〜'\0'の中に数字だけが入力された */ if (pStr[i] > 48 && pStr[i] < 58) { pStr[i] = pStr[i] - '0'; goukei = pStr[i] + (goukei * 10); } else { *pRetCode = -1; return pRetCode[0]; } } return goukei;
640 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 05:10:13 ] >>629 次からは宿題スレへ #include <stdio.h> short AtoS(char *pStr, int *pRetCode) { int n,s; if(pRetCode == NULL) return 0; *pRetCode = -1; if(pStr == NULL || *pStr == '\0') return 0; for(s=*pStr=='-'?1:0,pStr+=s,n=0;*pStr != '\0' && *pStr>='0' && *pStr<='9';pStr++) n=n*10+*pStr-'0'; n=s==1?-n:n; if(*pStr != '\0' || *(pStr-1) == '-' || n<-32768 || n>32767) return 0; *pRetCode = 0; return n; } int main() { int i,s,r; char t[][8]={"","-","a","-a","a1","1a","1-", "-32769","-32768","-1","0","1","32767","32768","-000001","000001"}; printf("String\t: Value\t(RetCode)\n"); s = AtoS("1",NULL); printf("\"1\"\t: %d\t(NULL)\n",s); s = AtoS(NULL,&r); printf("(NULL)\t: %d\t(%d)\n",s,r); for(i=0; i<sizeof(t)/8; i++) { s = AtoS(t[i],&r); printf("\"%s\"\t: %d\t(%d)\n",t[i],s,r); } return 0; }
641 名前:640 mailto:sage [2007/11/23(金) 06:31:08 ] 訂正 #include <stdio.h> short AtoS(char *pStr, int *pRetCode) { int n,s; if(pRetCode == NULL) return 0; *pRetCode = -1; if(pStr == NULL || *pStr == '\0') return 0; for(s=*pStr=='-'?1:0,pStr+=s,n=0;*pStr != '\0' && *pStr>='0' && *pStr<='9' && n>=-32768;pStr++) n=n*10-*pStr+'0'; n=s?n:-n; if(*pStr != '\0' || *(pStr-1) == '-' || n<-32768 || n>32767) return 0; *pRetCode = 0; return n; } int main() { int i,s,r; char t[][16]={"","-","a","-a","a1","1a","1-", "-32769","-32768","-1","0","1","32767","32768","-000001","000001","4294967296"}; printf("String\t: Value\t(RetCode)\n"); s = AtoS("1",NULL); printf("\"1\"\t: %d\t(NULL)\n",s); s = AtoS(NULL,&r); printf("(NULL)\t: %d\t(%d)\n",s,r); for(i=0; i<sizeof(t)/16; i++) { s = AtoS(t[i],&r); printf("\"%s\"\t: %d\t(%d)\n",t[i],s,r); } return 0; }
642 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:05:09 ] >>639 > pStr[i] = pStr[i] - '0'; 文字列へのポインタ貰った関数が、中身を書き換えちゃいけない。 呼び出し側が、 n=AtoS("12345", &x); とした場合、pStrの指す先は書き換えは不可能である処理系が多い。 普通、こういう文字列へのポインタを貰う関数は、 short AtoS(const char *pStr, int *pRetCode) のようにconstを付ける。
643 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:23:18 ] >641 for(s=*pStr=='-'?1:0,pStr+=s,n=0;*pStr != '\0' && *pStr>='0' && *pStr<='9' && n>=-32768;pStr++) n=n*10-*pStr+'0'; ↑こういう可読性の悪い書き方はやめようぜ…
644 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 09:24:47 ] わざとだろう
645 名前:デフォルトの名無しさん [2007/11/23(金) 10:41:36 ] x[n]とr=0.6に対して (x[0]-x[1])/x[1] + r * (x[1]-x[2])/x[2] + r^2 * (x[2]-x[3])/x[3] + ・・・ という計算を多くするとき計算が速く終わるコードって分かりますか? x[n]は変化します 厳密な値ではなくていいです
646 名前:デフォルトの名無しさん [2007/11/23(金) 10:42:45 ] あとx[n]の値は50%以内のずれしかありません
647 名前:デフォルトの名無しさん [2007/11/23(金) 10:54:43 ] x[n]の平均値hとその誤差をd[n]とすると (x[0]-x[1])/x[1] =d[0]-d[1]/x[1] =d[0]-d[1]/h =(d[0]-d[1])*k k=1/h とすれば速そうですね
648 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 11:57:13 ] (x[0]-x[1])/x[1] = x[0]/x[1]-1 でしょ。 -1の部分だけ分けて、 元の式=x[0]/x[1]+r*x[1]/x[2]+r^2*x[2]/x[3]....-(1+r+r^2+...) とすれば、 r=0.6固定なら後ろの部分は定数だから前もって計算しておけば早いのかも。 精度が無視できる項以降は計算しないって手もあるのかな。 有効数字2ケタでいいなら、0.6^10以降は計算しなくてもいいと思う。
649 名前:デフォルトの名無しさん [2007/11/23(金) 12:22:00 ] >>648 サンクス
650 名前:574 mailto:sage [2007/11/23(金) 13:43:42 ] >>576-579 ありがとうございました。 プロトタイプ宣言はやはり暗黙的にexternのですね。 社内のソースと合わせるため、一応これからはグローバルな関数はexternを付けて区別していこうと思います。
651 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:22:28 ] プロトタイプ宣言は厳密には暗黙的に extern なのではなくて、 それより前に static なプロトタイプ宣言や関数定義がなければ extern になり、 あれば static になる。
652 名前:デフォルトの名無しさん mailto:sage [2007/11/23(金) 14:24:28 ] そういうときに「規定」って言葉を使うのかな。