C言語なら俺に聞け( ..
[2ch|▼Menu]
331:デフォルトの名無しさん
08/06/05 20:36:22
関数の処理が正しいかどうかは知らんが
フィボナッチ数列ならf(0) f(1)は固定でいれなきゃじゃない?

332:デフォルトの名無しさん
08/06/05 20:36:25
>>330
なら答えはひとつしかない

「わからない」

fの値がなんになるかはnの値のほかpush()、pop()、empty()、show()の仕様に依存する
fの値がどう使われるかはこの関数を呼んだ場所のコードに依存する
つまりこの関数だけ見せられてfがなにものであるか答えられるわけがない

333:デフォルトの名無しさん
08/06/05 20:38:12
>>329
少なくともこのままコンパイルにかけたら構文エラーだな

334:デフォルトの名無しさん
08/06/05 20:38:51
>>327
それであってるし0から始まるフィボナッチ数列の四番目は3だからおk

335:デフォルトの名無しさん
08/06/05 20:45:03
push()は()内をプッシュ、
pop()はポップしてその値を返す、
empty()はタックが空かどうか判定する、
show()は現在のスタック内表示です


336:デフォルトの名無しさん
08/06/05 20:46:54
>>334
fはスタックとは別のところで計算されてると考えてよろしいんでしょうか?

337:デフォルトの名無しさん
08/06/05 20:47:18
int fibo_stack( int n )
{
vector<int> x;
int f =0;
x.push_back(n);
while(!x.empty()) {
n = x.back();
x.pop_back();
if( n==0 ) f+=0;
if( n==1 ) f+=1;
if( n>=2 ) {x.push_back( n-1); x.push_back( n-2);};
}
return f;
}

極普通のスタックだと思うのですが因縁つけてくる人が多いので
C++になっちゃいますが動くようにしました。
引き続きお答え願います

338:デフォルトの名無しさん
08/06/05 20:49:07
そこまでわかっててなぜわからんのかわからん

339:デフォルトの名無しさん
08/06/05 20:49:44
単にフィボナッチ数列というものを知らないのでは

340:デフォルトの名無しさん
08/06/05 20:55:23
このプログラムのfを足していく理由がわからないんです。
スタックを計算する上で必要な事なんでしょうか


341:デフォルトの名無しさん
08/06/05 21:03:35
fって言う時点でフィボナッチと関連あるとか想像付かないかな・・・
Wikipedia項目リンク

342:デフォルトの名無しさん
08/06/05 21:09:37
解りました!!fはn番目のフィボナッチ数を計算するためにあったんですね!!
ずっとスタック内に影響するものだと思ってました。
ありがとうございました。

343:デフォルトの名無しさん
08/06/05 21:10:51
なぜこれで正しく計算できるかまではわかったのかなー?
そこが意図のはずだが

344:デフォルトの名無しさん
08/06/05 21:11:56
>343
どっちかっつーと数学板の仕事だし…
実用でこんなタコなアルゴリズム書いたら殴られるわ

345:デフォルトの名無しさん
08/06/05 21:12:14
やってることは再帰と同じくらい効率悪いなw

346:デフォルトの名無しさん
08/06/05 21:14:47
スタックを使う理由がわからん

347:デフォルトの名無しさん
08/06/05 21:17:10
数学的な数列の再帰証明をプログラムに変換するために必要だったんだろう
こんなことやる意味がそもそもあるのかと思うけど

348:参考
08/06/05 21:28:29
再帰呼び出し関数で、フィボナッチ数列を計算するコードを定義した際にn=0,1の条件で関数が何回
呼ばれるかを計測するプログラム。奇しくもこれはフィボナッチ数列そのものを与えるという
トリック

unsigned int fib(unsgined int n){
static unsigned int m=0;
static unsigned int result=0;
if(m==0)
m=n;
if(n<=1)
result++;

else{

fib(n-1);
fib(n-2);

}
if(m==n)
return result;
}
(この関数は1回しか呼び出せないのがイタいが)

349:参考
08/06/05 21:33:06
mなんていらねぇな。
unsigned int fib(unsgined int n){
static unsigned int result=0;
if(n<=1)
result++;
else{
fib(n-1);fib(n-2);
}
return result;
}


350:デフォルトの名無しさん
08/06/05 21:33:08
当たり前って言えば当たり前の結果だよな

351:デフォルトの名無しさん
08/06/05 21:35:29
つーか、IT関連の授業教えてる先生ってこんなのばっかり出題してるのか?
大学院とか行って研究するやつなんてすくないんだからもうちょっと実用的
な問題だせよ。

昨日もBMPの読み込みとかなかったっけ?

352:デフォルトの名無しさん
08/06/05 21:40:15
この件については議論せずにスルーしような

353:デフォルトの名無しさん
08/06/05 21:46:10
>>326
キャストは左辺値にも出来ますが何か?
char *p;
void *q;

(char*)q=p;

354:デフォルトの名無しさん
08/06/05 21:48:42
フィボナッチ理解できない人間が結構いることに驚き

355:デフォルトの名無しさん
08/06/05 21:49:57
>>353
それはだめじゃないのか?

356:デフォルトの名無しさん
08/06/05 21:51:39
>>353
間違いである。少なくともANSI/ISO規格の保証する動作ではない。

357:デフォルトの名無しさん
08/06/05 22:00:43
固定長のフィールドからなるレコードを
fgetsした後にsscanfでバラバラにして
フィールド毎にprintfで表示したいんだが
うまくsscanfでバラせてないみたい・・・

AAAAA
BBB
CCCC
こうなって欲しい。

入力ファイル(固定長5、3、4の3フィールドからなる)
AAAAABBBCCCC



358:デフォルトの名無しさん
08/06/05 22:01:14
禁止しても、抜け穴が幾らでもありそうだな。

359:デフォルトの名無しさん
08/06/05 22:04:01
>>357
それって区切りになる文字が無いから失敗するんじゃないの?


360:デフォルトの名無しさん
08/06/05 22:04:15
>>357
sscanf(s, "%5s%3s%4s", a, b, c);
これで済まないのか?


361:デフォルトの名無しさん
08/06/05 22:06:17
>>342
だから>>331でフィボナッチだっつってんじゃん
関数名見ても分からないとか大丈夫か?

362:デフォルトの名無しさん
08/06/05 22:07:53
>>357
ばらせてるけどNULL終端じゃないから残りが出てるだけに5ペリカ

363:デフォルトの名無しさん
08/06/05 22:07:54
>>361
まーそういうなって。
初めてのころは「自分が何にはまってるかそれがわからない」
ということもあるよ。

あることをきっかけにどんどん進むのさ・・・

364:デフォルトの名無しさん
08/06/05 22:10:26
わかってないのに見当違いのレスつけてるヤツらよりはマシだけどな

365:デフォルトの名無しさん
08/06/05 22:10:34
>353

4.5
質問:charのポインタがあって、そのポインタがたまたまintを指していた。
intの次へポインタを進めたい。なぜ以下の式ではうまくいかないのか。

 ((int *)p)++;

回答:C言語でキャスト演算子は「ビット列が別の型を持っているふりをして、
そういう風に扱ってやろう」ということを意味しているわけではない。
キャストは変換演算子であって、それは右辺値を生みだすと定義されている。
右辺値であるとするなら、代入することも++で足し算することもできないことになる
(古いコンパイラやgccの拡張機能が上のような式を受け付けることは例外である)。

References: K&R2 §A7.5 p.205 / ANSI §3.3.4(とくに注14) / ISO §6.3.4 / Rationale §3.3.2.4 / H&S §7.1 pp.179-80

366:デフォルトの名無しさん
08/06/05 22:28:22
公開された定義に基づいて
再解釈可能なものについては再解釈し、そうでないものは絶対に通さないというのが
基本だったのだが...
いつのまにやら処理系に依存する話になってしまった。

367:デフォルトの名無しさん
08/06/05 22:55:01
こう書けばとおるが、
*(char**)&q=p;
そもそもvoid *へ/からの変換はキャストが不要なのでこの例なら
q=p;
でよい。

368:デフォルトの名無しさん
08/06/05 22:55:55
- キャストが不要なので
+ 明示的なキャストが不要なので

369:デフォルトの名無しさん
08/06/05 22:56:40
((struct hoge*)p)->fuga

370:デフォルトの名無しさん
08/06/05 22:58:00
**a と a[][] って、同じ?

371:デフォルトの名無しさん
08/06/05 22:58:40
仮引数でなら

372:デフォルトの名無しさん
08/06/05 23:00:54
仮引数でも違う。
というか、不完全型の配列型は存在しない。

373:デフォルトの名無しさん
08/06/05 23:01:33
コンパイルは通るよ。

374:デフォルトの名無しさん
08/06/05 23:02:23
通らんかった。二次元はダメか。

375:デフォルトの名無しさん
08/06/05 23:06:05
>>370
仮引数に限ってT**とT*[]は同じ。T[][]はT[]が不完全型だから許されない。

376:デフォルトの名無しさん
08/06/05 23:07:39
仮引数の[]は、識別子に最初に結合する一回だけポインタ扱い

377:デフォルトの名無しさん
08/06/05 23:20:18
>>369
-> の結果は左辺値になりうる。

378:デフォルトの名無しさん
08/06/06 00:04:07
多次元配列はC/C++の最もクサいところ。使わないでね。なるべく。
(普通の1次元配列を工夫して使って)

379:デフォルトの名無しさん
08/06/06 00:07:57
int main(int argc, char** argv)


int main(int argc, char argv[][])


380:デフォルトの名無しさん
08/06/06 00:08:46
>>379
悪い例ですね、わかります

381:デフォルトの名無しさん
08/06/06 02:21:47
メモリの動的確保とポインタについて勉強したのですが、
分からないところがあったので質問します

・mallocで確保したメモリは、プログラムの終了と同時に解放されることは保証されているのか
・関数内でmallocで確保したメモリは関数が終了しても解放されず、
 別の関数から参照できることは保証されているか

両方、正常に動くことは確認できたのですが、あらゆる環境・状態で成り立ちますか?

382:デフォルトの名無しさん
08/06/06 02:25:13
・プログラムが終了すれば解放はされる
・別の関数にアドレスを渡せばそりゃ参照できる

383:デフォルトの名無しさん
08/06/06 02:25:20
>>381
Cの規格では保証されてない、プログラム終了後の処理はOS頼み
ただし、間違いなく解放されると思って問題ない。(されないOSが昔あるにはあったが)

二番目は保証されてる、こっちはそう決まってる

384:デフォルトの名無しさん
08/06/06 02:27:49
関数からポインタを返すときって混乱しやすいところだよね。

385:デフォルトの名無しさん
08/06/06 04:34:47
あんまりC言語関係ないけど
#include <stdio.h>
#include <stdlib.h>
void main(){
int a[25];
int i,j;
for(i=0;i<25;i++){
a[i] = rand()%25+1;
for(j=0;j<i;j++){
if(a[j]==a[i]){
a[i] = rand()%25+1;
j=0;
}
}
printf("a[%d]は%dです。\n",i,a[i]);
}
}

↑のは
a[0]〜a[24に]1〜25の乱数を生成し、且つどれも一致しないというモノなんだけど
乱数が何度やっても決まった値しかでないんだけどどうすればいいのかな?
あと、j=0;とかやってたりソースかなり読みにくいので、訂正などあったらガンガンお願いしますmm

その際解説もつけてくれるとありがたいです

386:デフォルトの名無しさん
08/06/06 04:37:29
#include <time.h>

srand(unsigned)time(NULL));

