[表示 : 全て 最新50 1-99 101- 201- 301- 401- 2chのread.cgiへ]
Update time : 05/09 14:16 / Filesize : 113 KB / Number-of Response : 491
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

C言語なら俺に聞け(入門篇) Part 34



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;






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<113KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef