1 名前:静的領域の名無しさん mailto:sage [2008/08/12(火) 18:23:10 ] C言語の入門者向け解説スレです。 教えて欲しいのではなく宿題を丸投げしたいだけなら ↓宿題スレ↓へ行ってください。 C/C++の宿題を片付けます 114代目 pc11.2ch.net/test/read.cgi/tech/1216746971/ ・C++言語はスレ違いです。 ・分からない事をなるべく詳しく書いて下さい。 ・ソースコードを晒すと答えやすくなるかもしれません。 # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること # サイズが大きい場合は宿題スレのアップローダ等を利用してください ・開発環境や動作環境も晒すと答えが早いかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。 前スレ C言語なら俺に聞け(入門篇) Part 33 pc11.2ch.net/test/read.cgi/tech/1217073697/ 過去スレ makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
331 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:31:06 ] >>330 だから、>>329
332 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:34:17 ] >>331 ということは、長くだらだらと書く奴の方が簡潔に書く奴より高給を貰ってた訳か 狂ってるな
333 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:34:18 ] 可読性の話をしてると思ってたのだが。
334 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:35:49 ] >>332 正直者はいつも馬鹿を見るのがこの世です
335 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:36:21 ] >>332 まー実際は予算も決まってるし、新規で行数書けばその分テスト件数も増やさないといけないとか いろいろあるのよ>日立の場合。
336 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:44:00 ] >>302 n = strspn(s, "ABCDEF・・・XYZ"); if (s[n] == '\0') return 0; else return -1; とすれば、ループもなくなるなと一瞬思ったけど、やっぱ"ABCDEF・・・"と書くのがダサいな。 isupperでまわしたほうがいいか。 あと、正常が0で、異常終了で-1ってのも、出題者のセンスが・・・
337 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:45:35 ] >>332 つか、メインフレームの作業体制は極度に分業が進んでいて コーダーという人は詳細フローを言語のコードに一行ずつ落とすだけ。 そういう環境だから、ステップ単価というのは有効だったんだよ
338 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:49:20 ] >>336 正常0は理にかなってるよ 正常は一通りしかないが、異常にはいろんなケースがある だから正常は0を返し、エラー時はエラーコードを返すほうがいい
339 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:53:14 ] >>338 だからウゼーって 独り言はチラシの裏にでも書いてろ
340 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:54:30 ] >>338 この場合は、エラーは一通りしかないじゃん。 bool値のかわりで、0と0以外のほうがいい。 それに、そういう思想だったら、-1じゃなくて、0とマイナス値としておかないとダメ。
341 名前:デフォルトの名無しさん [2008/08/18(月) 23:56:05 ] 多分この問題の次ではアルファベットじゃなかった文字数を返すようにしましょうって続くんだよ きっとそうだよ
342 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:58:21 ] >>339 完全に反論の余地がない時は黙ってた方がいいですよ
343 名前:デフォルトの名無しさん mailto:sage [2008/08/18(月) 23:59:58 ] どう見ても初学者用の問題なのにstrspnとかisupperつかってかえって混乱させようとしてるやつなんなの?
344 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:00:11 ] 入力がヌル文字列の場合はどっち?
345 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:04:42 ] >>343 ああ、そういえば再帰とかつかって、面白い回答にするの忘れてたな。
346 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:05:54 ] 今からでも遅くないからさっさとやれよ
347 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:12:35 ] >>343 標準ライブラリ関数を使うことの何が問題なんだかわからん string.hに定義されてるような車輪の再発明をやらせる方がよっぽど問題だ
348 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:13:05 ] >>342 反論の余地とかそういう問題じゃなくてお前がうざいの
349 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:14:15 ] >>348 しーっ!これ以上書くと頭が悪いことがばれますよ!
350 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:15:18 ] Cだと文字列の理解はC言語自体の理解にも多少は 繋がる気がするから再発明も完全に無駄だとは思わない俺
351 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:16:29 ] 文字列じゃなくて文字配列か
352 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:16:34 ] >>349 お前がな
353 名前:304 [2008/08/19(火) 00:22:21 ] >>302 じゃ初学者用に書くよ int CheckFunc(char *str) { int i; for(i = 0; str[i]; i++){ if ('A' > str[i] || str[i] > 'Z') return -1; } return 0; } >>344 0が返る
354 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:25:07 ] >>353 ○strがNULLだと落ちる ○iは無くても書ける
355 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:26:59 ] 文字列に大文字以外が含まれているかどうか調べる関数って、どういう関数名が適切だと思う?
356 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:27:27 ] >>352 しーっ!これ以上書くと頭が悪いことがばれますよ!
357 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:28:01 ] >>354 引数にNULLを渡してはいけないという仕様です。
358 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:29:43 ] >>313 でおk
359 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:29:59 ] >>357 君の世界ではそれでいいのかもしれないが、俺の世界では文字列のNULLチェックを怠ったばかりに 落ちてしまうソフトが後を絶たないんだなこれが
360 名前:デフォルトの名無しさん [2008/08/19(火) 00:32:54 ] ポインタを渡す関数はnullかどうかひかくしなくてはいけないのですか?それが一般的ナのですか?
361 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 00:43:45 ] >>359 あなたの世界では、たとえばstrcat()にNULLを渡したときに、落ちずに正常に動作してますか? strcat()がNULLを渡しても動作するとしたら、どう動作すればいいですか?
362 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 01:04:20 ] パルプンテ
363 名前:デフォルトの名無しさん [2008/08/19(火) 01:14:15 ] そうだな、システムコールとかは異常が-1、正常がそれ以外だったりするしね。
364 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 02:40:04 ] >>361 顔が真っ赤ですよ
365 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 03:04:33 ] >>364 しーっ!これ以上書くと頭が悪いことがばれますよ! ってもう遅いけど
366 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 04:02:45 ] ポインタを渡された側がNULLかどうかをチェックしてもあまり役に立つとは思わないけど。 無効なポインタは別にNULLだけじゃないから、無効なポインタは渡す側の責任でしか回避できない。 もちろん渡された側でのNULLチェックで回避できる問題もある。 でも渡される側でNULLチェックを怠ったばかりにおちてしまうような関数の使い方をしているようなプロジェクトなら、 他にも無効なポインタを渡してしまうような潜在的な危険があったりするおそれも。 >>357 の人も引数に渡してはいけないのはNULLとせず、無効なポインタとすべきだったと思う。
367 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 09:43:53 ] NULLは呼んだほうの責任だからな。 まあassert入れといてもバチはあたらんと思うが。
368 名前:デフォルトの名無しさん [2008/08/19(火) 11:44:22 ] Visual Studio 2005とかだと、sprintfの代わりにsprintf_sを使えと警告をされるのですが、いちいち書き換えたくありません。 sprintf_sは、Visual Studioの独自の関数で、2番目に、文字列のサイズを引数に取ります マクロとかで解決できないでしょうか
369 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 11:46:23 ] #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
370 名前:デフォルトの名無しさん [2008/08/19(火) 11:50:42 ] >>369 ありがとうございます。まさにそれを探してました。
371 名前:デフォルトの名無しさん [2008/08/19(火) 12:30:24 ] #include <stdio.h> #ifdef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #undef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES #endif #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1 int main( void ) { char fname[256]; // this causes 4996 warning sprintf( fname, "%s", "hogehoge" ); // this is safe version // sprintf_s( fname, sizeof(fname), "%s", "hogehoge" ); return true; } こんなシンプルなものでもまだwarningでるんですが。。。
372 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 12:32:15 ] #define _CRT_NON_CONFORMING_SWPRINTFS というかMSDN嫁
373 名前:デフォルトの名無しさん [2008/08/19(火) 12:32:37 ] すいません。 #include <stdio.h>を後にしたらできました。
374 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 12:34:47 ] あ。悪い >>372 は関係ないわ #pragma warning(disable : 4996)
375 名前:デフォルトの名無しさん [2008/08/19(火) 12:35:56 ] >>372 どうもありがとうございます。 MSDNは嫁にしたんですが、気づきませんでした。
376 名前:デフォルトの名無しさん [2008/08/19(火) 12:41:29 ] 初心者の底辺なんですがおすすめの開発環境はありますか? それとNetbeansでCをやろうとするとコンパイラが見つからないとエラー吐くんですが、 コンパイラってどこからDLするんでしょうか? 両方ググってはみたものの分かりませんでしたのでお願いします。
377 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 12:42:37 ] >>6
378 名前:デフォルトの名無しさん [2008/08/19(火) 12:56:19 ] やはり、>>371 でうまくいかない理由がわかりません。
379 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:00:12 ] >>378 ヘッダの位置変えたらうまくいくんでしょ? コンパイラだって機械だからねえ。 機械的、要するにソースの上から解釈するってことだけでしょ。
380 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:06:01 ] プロトタイプ宣言の意味とか、プロトタイプ宣言をしない場合はmainより中で使ってる 関数がソースに前に来るとか理解できてるんだろうか?
381 名前:デフォルトの名無しさん [2008/08/19(火) 13:12:34 ] >>379 そのとおりです。ヘッダをトップに持ってきたらうまくいきました。 >>380 理解できているつもりが、宣言の順番を変えるとうまくいかなくなる説明が解釈できません。
382 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:21:26 ] >>381 コンパイラの仕組み勉強してこい。
383 名前:デフォルトの名無しさん [2008/08/19(火) 13:25:32 ] >>382 的確なアドバイス、どうもありがとうございます。 不毛な気がしますが、VCのコンパイラがどのタイミングでCRTライブラリにしてくれるのか、調べてみます。
384 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:30:49 ] たぶんヘッダを解析した段階でコンパイラがリンクするライブラリを決定してしまってるのに 後でスイッチ置かれても切り替えができなってことかな?
385 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:52:31 ] _CRT_NON_CONFORMING_SWPRINTFS をgrepしてそのあたり見てみりゃわかる
386 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:53:35 ] コピペ元間違った _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES こっちな
387 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 13:59:33 ] あと、、defineはコンパイラ等に直接指示するわけじゃないから 切り替えたいときはincludeの前に置くのは常識なんだけどな。 コンパイラ等に指示出せるのはpragma
388 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 14:23:05 ] C言語の入門書を理解したレベルで取れそうな資格ってなにかありますか?
389 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 14:28:15 ] 英検3級
390 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 14:33:19 ] >>388 「C言語プログラミング能力認定試験」という、クソの役にも立たない資格があるぞ。 3級とか、C言語をほとんど知らなくても取れる。2級はプログラムが組めなくても取れる。 が、入門レベルがわかるだけの資格持ってて何の役にたつと思う? やめとけ。
391 名前:デフォルトの名無しさん [2008/08/19(火) 15:30:31 ] >>387 なるほど。みなさん、よくわかりました。 おそらく、 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMESがデフォルトでゼロになっていて、その値をマクロの引数にとって何かを展開しているのでだめなんでしょうね。 先手を取って1で定義してあげればよい、と。 #undefの使い方の間違えの典型であることがわかりました。 以上踏まえて、既に定義されているマクロを再定義する場合は#undefを使わないで、そのマクロが定義されている#includeの前におけばよいってことですかね。
392 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 15:50:55 ] >>388 そこから頑張って2種とか取れば良い。 ていうか、会社に理解してもらえない資格は時間の無駄、金の無駄。 CG検定、シスアドとか取ったけど糞の役にもたたねぇ。
393 名前:ym [2008/08/19(火) 16:06:37 ] #include <stdio.h> #include <ctype.h> #define RET_OK 0 #define RET_NG -1 int N60901D01(const char *psChkString { int i; for(i = 0;psChkString[i]!='\0';i++){ if(isupper(psChkString[i])!=0){ return RET_OK; } else{ return RET_NG; } } return RET_OK; } int main(void) { char str[256]; int chk; gets(str); chk = N60901D01(str); printf("\n戻り値は%dです\n",chk); } アルファベットをチェックするプログラムなんですけど、 コンパイルをしたら1文字分しかチェックされませんでした。 どこが間違っているか教えてください。 お願いします。
394 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 16:09:22 ] >>393 >if(isupper(psChkString[i])!=0){ の中で必ず一回目でreturnしてる。
395 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 16:11:53 ] >>393 for文の中で1文字目チェックした後、真でも偽でもreturnしてるだろう。 そこは最後まで回さないと。最後がRET_OKってことは、if文のRET_OKの行を消せばいいような気がする。
396 名前:ym [2008/08/19(火) 16:11:55 ] 必ず1回目でreturnしないためにはどうしたらいいですか?
397 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 16:16:59 ] >>396 >>395 の言うように、 if(isupper(psChkString[i])!=0){ の下の return RET_OK; を消してみ。
398 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 16:17:12 ] return文を消せばいいと思うよ
399 名前:ym [2008/08/19(火) 16:26:09 ] if文のreturn RET_OKを消したらコンパイル成功しました。 ありがとうございました。
400 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 16:37:48 ] え、コンパイル失敗してたの?そういう話?
401 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 16:43:41 ] >>400 3つめのreturn文にいくことはありませんエラーか。
402 名前:デフォルトの名無しさん [2008/08/19(火) 17:43:19 ] 処理開始から処理終了まで何秒経過したかを調べる方法を探しているのですが、 #include <stdio.h> #import <time.h> #include <unistd.h> int main (int argc, const char * argv[]) { clock_t start, end; start = clock(); printf("start:%ld¥n",start); sleep(1); end = clock(); printf("end:%ld¥n",end); printf("CLOCKS_PER_SEC:%ld¥n",CLOCKS_PER_SEC); printf("%ld秒経過しました。¥n", (end - start) / CLOCKS_PER_SEC); return 0; } これを実行すると start:6464 end:6580 CLOCKS_PER_SEC:1000000 0秒経過しました。 こんな結果が帰ってきました。 CLOCKS_PER_SECは1秒あたりのクロック数では無いのでしょうか。
403 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 17:46:26 ] 整数型で出力しちゃあ駄目だろ
404 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 17:49:15 ] printf("%f秒経過しました。\n", (float)(end - start) / CLOCKS_PER_SEC);
405 名前:デフォルトの名無しさん [2008/08/19(火) 17:52:29 ] >>404 ありがとうございます。 start:6894 end:7011 CLOCKS_PER_SEC:1000000 0.000117秒経過しました。 こうなりました。sleep(1)が0.00017秒?なわけ無いんだが… CLOCKS_PER_SECはあてにならないってことなのかな
406 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 17:55:17 ] TimeGetTimeか QueryPerformanceCounter使えよ 1秒単位とか精度が悪すぎる(この場合はな)
407 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 17:55:40 ] int a[4]; int b[4]; int c[4]; : : といった感じに、int型配列が大量に存在している場合に、配列内の数字でソートしたいのですが、 int型配列の数字の大小比較がうまくできません。どなたかご教授お願いします 単純に int(a[0] > b[0]){ってやっていくと死ねる・・・orz
408 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:00:09 ] qsort
409 名前:デフォルトの名無しさん [2008/08/19(火) 18:01:15 ] >TimeGetTimeか QueryPerformanceCounter Winの独自実装ですか… 残念ながらWindowsでは無いです
410 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:04:02 ] それだけだとほとんど0になるはずだよね。 どんな環境でやってるの?
411 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:06:11 ] sleepかけてる間クロックとまってんじゃないの
412 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:07:19 ] sleepで0.00017秒も食ってるから、おかしいと思ってるんじゃないの?
413 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:07:50 ] >>411 だろーね こういうやり方してもテストにならないってこった
414 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:08:41 ] >>412 printf挟んどいてそれはないだろ
415 名前:402 mailto:sage [2008/08/19(火) 18:11:16 ] >>410 gcc 4.0.1 Mac OS 10.5.4 Intel Core Duo 2.4GHz 2GB 667MHz DDR2 SDRAM です。
416 名前:402 mailto:sage [2008/08/19(火) 18:13:05 ] >>411 ,413 sleepするとクロック止まるんですか…、ありがとうございます。
417 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:20:39 ] >>407 何がしたいのかよくわからないが、たぶん配列を大量に作るのがもうおかしいんだろう。 ソートしたいもの全部を一つの配列に入れましょう。
418 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:25:55 ] >>407 はもうちょっとくやしく
419 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:32:50 ] >>418 int a[4] ; a[0] =1 a[1]=2 a[2]= 3 a[3]= 4 int b[4] ; b[0] =2 b[1]=2 b[2]= 3 b[3]= 4 として、a自体を1234、bを2234と考えて、大小比較を行いたいわけなんです この場合はb>aみたいな感じで・・・
420 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:34:33 ] memcmpとかでいいのとちがうん? 配列で連続してればcharで見てやって
421 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:38:18 ] >>419 if ((a[0] * 1000 + a[1] * 100 + a[2] * 10 + a[3]) < (b[0] * 1000 + b[1] * 100 + b[2] * 10 + b[3])) { // bが大きい } else { // aが大きい } とかじゃ駄目なの?
422 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:38:42 ] >>420 今調べてみましたが buf1 と buf2 を先頭から n バイト分比較します。比較はunsigned char として行われます とあるのですが、int型でも関係なくできるものなんですか? intとcharじゃバイト数が全然違うので、なんか変なことになりそうな気もするのですが・・・
423 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:39:43 ] >>421 配列が何個もあるんです・・・ んで、バブルソートみたいなことをやりたいので、そのように書くととんでもないことになるんですorz 関数として何か簡単に比較できるものがないかな〜という感じで探してたのですが、いいのがなくて('A`
424 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:40:28 ] >>422 同じCPU環境化でメモリに入れちゃえばcharだろうがなんだろうがw 長ささえ同じなら問題ないよ。 エンディアンの問題も関係ないし。
425 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:41:45 ] 4桁固定?例えば0030とか0111とか。 それなら1桁目からソートしていけば良さそうだけど。
426 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:43:56 ] >>424 なるほど・・・。ためしにちょいと動かしてみます〜
427 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:46:24 ] int a[4]={1,2,3,6}, b[4]={1,2,3,5}; int i = 0,c = 0; while(!(b[i]-a[i]) && c < 3)i++, c++; if(b[i]-a[i]==0)puts("同じ"); else if(b[i]-a[i]>0) puts("bのがおおきい"); else puts("aのがおおきい");
428 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:52:21 ] >>419 のサンプルでいけば ビッグエンディアン系だとメモリに格納された場合はこんな感じ a 00000001 00000002 00000003 00000004 b 00000002 00000002 00000003 00000004 で格納する元も両方intで比べる際もcharでもいいしunsigned charでもいいし両者の条件さえ同じなら比較する桁もあうので問題ない リトルエンディアン系でも同じ ビッグエンディアン系だとメモリに格納された場合はこんな感じ a 01000000 02000000 03000000 04000000 b 02000000 02000000 03000000 04000000 intをレジスタ上で扱う場合は@ABC(<-バイトの並びね)だったらメモリにはCBA@とアドレスの最初から格納されるけど 通信でほかに渡したしりなければ同じエンディアン系で処理されるので結果memcmpであろうが比較する桁はいっしょなので 問題ない
429 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:53:30 ] ↑で書いた数字は全部16進数ね
430 名前:こうならないの? mailto:sage [2008/08/19(火) 18:57:27 ] ビッグエンディアン a 00000F01 00000002 00000003 00000004 b 00000002 00000002 00000003 00000004 (a > b) リトルエンディアン a 010F0000 02000000 03000000 04000000 b 02000000 02000000 03000000 04000000 (b < a)
431 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:59:01 ] 例を見る限り、配列に入ってるのは一桁の10進数だろ
432 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 18:59:11 ] >>430 エンディアン系を意識すればいいだけだろw
433 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:02:00 ] >>432 memcmpが意識してくれるの?
434 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:04:58 ] memcmpの結果を意識しろよw 大きいか小さいかイコールでくれるんだろw そんなことも考えれないようなら素直にループで1つ1つやれw
435 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:17:40 ] >>434 こういうのは? リトルエンディアン a 01010000 02000000 03000000 04000000 b 00020000 02000000 03000000 04000000 memcmpの結果 (a > b) リトルエンディアン a 00010000 02000000 03000000 04000000 b 00020000 02000000 03000000 04000000 memcmpの結果 (b < a) でも実際は、どちらも b > a にならなければおかしい
436 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:36:17 ] 誰か、いまだにエンディアンについてよくわかってない俺に図解!マンガでわかるエンディアンを頼む
437 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:42:35 ] >>436 数字があるとするじゃん。 一番上の位から読む?(ビッグエンディアン) それとも一番下の位から読む?(リトルエンディアン) って話。
438 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:44:20 ] >>437 いやそれは違う・・・ メモリ上に複数バイトで構成される数字を格納した際の 格納のされ方の違いだよ。
439 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 19:50:02 ] エンディアン糞フカナイ
440 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 20:45:12 ] >>439 汚ぇなぁ、おい。 >>435 >431 >>416 unix系なら、gettimeofday()がそこそこ使える。こいつは実時間だ。 既に指摘の通り、clock()はCPU時間だから要注意だ。
441 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 21:00:10 ] >>423 比較する関数を作ればいいだけなんじゃないの? エンディアンを意識してどうこうするよりよほど楽だと思うんだけど
442 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 21:06:39 ] >>423 こんなんとか int cmp(int a[4], int b[4]){ int i, ret; for(i=0;i<4;i++){ ret=a[i]-b[i]; if(ret) break; } return ret; }
443 名前:デフォルトの名無しさん [2008/08/19(火) 21:38:42 ] いつのことだったか、ガリバーという人が訪ねたある国の人々が、 卵を大きい方の端から割る派閥(ビッグエンディアン)と、 卵を小さい方の端から割る派閥(リトルエンディアン)とに分かれて 争っていたんだそうな(とある国の政治家の風刺でもあるんだが)。 それにちなんで、MSBから先に格納するのをビッグエンディアン、 LSBから先に格納するのをリトルエンディアンと呼ぶんじゃよ。
444 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 21:46:40 ] 扱う数値の範囲によっては>>442 だとオーバーフローして逆の符号を返す可能性もある
445 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 21:48:34 ] 計算結果がオーバーフローorアンダーフローしてるかどうかを調べることってできる?
446 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 21:50:30 ] >>445 標準Cの範囲内では無理じゃないかな?
447 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 22:11:52 ] >>440 ちょw 条件後付
448 名前:440 mailto:sage [2008/08/19(火) 22:38:10 ] >>447 私に言うな。
449 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 22:53:17 ] ふつうに計算じゃなくてビット演算組み合わせればオーバーフローもチェックできるんじゃね?って思った
450 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:01:45 ] >>445 ,446,449 できるよ。 符号付きとなしとで微妙に変わるけど、加減算なら二つの数値の 最上位ビット見ればいい。 乗除算もちょっと手間かかるけどできなくはない。
451 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:09:23 ] 具体的にどうやんの 加算でもいいから教えてくだちい
452 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:16:07 ] 符号付での二つでの足し算で言うと 負と負なら答えは負なので最上位ビットは普通はずっと1、 オーバー フローすると0になる 負と正ならそもそもオーバーフローしない 正と正ならオーバーフローすると最上位は1になる そんな感じ
453 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:17:01 ] 桁あふれか 加算なら結果からもう一回引いてみればいいんじゃね? 元の数字に復元できれば桁あふれ無し。 元の数字にもどら無ければ桁あふれあり
454 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:26:06 ] オーバーフローした結果から引いたらアンダーフローして元に戻ると思うよ ・・・アンダーフローって意味違うような気がした
455 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:27:45 ] 半分のビット数ごとに分けて計算する
456 名前:デフォルトの名無しさん [2008/08/19(火) 23:31:35 ] >>453 お戯れを。
457 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:33:35 ] logで計算する
458 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:38:17 ] logで足し算できるものなら教えて欲しい。
459 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:39:47 ] 指でも折って数えるんだ 足りなくなったら隣の人の借りろ マイナスなど知らん
460 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:44:17 ] >>445 そもそも、どんなデータなんだよ。 そのオーバーフローやアンダーフローを気にしなくてはいけないデータというのは。
461 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:51:07 ] int add(int a, int b, int *p_is_overflow){ int chk_type, result, is_over_flow=0; chk_type=(a<0)*2+(b<0); result=a+b; switch(chk_type){ case 0: if(result>0) is_over_flow=1; break; // a, b ともに 0 以上なので解も 0 以上になるべき case 3: if(result<0) is_over_flow=1; break; // a, b ともに 0 未満なので解も 0 未満になるべき } if(p_is_over_flow) *p_is_over_flow=is_over_flow; return result; }
462 名前:デフォルトの名無しさん mailto:sage [2008/08/19(火) 23:52:00 ] >>461 case の 0 と 3 間違えた
463 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 01:01:39 ] >>460 ちょっとした計算を代わりにやってもらうのプログラムなんですが 計算過程を式としては理解しているのですが、 計算途中の値がどの程度の大きさになっているのは知りません 知らないうちにオーバーフローしてるんじゃないかと少し不安なんです もちろん値が狂ったら答えも大抵はおかしくなるでしょうからそうそう困ることはないのですが
464 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 01:04:47 ] 出た答えが正常かおかしいかは判断できるのか? 方程式の解とかで元の式に代入して検算とかできるのなら困らないけど
465 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 01:37:58 ] >>461 の修正版 int add(int a, int b, int *p_is_overflow){ int chk_type, result, is_overflow=0; chk_type=(a<0)*2+(b<0); result=a+b; switch(chk_type){ case 0: if(result<0) is_overflow=1; break; // a, b ともに 0 以上なので解も 0 以上になるべき case 3: if(result>=0) is_overflow=1; break; // a, b ともに 0 未満なので解も 0 未満になるべき } if(p_is_overflow) *p_is_overflow=is_overflow; return result; } 掛け算は a*b/b==a をチェックすればいい 整数同士の除算は一つの例外を除いてオーバーフローしない (0div はあるけど)
466 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 01:57:37 ] その例外は・・・?
467 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 02:00:18 ] ヒント・大抵正の最大値より負の最少値のほうが絶対値が大きい
468 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 02:02:27 ] >>466 読みたくば●を買え C言語なら俺に聞け(入門篇) Part 12 pc11.2ch.net/test/read.cgi/tech/1178620766/951-952
469 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 02:04:57 ] 951 名前:デフォルトの名無しさん[sage] 投稿日:2007/05/15(火) 14:28:25 これでダメな場合って lop==0 の時以外にあるかな? result=lop*rop; if(result/lop!=rop) オーバーフロー 952 名前:デフォルトの名無しさん[sage] 投稿日:2007/05/15(火) 14:54:12 >>951 っ lop=-1 rop=INT_MIN
470 名前:402 mailto:sage [2008/08/20(水) 09:34:26 ] >>440 ありがとうございます。 今作っている物は1秒ごとの判断で良かったので最終的にtime()関数を使うことにしました。 gettymeofday();も今度試してみます。
471 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 10:39:41 ] このプログラムなら正常に動くんですが、main関数内のnibai関数を scanf("%d",&a); nibai(a); printf("二倍した数値は%d\n",a); と書くと2倍してくれないんですが、何故でしょうか? ----------------------------------------------------------- #include<stdio.h> int nibai(int x); int main(void){ int a; printf("数値を入力してください:"); scanf("%d",&a); printf("二倍した数値は%d\n",nibai(a)); return 0;} int nibai(int x){ int wk; wk=x*2; return wk;}
472 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 10:59:39 ] a = nibai(a);
473 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 11:00:37 ] あーなるほど!! ありがとうございます。
474 名前:ym [2008/08/20(水) 13:43:00 ] 受け渡された文字列が'0000'〜'2359'の時刻範囲内かをチェックする プログラムを教えてください。お願いします。 チェック内容は以下の通りです。 1. 受け渡された文字列が全て数値であること。 2. 受け渡された文字列の先頭2文字が'00'〜'23'の範囲であること。 3. 受け渡された文字列の3文字目〜4文字目が'00'〜'59'の範囲であること。 正常終了時:return 0 異常終了時:return -1(時刻範囲外)
475 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 13:45:10 ] 教えて欲しいのではなく宿題を丸投げしたいだけなら 宿題スレへ行ってください。
476 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 13:48:49 ] なんか最近範囲内チェックの質問多いな。全部同じやつか?
477 名前:ym [2008/08/20(水) 13:57:04 ] char hh[3]; char mm[3]; int h; int m; hh[0]=pstime[0]; hh[1]=pstime[1]; hh[2]='\0'; mm[0]=pstime[2]; mm[1]=pstime[3]; mm[2]='\0'; h=atoi(hh); m=atoi(mm); if((h >= 0 && h <= 23)&& (m >= 0 && m <= 59)){ return RET_OK; }else{ return RET_NG; } } int main(void) { char str[256]; int chk; gets(str); chk = N60901D04(str); printf("\nreturn=%d\n",chk); } 受け渡された文字列が'0000'〜'2359'の時刻範囲内かをチェックするプログラムなんですけど、コンパイルをしたら、 アルファベット4文字を入力してもreturn 0(正常)で判定されてしまったん ですけど、プログラムの中のどこが悪かったのか、教えてください。お願いします。
478 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 13:59:57 ] たぶん、数字以外で数値に変更できなかったから0になって0時0分は有効だから、じゃない? isdigit とかで先にチェックするとか。
479 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:00:28 ] >>474 int main(int argc, char *argv[]) { char *p; int n; for(p=argv[1] ; *p ; p++) switch(*p) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': break; default: return -1; } switch(argv[1][0]) { case '0': case '1': break; case '2': switch(argv[1][1]) { case '0': case '1': case '2': case '3': break; } default: return -1; } switch(argv[1][2]) { case '0': case '1': case '2': case '3': case '4': case '5': break; default: return -1; } return 0; }
480 名前:デフォルトの名無しさん [2008/08/20(水) 14:01:42 ] >>477 atoiで変換は失敗すると0を返すからじゃね
481 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:02:11 ] あ、n消し忘れた
482 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:03:47 ] >>479 4桁目のチェックが抜けてないか?
483 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:05:20 ] >>482 必要あるか?
484 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:05:42 ] >>482 あーそうだね switch(argv[1][2]) { case '0': case '1': case '2': case '3': case '4': case '5': if(argv[1][3]) break; default: return -1; } こうか
485 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:07:05 ] >>483 ある [3]が\0のときも無視して通してしまう
486 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:09:08 ] 2桁目も switch(argv[1][0]) { case '0': case '1': if(argv[1][1]) break; だな
487 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:22:21 ] int check_time(const char *hhss) { int i, hour, second; if (strlen(hhss) != 4) return -1; for (i = 0; i < 4; i++) if (!isdigit(hhss[i])) return -1; hour = (hhss[0] - '0') * 10 + (hhss[1] - '0'); second = (hhss[2] - '0') * 10 + (hhss[3] - '0'); return (0 <= hour && hour < 24 && 0 <= second && second < 60) ? 0 : -1; }
488 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:29:42 ] 教えてください int型の2次元配列の先頭のポインターだけをもらってくる関数があります。 配列のサイズはわかっているんですが関数内で見る際にはどう記述すればいいでしょうか? これを関数内でいじりたい unsigned int hoge2div[100][200]; 関数を呼ぶ前に連絡用構造体の所定のエリアに2次元配列のポインターを格納してます。 (unsigned int* )hoge->ptr = hoge2div; 関数内の定義(ここを直したい。) unsigned int* 2div = (unsigned int* )2div->ptr;
489 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:30:40 ] >関数を呼ぶ前に連絡用構造体の所定のエリアに2次元配列のポインターを格納してます。 >(unsigned int* )hoge->ptr = hoge2div; こっちが正解です hoge->ptr = hoge2div;
490 名前:デフォルトの名無しさん mailto:sage [2008/08/20(水) 14:36:52 ] unsigned int (*p)[DIV1_SIZE]=(unsigned int (*)[DIV1_SIZE])hoge->ptr;