を足す

387:デフォルトの名無しさん
08/06/06 04:37:53
括弧抜けた
srand((unsigned)time(NULL));


388:デフォルトの名無しさん
08/06/06 04:46:41
あー解説か…まあ細かい話はおいておいて
乱数発生させるには最初に種みたいなのが要るんだけど

srand((unsigned)time(NULL));
はプログラムを実行させた時の現在時刻を拾ってきて
それを種にするように設定する関数なわけ

>>385のプログラムだと何もして無いのでsrand(1);
と設定した事とみなされて
常に同じ乱数が生成されてるのよ

389:デフォルトの名無しさん
08/06/06 06:06:42
Cのプログラムの中で、
system("hoge")で起きたコマンドの結果を文字配列に格納したい場合、何かいい方法は無いですかね?
コマンドライン上ならls > fileで一発なのに・・・orz

390:側近中の側近 ◆0351148456
08/06/06 06:21:52
>>389
(っ´▽`)っ
popen, pclose
標準ライブラリ関数ではないが、unix系OSだと使える。

391:デフォルトの名無しさん
08/06/06 06:29:17
>>390
感謝。さっそく調べて試してみるっすー。

392:デフォルトの名無しさん
08/06/06 08:34:52
>>381
まあmallocも関数でvoid*ではあるけどポインタ返ってくるよね?

393:デフォルトの名無しさん
08/06/06 10:48:52
#include <stdio.h>
#include <float.h>
int main(void)
{ float f;
double x;
long double ld;
printf("\nTesting the precision of float, double, and long double : \n");
f = 1.0f + 1.0e-7;
printf(" 1.0 + 1.0e-7 = %.10f\n", f);
f = 1.0f + 1.0e-8;
printf(" 1.0 + 1.0e-8 = %.10f\n", f);
x = 1.0l + 1.0e-15;
printf(" 1.0 + 1.0e-15 = %.20lf\n", x);
x = 1.0l + 1.0e-16;
printf(" 1.0 + 1.0e-16 = %.20lf\n", x);
ld = 1.0L + 1.0e-19;
printf(" 1.0 + 1.0e-19 = %.30Lf\n", ld);
ld = 1.0L + 1.0e-20;
printf(" 1.0 + 1.0e-20 = %.30Lf\n", ld);
printf("\nThe experiment above is explained by constants from float.h :\n");
printf(" precision of float : %e\n", FLT_EPSILON);
printf(" precision of double : %.15le\n", DBL_EPSILON);
printf(" precision of long double : %.30Le\n", LDBL_EPSILON);
return 0; }
表示された結果のうち、
1.0 + 1.0e-7 が 1.0000001 にならず、同様に
1.0 + 1.0e-15 が 1.000000000000001 にならず、
1.0 + 1.0e-19 が 1.0000000000000000001 という、きれいな数にならない理由を、FLT_EPSILON, DBL_EPSILON, LDBL_EPSILON との関係から説明してもらえないでしょうか。
よろしくお願いします。

394:デフォルトの名無しさん
08/06/06 11:07:42
宿題丸投げは宿題スレへ

自分で考えるヒントが欲しいなら、まずそこに出てくる制限定数の意味やIEEE浮動小数点数フォーマットについて調べること

395:デフォルトの名無しさん
08/06/06 11:33:43
板違いごめんなさいッ
ありがとうございます。

396:デフォルトの名無しさん
08/06/06 12:42:40
問03
学科の出席簿作成。
15人分の学生を表示し、入力により内容を変動させる。

表示順番:
出席表
<入力>学生番号0〜14
<入力>曜日番号0〜6
<入力>時限番号0〜3
<入力>出欠番号0〜1


<入力>学生番号0〜14の時に99を入力するとプログラム終了。
誰かこの問題教えてください。

397:デフォルトの名無しさん
08/06/06 12:44:01
>>396
氏ね

398:デフォルトの名無しさん
08/06/06 12:59:39
>>396
/* stdio.h をインクルード */
int main(void)
{
  /* 必要な変数を宣言し、出席簿の初期値を設定 */

  /* 学生番号を入力から一時変数に取り込み、それが妥当な値である間、以下の処理を繰り返す */
  {
    /* 曜日を入力から一時変数に取り込み、もし妥当な値でなければエラーメッセージを表示して continue する */
    /* 時限を入力から一時変数に取り込み、もし以下略 */
    /* 出欠を入力から以下略 */
    /* 入力された一時変数の値を出席簿に反映する */
    /* 出席簿の現在の内容を表示する */
  }

  return 0;
}

399:デフォルトの名無しさん
08/06/06 13:02:11
>/* 学生番号を入力から一時変数に取り込み、それが妥当な値である間、以下の処理を繰り返す */
親切そうに見せて性格悪いなお前

400:デフォルトの名無しさん
08/06/06 13:23:10
出席簿のデータ構造くらいは教えてやったほうがよくね?

int book[15][7][4]={0};

まあcharにするほどのサイズではあるまい

401:デフォルトの名無しさん
08/06/06 13:23:58
日曜日に授業あんのかよ

402:デフォルトの名無しさん
08/06/06 13:25:40
たまに・・・・・

403:デフォルトの名無しさん
08/06/06 13:28:03
>398
必要な変数ってこれでいい?
データ形式:
(一人分のデータ)
学生番号<int>
名前<char*>
性別<char*>
曜日番号<int[]>
時限番号<int[]>
出欠番号<bool>
変更番号<bool>

404:デフォルトの名無しさん
08/06/06 13:30:25
Cにboolはありません

405:デフォルトの名無しさん
08/06/06 13:31:02
396のどこに名前と性別があるんだよ

406:デフォルトの名無しさん
08/06/06 13:32:38
じゃあ _Bool で

407:デフォルトの名無しさん
08/06/06 13:34:00
学生の名前も含めて構造体で表すなら
struct{
 char name[NAMELEN_MAX];
 int sex;
 int attend[7][4];
}student[15];
ってとこか

408:デフォルトの名無しさん
08/06/06 13:38:20
>>403
学生番号は不要。要素15の配列の添字で扱えば済む。
名前は動的割付するほど大きなデータじゃない。適当な大きさの配列で十分。
性別は整数でいい。男か女かそれ以外しかないのだから。
曜日、時限、出欠を別々に宣言しても意味がない。多次元配列を使え。
Cにbool型は無い。メモリを節約したいならchar型を使え。
変更番号ってなんだ説明しろ。

409:デフォルトの名無しさん
08/06/06 13:41:19
> char name[NAMELEN_MAX];
そこは NAMELEN_MAX+1 にしとけよ
一応

410:デフォルトの名無しさん
08/06/06 13:45:44
>>408
退学とかで、欠番の可能性は?

411:デフォルトの名無しさん
08/06/06 13:47:18
>>410
問題の前提が番号は0〜14まで15人ってなってる

412:デフォルトの名無しさん
08/06/06 13:47:40
そこで性別をenumですよ

413:デフォルトの名無しさん
08/06/06 13:48:43
>408
>名前は動的割付するほど大きなデータじゃない。適当な大きさの配列で十分。
初期化したあと変更しないならconstポインタのほうがいいんじゃね?

414:デフォルトの名無しさん
08/06/06 13:52:11
後出しの条件はともかく、まずは>398を作れ
話はそれからだ

415:デフォルトの名無しさん
08/06/06 14:03:48
入力はgetchar?99を入力するとプログラム終了ってどうやんだっけ?

416:デフォルトの名無しさん
08/06/06 14:06:50
本当はfgetsを使うんだがこのレベルの問題ならscanfでいいだろう

417:デフォルトの名無しさん
08/06/06 14:07:31
>>415
おいおいそこから教えなきゃいけないのかよ
もう一回最初から本を読み直せ

418:デフォルトの名無しさん
08/06/06 14:10:57
どうやんだっけ?じゃねーよw
素直に全く分かりませんって言えよ

419:デフォルトの名無しさん
08/06/06 14:14:51
すまぬがちょっと質問。

MinGWとVC++でDLL連携をしようと思って下記みたいなソース書いたんだ。
GeoOpen関数に「1」を渡してるのに
返ってくる値は何故か「63」。
printfで出力される値も「63」。
なんぞこれー


DLL作成側cpp(MinGW)
extern "C" __declspec(dllexport) int __stdcall GeoOpen(string strLicence, string strGeoDBDir, string strNormalize, int intA) {
printf("%u", intA);
return intA;
}

DLL呼び出し側cpp(VC++)
// GeoOpen関数のポインタ取得
GEOOPEN geoOpen = (GEOOPEN)GetProcAddress(hGEOCODERDLL, "GeoOpen@16");

int testInt = 1;
// GeoOpen関数のポインタ取得成功
if (geoOpen != NULL)
{
// GeoOpen関数呼び出し
int intRes = (*geoOpen)(strLicence, strGeoDBDir, strGeoDBDir, testInt);
}

420:デフォルトの名無しさん
08/06/06 14:15:34
エラーメッセージって表示しなきゃなんないのか?

421:デフォルトの名無しさん
08/06/06 14:17:05
>420
「そんなの問題に書いてないじゃないですか」で押し通せるならしなくていい
常識的にはする

422:デフォルトの名無しさん
08/06/06 14:17:13
>>419
MinGWとVC++のstd::stringの内部構造が異なるんじゃないのかたぶん

423:デフォルトの名無しさん
08/06/06 14:19:51
というか完璧スレ違い

424:デフォルトの名無しさん
08/06/06 14:28:13
>>422
試しにintを第一引数にしたらちゃんと1が返ってきたよ。
stringが邪魔してたのか、、、これは気づかなんだ。
サンキュー助かった。

>>423
あぁC++はスレチか。すまん


425:デフォルトの名無しさん
08/06/06 14:28:58
異なるコンパイラ、コンパイラが同じでもバージョンが違う場合、モジュール間でのクラス渡しは御法度。
クラスで渡したければCOM使うしかない。

426:デフォルトの名無しさん
08/06/06 14:35:16
COMってなんぞえー!?

427:デフォルトの名無しさん
08/06/06 14:37:39
C++つかわず、CだけでCOM(ActiveX)のプログラムするのは死ぬほど辛い

428:デフォルトの名無しさん
08/06/06 15:48:13
素直にポインタを使え

429:デフォルトの名無しさん
08/06/06 21:35:24
strtokを使ってカンマ区切りの文字列を分け、それぞれの文字配列に格納する関数を作ってるのですが、
関数の中で正常に表示される文字配列が、関数の外だと化けるんですよ!

何が原因なのでしょうか?お手上げです。どなたかどうか、教えてくださいm(_ _)m

430:デフォルトの名無しさん
08/06/06 21:36:24
ローカル変数を外に持ち出そうとしてるのか?

431:デフォルトの名無しさん
08/06/06 21:41:00
ソースうp

432:デフォルトの名無しさん
08/06/06 21:45:23
B木の話なんですが質問させてください、二分木でも同じと思いますが
ノードに入るkeyの値は自然数としています

現在の木に例えば3という値が入っているときにさらに3を挿入する場合は
すでに入っている3の手前と後ろのどちらに入れるかは決まっているんですか?

433:デフォルトの名無しさん
08/06/06 21:49:14
比較の仕方によるけど、だいたい後ろになるんじゃね?

434:デフォルトの名無しさん
08/06/06 21:54:38
>>430
文字配列はmainで宣言していて、関数の中では、char*型で引数宣言しています。

>>431
今携帯なので、うち帰ってからまたソースうpさせていただきますね。

すみません、また来ます。ありがとうございます。

435:デフォルトの名無しさん
08/06/06 21:57:55
>>434
たぶん、その引数のポインタにstrtokの戻り値を代入してるだけだろう?
ちゃんとstrcpyしろ

436:デフォルトの名無しさん
08/06/06 22:03:51
>434
こういうことをやってないかどうか

#include <stdio.h>
void hoge(char *str)
{
  str="STRING"; /* 間違い */
/* こっちが正解
  strcpy(str, "STRING");
*/
}

int main(void)
{
  char str[]="string";
  hoge(str);
  puts(str);
  return 0;
}

437:デフォルトの名無しさん
08/06/06 22:04:41
>>436
まてそれは大丈夫だろw

438:デフォルトの名無しさん
08/06/06 22:06:36
>>437
落ち着け

439:デフォルトの名無しさん
08/06/06 22:08:22
>>438
ごめんおちついた、ごめんなさい
mainみないで条件反射してしまいました・・・

440:デフォルトの名無しさん
08/06/06 22:10:46
435の解釈が妥当そう。
strtokの戻り値は次のstrtokの呼び出しで破壊されるから、
strdupしておくべし。


441:デフォルトの名無しさん
08/06/06 22:11:29
>440
お前も落ちつけよ

442:デフォルトの名無しさん
08/06/06 22:14:59
>strtokの戻り値は次のstrtokの呼び出しで破壊されるから
されんされん

443:385
08/06/06 23:01:23
>>386-388
なるほど、ありがとうございます

444:デフォルトの名無しさん
08/06/06 23:08:26
>>443
for(i=0; i<25; i++) {
j = rand() % (i + 1);
a[i] = a[j];
a[j] = i + 1;
}
こうやるとムダなチェックが必要なくなるよ

445:デフォルトの名無しさん
08/06/07 00:45:33
URLリンク(ytteter.so.land.to)

446:デフォルトの名無しさん
08/06/07 02:50:52
>>444
ぱっと見では、なんでうまくいくのか分からなかったけど面白い方法だ

447:デフォルトの名無しさん
08/06/07 03:23:54
わからん

448:デフォルトの名無しさん
08/06/07 03:49:22
確かに重複は回避できるけどシャッフルの度合いとしてはどうなんだろう……
前方にかたよる気がするが

449:デフォルトの名無しさん
08/06/07 04:56:54
シャッフルの度合いw
前方にかたよるw

450:デフォルトの名無しさん
08/06/07 08:03:17
もっといい擬似乱数がほしければメルセンヌ・ツイスターでも使えばいいよ。


451:デフォルトの名無しさん
08/06/07 09:00:24
>>448
くじ引きは最初と中間と最後のどこで引くのが有利だと思う?

452:デフォルトの名無しさん
08/06/07 09:08:43
>>451
商店街のクジ引きなら最後のほうw

453:デフォルトの名無しさん
08/06/07 09:12:39
>>452
当たりが1つで残りn個全部ハズレのクジとした場合、

1)引いたクジを戻す場合は常に確率は一緒
2)引いたクジを戻さない場合はそのときによる。

2)は最初に引く人はかなり確率は低いけど当たりも引ける。
後に引く人は当たりを引く確率は上がるが、最初に当たりを引かれると残りは
ハズレのみになる・・・・・

454:デフォルトの名無しさん
08/06/07 09:26:24
>>453
マジで言ってる?
2)の場合
1回目は 1/n
2回目は (n-1)/n*1/(n-1) = 1/n

最初から最後まで確率は一定だよ。


455:デフォルトの名無しさん
08/06/07 10:33:49
たぶん>>452
商店街とかだと当たりを前半に出すわけにはいかないから、
後半にしか入ってないことをいってるんだと思うぜwww

456:デフォルトの名無しさん
08/06/07 13:25:48
>>444のやり方はこのスレや宿題スレなんかではよく出る中身がある配列のシャッフル
for(i=0; i<N; i++) {
j = rand() % (i+1);
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
と同じ理屈だろ。
これが偏ってるとか思うヤツはセンスないな。

>>450
擬似乱数の精度の話なんかしてない

457:デフォルトの名無しさん
08/06/07 13:30:52
>>454
それは違うな。
あらかじめ引く順番が決められてるなら(2)でも(1)と同じ確率になるが、
自分でいつ籤を引くか決められるなら、(1)とは異なった確率にできる。

たとえば当たり籤が一本しかなかったとして、
当籤が出るまでは誰かが籤を引くたびに当たり確率が高くなっていくが、
当たりが出た途端に当たり確率は0になる。

458:デフォルトの名無しさん
08/06/07 13:31:42
数学的な話か実際の話かの差だから論じても意味が無いと思うけど

459:デフォルトの名無しさん
08/06/07 13:53:49
>>456
マジレスすると、センスないのはお前だ。それは偏る。

<Proof>
N=3とすると、置換の可能性は3^2=27。
一方、3つの要素の並べ方は3!=6。
27/6は整数ではない。故に、偏る。q.e.d.

実際に列[0,1,2]に対して、6万回の試行をしてみると、
[0,1,2]:9063
[0,2,1]:10843
[1,0,2]:11236
[1,2,0]:11121
[2,0,1]:8719
[2,1,0]:9018
この程度のばらつきが出る。

数学的に考えれば、9000前後の数字が出ている列は、
それぞれ並べ替え方27のうち4を占めていて、
11000前後のはそれぞれ27のうち5を占めている。

正確にシャッフルしたければ、並べ替え方が6!のKnuthシャッフルを使うべし。

460:デフォルトの名無しさん
08/06/07 13:56:32
>>459
j = rand() % N;
じゃなくて
j = rand() % (i+1);
になってるんだよ

461:デフォルトの名無しさん
08/06/07 13:57:15
>>458
数学的には、確率を考えているか条件つき確率を考えてるかの違い。
数学vs実際の違いじゃないぞ。

462:デフォルトの名無しさん
08/06/07 14:01:54
暗号化に関する質問です

char str[] = hairetu //暗号化する文字列
int j = 0; //暗号化する文字列の現在位置

strとjが上記の場合

while(*(str+j) != ’\0’)

このwhileの条件ってどういう意味ですか
なぜ文字列に位置を示す数を加算できるのですか??

463:デフォルトの名無しさん
08/06/07 14:04:08
それのどこに暗号化が関係してるの?

464:デフォルトの名無しさん
08/06/07 14:07:01
暗号化のところで出てきたので暗号化特有の構文かと思ったわけです

465:デフォルトの名無しさん
08/06/07 14:07:19
>>459
恥ずかしいヤツw

466:デフォルトの名無しさん
08/06/07 14:08:02
>>462
配列はその先頭の要素を指すポインタになるから
char str[] = ... ;
char *p = str;
while (*(p + j) != '\0')
と書くのと同じ

467:デフォルトの名無しさん
08/06/07 14:09:37
>>462
>char str[] = hairetu
本当にこうか?

468:デフォルトの名無しさん
08/06/07 14:11:04
すみません間違いましてあ
char str[] = ”hairetu” //暗号化する文字列

微妙に間違いました

469:デフォルトの名無しさん
08/06/07 14:13:28
>>466
最初の
char str[] 
の先が文字化けしてるみたいです…

470:デフォルトの名無しさん
08/06/07 14:17:59
*p = str でpの中身がstrのアドレスになって
*(p+j)によってstrの先頭アドレスにjを足したアドレス格納されてる数値を示しているということでしょうか?

471:デフォルトの名無しさん
08/06/07 14:26:49
>>470
だいたいそんな感じ
p はわかりやすく入れてみただけで・・・ p を介さず直接 *(str + j) と書いても同じこと

472:デフォルトの名無しさん
08/06/07 14:29:31
*(str + j) は str[j] と同じ
char str[] = "hairetu"; は char str[] = {'h','a','i','r','e','t','u','\0'} と同じ

文字列が終端になる(str[j]=='\0')まで処理を繰り返す

473:デフォルトの名無しさん
08/06/07 14:39:04
ということは
char key[128] = "abc"  //暗号キー

としたとき

*(str+j) + key[i++]

とすると、これはどういうことですか?

474:デフォルトの名無しさん
08/06/07 14:41:22
>>473
*(str+j)

key[i++]
を足している

何が疑問??

475:デフォルトの名無しさん
08/06/07 14:41:42
それ正確に写してる?

476:デフォルトの名無しさん
08/06/07 15:00:48
正確に写してます…

例えば*(str+1)はeですよね?
それに対してkey[i++]はa,b,cのうちのどれかだと思うんですけど
それなら文字と文字を加算するってどういうことですか?

477:デフォルトの名無しさん
08/06/07 15:04:12
eでは無くhairetuのaですた

478:デフォルトの名無しさん
08/06/07 15:06:35
文字も数値として扱われてるから加算しても問題ない

479:デフォルトの名無しさん
08/06/07 15:08:22
そうでした…
だいぶん前に習ったので忘れてました。。
ありがとうございました…

480:デフォルトの名無しさん
08/06/07 15:09:37
度々すみません
文字を数値で扱う場合は変数をintにする必要はないのですか?

481:デフォルトの名無しさん
08/06/07 15:14:57
char だって整数型だ

482:デフォルトの名無しさん
08/06/07 15:23:35
解決しました
ありがとうございましあ!

483:429
08/06/07 16:48:15
>>435-442
遅くなりまして、すみません。長いですがソース↓です。
void hoge(char gyou[512], char *s1, char *s2, char *s3)
{
int cnt;  /* ,の数 */
char *tp;  /* 区切り文字へのポインタ */

cnt = 0;
memset( s1, 0x00, sizeof(s1) );
memset( s2, 0x00, sizeof(s2) );
memset( s3, 0x00, sizeof(s3) );

  tp = strtok( gyou, "," );
  while( tp != NULL ){
    tp = strtok( NULL, "," );
    if ( tp != NULL && cnt == 2 ){
      strcpy( s1, tp );
      printf("hogeの中のs1の値:%s",s1);
    }else if( tp != NULL && cnt == 3 ){
      strcpy( s2, tp );
      printf("hogeの中のs2の値:%s",s2);
    }else if( tp != NULL && cnt == 5 ){
      strcpy( s3, tp );
      printf("hogeの中のs3の値:%s",s3);
    }
    cnt++;
  }
}

484:デフォルトの名無しさん
08/06/07 16:55:31
>>459
スレリンク(tech板:226番)
はダメですか?N-BASICの昔からよく目にするからくりですが。

485:429
08/06/07 17:01:37
void main()
{
char s1[18];
char s2[3];
char s3[21];
FILE *fp;
char gyou[512]; /* 一行のデータ */

memset( s1, 0x00, sizeof(s1) );
memset( s2, 0x00, sizeof(s2) );
memset( s3, 0x00, sizeof(s3) );

fp = fopen(fullFileName, "r")
while( fgets(gyou, sizeof(gyou), fp) != NULL ){
  hoge(gyou, s1, s2, s3);
  printf("hoge直後のs1の値:%s",s1);
  printf("hoge直後のs2の値:%s",s2);
  printf("hoge直後のs3の値:%s",s3);
  }
}

で、中のファイルというのが、

'00099','あああ','123:サンプル','んんん','','2007/03/01','','',,
'タイトル1','タイトル2','タイトル3','タイトル4','タイトル5'
'00099','00001','1234123412341234',3000,'','','2008/03/31','2008/04/02 11:20:56','4','えええ'

とこんな感じに項目数も、中の文字数もまちまち。
で、たいてい、s1とs3が一文字分ズレてたり、化けてたりします。
一定の規則にしたがって並んだ行だけ処理したいんですが、項目を
入れる文字配列を、s1[]とかにすればいいんでしょうか?ひょっとして・・・

486:デフォルトの名無しさん
08/06/07 17:04:55
>>484
ランダムシャッフルは >>456 が偏りも無く最も高速。
それでもう話はついてるのでもういいよ。

487:デフォルトの名無しさん
08/06/07 17:08:37
恥ずかしながら質問させてください・・・
#include <stdio.h>
int main(void){
int i;
int goukei, tensu[10];
int max = 0;
int min = 999;

printf("入力された点数の最高点、最低点、平均点を出力するプログラムです。\n");
puts("点数を入力してください。");

for(i = 0; i < 10; i++){
scanf("%d", &tensu[i]);
goukei += tensu[i];

if(tensu > max){
max = tensu[i];
}
else if(tensu < min){
min = tensu[i];
}
}
printf("最高点数は%d、最低点数は%d、平均は%dです。", max, min, goukei/10);
}

このような感じで、最高点数と最低点数、平均点を出力するプログラムなのですが、
.\1.cpp(18) : error C2446: '>' : 'int' 型から 'int *' 型への変換ができません。
整数型からポインタ型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。
.\1.cpp(18) : error C2040: '>' : 'int [10]' は 'int' と間接操作のレベルが異なります。
とエラーがでてしまいます。配列を使わなければコンパイルできるのですが・・エラーの文章を読んでもどうしてなのかがわかりません・・・
どうかご教授くださいです・・・


488:デフォルトの名無しさん
08/06/07 17:10:44
やばいわかりましたすみません・・・ifの中身がおかしかったのか・・・回線切手しに増す

489:デフォルトの名無しさん
08/06/07 17:48:15
>>487
if(tensu > max){
else if(tensu < min){
このtensuってtensu[i]の間違いじゃないの?

490:デフォルトの名無しさん
08/06/07 17:49:18
俺も回線切ろう・・・

491:デフォルトの名無しさん
08/06/07 20:36:08
>>487
@goukeiは初期化されていない。
Ascanf関数でのアドレス指定は不要。
Bmaxとminの使い方が意味不明。特に、最大値・最小値アルゴリズム。
C存在しない配列にアクセスしている。

492:デフォルトの名無しさん
08/06/07 21:45:07
>>485
hoge() は配列 gyou に格納されている元になる文字列から2番目、3番目、5番目のトークンを切り出し、
s1 、s2 、s3 の指している先へコピーする。そこまではいい。問題は、その指している先の大きさが足りていないことにある。

この場合コピーする先は main() で宣言された s1[18] 、s2[3] 、s3[21] である。これらはメモリ上に連続して配置される。
そしてたぶん s2 に3番目のトークンをコピーしたときに、s2 の範囲を踏み越えて s3 にまで書き込んでしまった。
このとき hoge() の中で s2 を表示したときには正しくトークンが書き出される。しかし次に s3 に5番目のトークンが書き込まれる。
ここで、s3 の中にある、s2 から領域を踏み越えて書き込まれた文字列のシッポを塗りつぶしてしまった。
そうなると、全部の処理が収まって main() に戻ってきてから s1 、s2 、s3 を表示させると、当然トークンは壊れている。

文字列をコピーするときは、コピーする先の領域の大きさが十分かどうかが常に問題になる。
特に strtok() では、トークンの長さがどれだけなのか事前に予測しがたいために、さらに難しくなる。
万全に行うには、strtok() の戻り値を一旦保存した上で strlen() でトークンの長さを調べ、
必要な大きさの領域を malloc() などで割り付けて、そこにトークンをコピーする。もちろん使い終わったら free() する。
もし所定の大きさを越えたぶんは捨ててしまってもいいとするのなら、
strncpy() か strncat() か sprintf() を使って領域に入るぶんだけをコピーする。

もっとも、切り出したトークンに特段手を加えないなら、そもそも配列にコピーする必要もないかもしれない。
この場合は、単にトークンの先頭を示すポインタの値を記憶しておけばよい。
strtok() によって切り出される各トークンの本体は strtok() の中にあるのではなく、
最初の strtok() の呼び出しで第一引数に指定したポインタの指し示す先、
つまりトークンを切り出す元になる文字列( strtok() によって加工される)の中にあるからである。
ただし、そうやって切り出した一群のポインタの値を関数の外に持ち出すには、
ポインタのポインタ(ポインタの配列)を使う必要があることに注意すること。

493:デフォルトの名無しさん
08/06/07 21:50:30
追加。

memset( s1, 0x00, sizeof(s1) );
memset( s2, 0x00, sizeof(s2) );
memset( s3, 0x00, sizeof(s3) );

hoge() 内にある上のコードは、きっと君が考えているだろう作業をしてくれない。
なぜならここでの s1 、s2 、s3 は、配列ではなくポインタだからである。sizeof(s?) はポインタのサイズを返す。

厳密に言えば、むしろこの処理は不要である。main() にある同様のコードも不要である。
strcpy() は、それが正しく行われるかぎり、必ずコピーした文字列の末尾にヌル文字を付加する。
あらかじめ領域を 0x00 でクリアしておく必要はない。

494:デフォルトの名無しさん
08/06/07 22:03:20
こういうmemset()で0で埋めるテクニック(?)って、使ってるやつはどこで覚えるんだろうな。
職場とか、ヘンなサイトとか?


495:デフォルトの名無しさん
08/06/07 22:14:25
>>494
かつて、今はもう時代遅れとなった「固定長の文字列」が使われていたことがあった。
これは、16バイトとか32バイトとかの固定長のフィールドに文字列を書き込んだもので、
それぞれの文字列の長さは最大でもそのフィールドの大きさにしかならないと決まっていた。
そして、フィールドの長さより短いときには、残りをヌル文字が埋めていた。
だから、フィールドに文字列をコピーするときは、あらかじめフィールドを全部ヌル文字で埋めてから、
フィールドの先頭から文字を入れていって、もう文字がなくなったらそこでやめるだけで済んだ。

この仕様の名残がライブラリ関数 strncpy() である。この関数は指定された長さまで文字をコピーし、
文字列の長さが足りないときにだけ、残りをヌル文字で埋める、という一風変わった動作をするが、
これがまさに上で紹介した固定長の文字列を扱うために最適な仕様であった。

そして今でも、そういう古い習慣を引きずってコードを書いているプログラマや、
そういうプログラマに教わったために意味も知らず古い習慣に従っているプログラマがいる。
既に述べたが、今となっては時代遅れであり、やがて消えていくだろう。
もっともそのときにC自体が残っているかどうかは、誰にもわからない。

496:デフォルトの名無しさん
08/06/07 22:16:17
>>494
あとでメモリーダンプをするときは領域をmemset()しておくといい
ぶっ壊したところが一目瞭然
それ以外では?だな


497:デフォルトの名無しさん
08/06/07 22:36:01
>>495
それは意味のあるmemsetの使い方

498:デフォルトの名無しさん
08/06/07 22:38:13
>>496
それやるなら、VCのデバッグモードみたいに、フフフフ・・・で埋めるとかだな。
0で埋めるのはうまくない。

499:デフォルトの名無しさん
08/06/07 22:38:16
>>497
意味がないとは言っていない。意味を知らない人間も多い時代遅れな使い方だというだけである。

500:デフォルトの名無しさん
08/06/07 22:39:27
>>498
なんか福田の含み笑いみたいだなフフフフってw

501:デフォルトの名無しさん
08/06/07 22:40:33
>>495
へぇー勉強になるなー

502:デフォルトの名無しさん
08/06/07 22:44:18
>>484
方向が逆なだけで456と理屈は同じ

503:デフォルトの名無しさん
08/06/07 22:45:59
フフフフフフフ は 0xCC で int 3 だから
万が一そこに IP が飛んだらブレークされる

504:デフォルトの名無しさん
08/06/07 23:14:14
バグのあるコードを呼び出したり、バグのあるコードから呼ばれたりするような、開発現場の
コードでは、とにかく使用するローカル変数は
memsetでクリアしておかないと、何が起こるかわからないし、下手すりゃ責任取らされる
ハメになるという職業上の経験から、
何はともわれ最初にmemsetの因習が生まれたモヨウ

505:デフォルトの名無しさん
08/06/07 23:17:19
そういや行く先々で何重にもmemsetされてる変数を見たことあるな。

506:デフォルトの名無しさん
08/06/07 23:21:24
>>504
そもそも、memset()でクリアしてもバグ対策にならんだろ。

507:デフォルトの名無しさん
08/06/07 23:22:22
Windowsの構造体をゼロクリアする慣習が広まったんじゃないかな・・・

508:デフォルトの名無しさん
08/06/07 23:22:41
バグが表面化しにくくなるだけな気がするな

509:デフォルトの名無しさん
08/06/07 23:23:13
変数はとにかく宣言時に初期化しておきましょうみたいな慣習だろ

510:デフォルトの名無しさん
08/06/07 23:23:22
>506
もちろん根本的な解決ではないけど、なる場合もある
特に文字列の末尾をちゃんと処理しないアホな関数を呼ぶときには

511:デフォルトの名無しさん
08/06/07 23:23:32
>>507
バークレーソケットのとある構造体もゼロクリアしないといけなかったような...。

512:デフォルトの名無しさん
08/06/07 23:24:03
>>507
unixの職場でも、文字列のmemsetクリアが有効だって信じられてる所を見たことあるよ。

513:デフォルトの名無しさん
08/06/07 23:27:09
コボラーの先輩が使ってたからコボルの流儀かと思ってた

514:デフォルトの名無しさん
08/06/07 23:28:09
mallocで構造体用のメモリ確保した際、
セットする内容が0が多い場合はとりあえず
やちゃえでmemsetは使うけどそれ以外は微妙

515:デフォルトの名無しさん
08/06/07 23:28:58
callocはゼロで埋めるんだっけ

516:デフォルトの名無しさん
08/06/07 23:29:27
そうえいば、malloc()じゃなくて、calloc()を使うべきとかいうやつも見たことあるな。

517:デフォルトの名無しさん
08/06/07 23:31:28
callocだと何か不味いの?

518:デフォルトの名無しさん
08/06/07 23:33:27
#define strncpy(d, s, n) ((d)[0]='\0', strncat(d, s, n))

519:デフォルトの名無しさん
08/06/07 23:34:07
>518
てめえ!!(笑

520:デフォルトの名無しさん
08/06/07 23:38:13
盛り上がっているところ失礼しますが、rewind(stdin)の動作は規格で決められたものでしょうか?
それとも処理系定義とか未規定とか未定義でしょうか?

521:デフォルトの名無しさん
08/06/07 23:42:46
callocなんてあったのには驚き。
でも結局のところ関数の中身はmalloc+memsetなんでしょ。

522:デフォルトの名無しさん
08/06/07 23:48:00
>>520
c faqにstdinをクリアする一般的な方法はないってかかれていたから、rewind(stdin)にも移植性はないんじゃない?

523:デフォルトの名無しさん
08/06/07 23:52:04
rewindってことは入力があった状態に戻したいのか。無理。

524:デフォルトの名無しさん
08/06/07 23:59:52
ungetch()しかないね。標準では。
でもそもそも意味違うし。

525:デフォルトの名無しさん
08/06/08 00:04:02
>>522
やっぱりそうですか
でも引数になるstreamに特に制限はないから未定義ではないと思っていいでしょうか?

>>523
いえ、読んでない文字を全て捨てたいのです

526:デフォルトの名無しさん
08/06/08 00:06:50
VC特有だろflush(stdin); が有効なのは

527:デフォルトの名無しさん
08/06/08 00:09:49
rewind(stdin) ってやったことないから推測だけど、入力にファイルをリダイレクトされていると、
ファイルポインタがファイルの先頭まで戻っちゃうんじゃないの?



528:デフォルトの名無しさん
08/06/08 00:10:58
while((ch=getchar())!='\n'); とかで読み飛ばすのは?

529:デフォルトの名無しさん
08/06/08 00:11:34
C/C++の宿題スレ見てて思ったんだけど、
a == b のような 条件式は成り立った時必ず 1 が返ると思っていいんですか?

530:デフォルトの名無しさん
08/06/08 00:12:18
うん

531:デフォルトの名無しさん
08/06/08 00:12:40
>>529
思ってちゃダメ, 0以外の何かだと思って対処するように

532:デフォルトの名無しさん
08/06/08 00:14:22
プログラミング知識0の状態から
苦しんで覚えるC言語っていうサイトの内容を一通り覚えたんだけど
次何やればいい?

533:デフォルトの名無しさん
08/06/08 00:14:36
>>531
おい嘘書くな

534:デフォルトの名無しさん
08/06/08 00:14:58
>520
標準入力のバッファリングの方法に依存したはず
stdinを読む関数を呼んだときにまるっとバッファリングするシステムなら
意図どおり未読の入力をクリアしてくれる
もちろん入力リダイレクトのことはまったく考慮してないが
わかってて使うぶんにはいいと思う

>531
違う
論理演算の結果は必ず0か1になると規格で決まってる

535:デフォルトの名無しさん
08/06/08 00:17:45
>>529
宿題スレのあれはあんまり誉められた書き方じゃないけどな。
素直にifで分岐してったほうがいい。

536:デフォルトの名無しさん
08/06/08 00:21:58
>>532
たまにそういう疑問が書き込まれるが、
正直そういう疑問が何故起こるのかが分からない。
何か作りたい物があったからプログラム勉強してんじゃないの?
それを作ればいいじゃないの。

537:デフォルトの名無しさん
08/06/08 00:22:52
>>534
ありがとうございました
参考にします

538:デフォルトの名無しさん
08/06/08 00:23:53
>>532
・アルゴリズム系の本を読む
・ゲームでもエディタのようなツールでもなんでもいいけど、なにかひとつまとまったものを作ってみる
 (挫折してもいい)
・どう書く?.orgとか、2chの宿題スレの簡単なやつとか、短時間で組めるやつをたくさん書いてみる

このあたりを同時に。

539:529
08/06/08 00:29:17
条件式の返り値は規格で決まっていたんですね…
これで安心して 条件式 == TRUE という書き方が出来ます
ありがとうございました

540:デフォルトの名無しさん
08/06/08 00:29:59
TRUEが1とは限らないけどな

541:デフォルトの名無しさん
08/06/08 00:33:19
そもそもTRUEなんてw

542:デフォルトの名無しさん
08/06/08 00:34:30
TRUE は1だが、
BOOL を返す関数が真の時に1を返すとは限らない。

そもそも、何で条件式と TRUE を比較する必要性があるんだ?
訳が分からん。

543:デフォルトの名無しさん
08/06/08 00:35:07
条件式で判定してるのにさらに比較が必要か?
だったら(((条件式==TRUE)==TRUE)==TRUE))==TRUEとか書けよ

544:529
08/06/08 01:41:59
あんまり虐めないでくれ
たまにif文の中の関数で混乱するから書いてみただけです

545:デフォルトの名無しさん
08/06/08 02:02:11
関数の戻り値ならなおさら TRUE と比較してはいけない。
理由は >>542

546:デフォルトの名無しさん
08/06/08 02:07:28
成功すると0を返す関数も多いしな

547:デフォルトの名無しさん
08/06/08 02:22:40
それは別問題。

548:デフォルトの名無しさん
08/06/08 02:24:14
関数の戻り値は関数の仕様だ
条件式の結果云々はコンパイラの問題だろ


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5029日前に更新/203 KB
担当:undef