C言語なら俺に聞け(入門篇) Part 29at TECH
C言語なら俺に聞け(入門篇) Part 29 - 暇つぶし2ch369:デフォルトの名無しさん
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は初期化されていない。
②scanf関数でのアドレス指定は不要。
③maxとminの使い方が意味不明。特に、最大値・最小値アルゴリズム。
④存在しない配列にアクセスしている。

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
関数の戻り値は関数の仕様だ
条件式の結果云々はコンパイラの問題だろ

549:デフォルトの名無しさん
08/06/08 02:27:32
コンパイラw

550:デフォルトの名無しさん
08/06/08 02:56:00
条件式の結果は規格で決められています

551:デフォルトの名無しさん
08/06/08 02:56:38
C99から導入された_Bool型って使ってる人いるのん?

552:デフォルトの名無しさん
08/06/08 03:01:30
C99って使ってる人いるのん?

553:デフォルトの名無しさん
08/06/08 03:09:52
まぁ関数が返す値は真偽を意味しているとは限らんしな。
真偽は比較、評価などで0か1かで、関数は0か0以外という概念もあるしね。

554:デフォルトの名無しさん
08/06/08 08:03:28
C言語で書かれたScket(linux)のプログラムコードで
#define DB(x) x
という、マクロがあり
DB(fprintf(stderr,"InitSocket\n"));
このような、使われ方をしていました
想像するに、DBにfprintf(stderr,"InitSocket\n")とい引数を持たせているのですが
このような使い方をすることで何かメリットがあるのですか?意味が分かりません
目的と、どのように何がどのように作用するのか教えてくださいエロイヒト

555:デフォルトの名無しさん
08/06/08 08:04:42
スマン
マチガエマスタ
C言語で書かれたプログラムコードで
#define DB(x) x
という、マクロがあり
DB(fprintf(stderr,"InitSocket\n"));
このような、使われ方をしていました
想像するに、DBにfprintf(stderr,"InitSocket\n")とい引数を持たせているのですが
このような使い方をすることで何かメリットがあるのですか?意味が分かりません
目的と、どのように何がどのように作用するのか教えてくださいエロイヒト

556:デフォルトの名無しさん
08/06/08 08:05:15
>>554
#define DB(x)
とすると
DB(fprintf(stderr,"InitSocket\n"));

;
になります

557:デフォルトの名無しさん
08/06/08 08:16:33
デバッグ文のつもりだと想像される。

558:デフォルトの名無しさん
08/06/08 08:20:39
>>556
う~んよく分かりません、
fprintf関数は書式付の出力ですよね、単にInitSocket\nという文字列をstderrに対して、出力してるだけですよね?
fprintf(stderr,"InitSocket\n")だけではいけないんでしょうか?
kuwasikuオナガイシマス

559:デフォルトの名無しさん
08/06/08 08:23:34
>>556
元ネタはここです↓
URLリンク(www.ncad.co.jp)

560:デフォルトの名無しさん
08/06/08 08:24:33
またまちがえた
>>555です
>>556
>>557
thx
元ネタはここです↓
URLリンク(www.ncad.co.jp)

561:デフォルトの名無しさん
08/06/08 08:47:49
>>560
次のコードの
#define DEBUG
の行の有無でコンパイルし直して実行してみれば?

#include<stdio.h>

#define DEBUG // 普通はコンパイルオプションで指定することが多い

#ifdef DEBUG
#define DB(x) x
#else
#define DB(x)
#endif

int main(void){
DB(fprintf(stderr,"InitSocket\n"));
return 0;
}

562:デフォルトの名無しさん
08/06/08 09:06:08
>>561
>>555です
あ!そっか、何となく分かったっぽいです
コンパイルオプションスイッチの有無で、出力する、しないを設定するのですね

563:デフォルトの名無しさん
08/06/08 11:28:33
DBはわかりにくいな
DEBUGにすればいいものを

564:デフォルトの名無しさん
08/06/08 12:21:55
>>553
概念つーか、関数作ったやつがどう仕様をきめるかって問題だろ。

仕様が「0かそれ以外」だったら、== TRUE で比較は間違ってるってだけの話だろ。


565:デフォルトの名無しさん
08/06/08 12:23:50
何時間前のレスに反応してんだよw

566:デフォルトの名無しさん
08/06/08 12:25:38
まあ、お前みたいに2chに常駐してるわけじゃないからな。

567:デフォルトの名無しさん
08/06/08 12:26:38
>>565
ム板で何言ってるんだ

568:デフォルトの名無しさん
08/06/08 14:02:44
>>564が必死な件について
自分で作ったものは自分で決める、そりゃそうだが
標準ライブラリをもっとよく見てみることをお勧めする。
あと >>546 みたいな意見が出たが、成功すると
0以外の値を返すものも普通にあるぞ。

569:デフォルトの名無しさん
08/06/08 14:11:35
おまいら、標準ヘッダーとか読んだりするのか?

570:デフォルトの名無しさん
08/06/08 14:23:05
is系関数なんかは0以外の値返す実装な場合があるな。

571:デフォルトの名無しさん
08/06/08 14:28:12
関数によって違うから一概に言えないってことは、529以外みんなわかってるだろ

572:デフォルトの名無しさん
08/06/08 14:40:36
>>568
いやだから、仕様を読んで、そのとおりに使えばいいんじゃん。
仕様もよくわからん関数ならともかく、標準関数とか特に。

573:デフォルトの名無しさん
08/06/08 14:46:43
あと、XX_TRUE, XX_FALSE みたいな、その関数やライブラリ独自のあやしい定義があって、
仕様が、それを返すってことになってたら、 func() == XX_TRUE みたいに比較したほうが安全って
意見も見たことはある。


574:デフォルトの名無しさん
08/06/08 14:49:49
戻り値が複数のエラーコードを持つ場合はともかく、成功か失敗かしかないならシンボル化する意味ないんじゃないですか
って言ったら1とか0とかなんてそんなのわかんないだろ!人間はコンピューターじゃないんだよ!ってコボラーの先輩がキレた

575:デフォルトの名無しさん
08/06/08 15:00:48
>>572
真偽値を返す関数の戻り値はほぼ必ず0か非0を返すとドキュメントに書かれている。

576:デフォルトの名無しさん
08/06/08 15:01:58
えらく自信満々だな

577:デフォルトの名無しさん
08/06/08 15:04:45
実際そうなんだから仕方が無い。
C++ なら bool 返す関数は true/false しか返さない(返せない)がな。

578:デフォルトの名無しさん
08/06/08 15:08:16
>>575
そこは論点になってませんよ。

579:質問です
08/06/08 15:16:47
C言語でシリアル通信をするプログラムを作りたいのですが、難しいです。。

<内容>
自分のPCにRS232Cを2つ繋いで(クロスケーブル)何でもいいので、通信させたいのです。
win32APIを使うといいらしいのですが、プログラムを作った後の動かし方等もわかりません。。
開発ツール:VisualC++2008

どなたか、答えられる方いますか??

580:デフォルトの名無しさん
08/06/08 15:19:01
可読性のためにTRUEと比較したいってことだから、TRUEが1だと仮定すれば
成功したら0を返す関数の場合 if(!func()==TRUE)
非0を返す関数の場合 if(!!func()==TRUE)って書けばおkじゃね?w

581:デフォルトの名無しさん
08/06/08 15:22:16
手段と目的が入れ替わっちゃった感が

582:デフォルトの名無しさん
08/06/08 15:23:31
>>579
「rs232c windows」でググったら、最初にこのページが出てきたけど、これじゃいかんの?
URLリンク(members.jcom.home.ne.jp)

583:デフォルトの名無しさん
08/06/08 15:23:41
MFCだと戻り値が0か非0と書いてること多いから、常にいf文ではFALSEと比較してるな
基本的にTRUEは使わない

584:デフォルトの名無しさん
08/06/08 15:25:51
>>580
if には基本的に真偽値を渡すんだから
真偽値を返す関数はそのまま書けばいいだけ。
別にそれで可読性は落ちない。

585:デフォルトの名無しさん
08/06/08 15:26:30
== FALSE ならともかく != FALSE とか二重否定で余計分かりにくいと思うんだが。

586:質問です
08/06/08 15:32:25
>>582さん

ありがとうございます。。。
ここを参考にやってみます><

587:デフォルトの名無しさん
08/06/08 15:33:35
それは比較対象に重点を置きすぎてるからじゃ
そりゃあTRUEやFALSEが混在してる中でなら、分かりにくいとは思うが

588:デフォルトの名無しさん
08/06/08 15:36:55
まあ、比較で、bool値のリテラルは使わないのが普通だよな。

589:デフォルトの名無しさん
08/06/08 20:51:59
そもそもこの話題の発端の発言は、比較の結果がTRUEのときそれを整数の1だと扱おうと
しているようだから、そんなのは規格で正しくても、規約では絶対認めない。


590:デフォルトの名無しさん
08/06/08 20:56:45
絶対は言いすぎだが普通は認めないだろうな

591:デフォルトの名無しさん
08/06/08 22:32:00
・比較演算や論理演算の結果は0か1
・真偽は0以外か0

単純にコレだけのことじゃん。

592:デフォルトの名無しさん
08/06/08 22:55:17
すいませ、うやむやなので、聞かせてください
等価演算子?の質問なんですが
例えばfor文で、 i <= 10 ってのは10までいったら終わるって事ですよね?
if文だと、 i <= 10 、10以下の条件が満たされると思っていいのでしょうか?

593:デフォルトの名無しさん
08/06/08 22:58:56
日本語でお願いします

594:デフォルトの名無しさん
08/06/08 23:00:42
>>592
> 例えばfor文で、 i <= 10 ってのは10までいったら終わるって事ですよね?

微妙に違う。「iが10以下の場合くりかえし」つまり「iが11になったら
終り(i++の場合)」

> if文だと、 i <= 10 、10以下の条件が満たされると思っていいのでしょうか?

文脈がわからん。何を聞いているんだろう?



595:デフォルトの名無しさん
08/06/08 23:00:44
意味が分からん
if文でもfor文でも
i<=10 が成立している場合実行、だ

596:デフォルトの名無しさん
08/06/08 23:01:42
>>593 読むのもレスするのも日本人でおねがいします

597:デフォルトの名無しさん
08/06/08 23:02:09
こういうの、以上や未満を正しい意味で使ってないやつ多いから、ややこしい

598:デフォルトの名無しさん
08/06/08 23:03:43
というか正しい日本語でも正確にきまってないからどうしようもないよw

599:デフォルトの名無しさん
08/06/08 23:04:24
だいなりしょうなり

600:デフォルトの名無しさん
08/06/08 23:06:43
もっとわかりやすく質問しろ



601:デフォルトの名無しさん
08/06/08 23:06:52
for( i=1 ; i <10 ; i++){
printf(" * ")
って式だと,
* は11個でるんでしょうか? それとも10個で終わるんでしょうか?


602:デフォルトの名無しさん
08/06/08 23:07:28
>>601
試せよ
36個だよ

603:デフォルトの名無しさん
08/06/08 23:07:51
>>601
9コだよ。

604:デフォルトの名無しさん
08/06/08 23:08:00
9個だ

605:デフォルトの名無しさん
08/06/08 23:10:00
>>601
それだけだと分からない

606:デフォルトの名無しさん
08/06/08 23:10:01
>>601
i = 1;
if (i < 10) printf
i++
if (i < 10) printf
i++
if (i < 10) printf
i++
if (i < 10) printf
i++
if (i < 10) printf
i++
if (i < 10) printf
i++

これで考えろ

607:デフォルトの名無しさん
08/06/08 23:22:53
試してみましたが10個でした・・・
最初は ++しないで、下に下がるんですよね?

608:デフォルトの名無しさん
08/06/08 23:23:35
なん・・・だと・・・

609:デフォルトの名無しさん
08/06/08 23:27:13
じゃあもう10じゃなくて3くらいで数えてみろよ

610:デフォルトの名無しさん
08/06/08 23:29:21
>>607
もう一度良く数えてみるんだ。
printf("%0d",i);してみろ


611:デフォルトの名無しさん
08/06/08 23:32:58
>>607
もしかして
for(i = 1; i < 10; i++)
じゃなくて
for(i = 1; i <= 10; i++)
とかやってないだろうな・・・

612:デフォルトの名無しさん
08/06/08 23:34:02
>>592
for 構文は、最初に第1式を評価し、第2式の値が真である間、
続く一文またはブロックの処理と第3式の評価を繰り返す。
たとえば for(i=1; i<=10; i++) は、最初に i を 1 に初期化し、
i が 10 以下である間、続く文かブロックを実行してから i を 1 ずつ増やす。
これは結果として同じ処理が 10 回繰り返されることを意味する。

どうしても処理の流れが想像できないときは、まず文房具を用意して絵を描くこと。

613:デフォルトの名無しさん
08/06/08 23:34:20
ループする回数すらよく分からんならforなんざ使わず
全部 while で書け

614:デフォルトの名無しさん
08/06/08 23:34:32
計算順序は>>606のとおりだ

615:デフォルトの名無しさん
08/06/08 23:40:44
<= は++せず1回下に戻って、
< はそのまま最初から++するんですか?

616:デフォルトの名無しさん
08/06/08 23:41:26
>>615
日本語でいうと
< は未満
<=は以下

617:デフォルトの名無しさん
08/06/08 23:46:33
まず演算子の意味から勉強しなおせ

618:デフォルトの名無しさん
08/06/08 23:46:55
これはひどい

619:デフォルトの名無しさん
08/06/08 23:47:28
どう考えてもforうんぬん以前の問題です
本当にありがとうございました

620:デフォルトの名無しさん
08/06/08 23:52:40
何となくわかりました
すっきりしましたのでありがとうございます

621:デフォルトの名無しさん
08/06/08 23:56:04
で、何回だったのかい

622:デフォルトの名無しさん
08/06/08 23:56:59
>>616が言ってるのは>>601のケースについてだろ?
あってるんじゃね?日本語にした場合の説明は。

623:デフォルトの名無しさん
08/06/08 23:57:19
ちなみに
for ( A; B; C)



A
while(B) {

C
}
は等価

624:デフォルトの名無しさん
08/06/08 23:59:17
>>622
流れが読めてないね

625:デフォルトの名無しさん
08/06/09 00:10:40
>>492
ご丁寧に大変どうもありがとうございます!
なるほど。s2やらをコピーした直後に表示しているから、壊れて出ないけど、
その後、s3がs2の領域を塗りつぶしちゃってるんですね!!
ポインタ苦手すぎて、メモリ操作とか難しすぎて涙が出ます。。
memsetは不要なんですね。よく分からないけど、みんなやってるので、やってただけなんです。
ポインタだから不要ってことですね。大変助かります。ありがとうございます。

strncpy()という関数を教えてくださり、ありがとうございます!
決まった文字数以外は切り捨ててしまって構わないので、これで確実にできると思います。
大変ありがとうございます!!
Cド初心者で、ポインタ操作が苦手なんですが、トークンの先頭を示すポインタの値を
記憶しておく場合、main()に戻ったときに、その値は消えてしまったりしないんでしょうか??
変数の範囲とポインタ関係とかもよくわかってません・・泣

> そうやって切り出した一群のポインタの値を関数の外に持ち出すには、
> ポインタのポインタ(ポインタの配列)を使う必要があることに注意すること。

これが切ないほどによく分からないので、やはり、配列コピーで、
文字列はここにある!と、安心した状態でやりたいと思います。

大変に助かりました!感謝感激!助言くださった皆様も、どうもありがとうございました!
お返事遅くなり、すみませんでした!!m(_ _)m

626:デフォルトの名無しさん
08/06/09 00:12:09
for(i = 1; i < 10; i++)printf("%d ",i);

1 2 3 4 5 6 7 8 9  :9回

for(i = 1; i <= 10; i++)printf("%d ",i);

1 2 3 4 5 6 7 8 9 10 :10回

for(i = 0; i < 10; i++)printf("%d ",i);

0 1 2 3 4 5 6 7 8 9 :10回

for(i = 0; i <= 10; i++)printf("%d ",i);

0 1 2 3 4 5 6 7 8 9 10 :11回


627:デフォルトの名無しさん
08/06/09 00:15:08
>>625
strncpyはヌル文字つけないことあるから注意しろよ
s1[n]='\0', strncpy(s1, tp, n); みたいに使うんだ

628:デフォルトの名無しさん
08/06/09 00:17:01
>>625
全体的に知識不足っぽいから、本読むといいと思う。

実際プログラム組むのもいいんだけど、知識がないと、どうでもいい所でつまづく。

629:デフォルトの名無しさん
08/06/09 00:28:58
>>627
ありがとうございます!
たとえば5文字の文字列をコピーしたい場合、'\0'の分もとって、
s1[6];
で宣言するんでしょうか?それとも、s1[7]?
>>628
はい、ひたすらに読みまくってみます。ありがとうございます!

630:デフォルトの名無しさん
08/06/09 00:42:50
>629
5文字ならs1[6]でいい
良く使われるのは、

#define LENGTH 15
char str[LENGTH+1];

みたいな手法

631:デフォルトの名無しさん
08/06/09 01:12:52
>>630
ああ、なるほど!
それはよく見かけるけど、+1 はそういう意味だったんですね!
こういうの、本に載ってないですよね!為になります。
ありがとうございます!

632:デフォルトの名無しさん
08/06/09 01:16:54
文字列には'\0'が必要だから文字数+1のサイズが必要ってのは大概の本に載ってると思うけど。

633:デフォルトの名無しさん
08/06/09 01:27:49
i++ と ++i って何が違うの?

論争はやめてね。

634:デフォルトの名無しさん
08/06/09 01:28:57
俺的にはfor文で、変数名iとか付けてほしくないな

635:デフォルトの名無しさん
08/06/09 01:32:40
>>633
それだけを1行に書いたら同じ機能。
if文なんかの中に組み込むと結果が違ってくる。

636:デフォルトの名無しさん
08/06/09 01:35:37
変数名 i はfor文専用
それ以外で使うべきではないし、for文では積極的に使う。

637:デフォルトの名無しさん
08/06/09 01:36:58
>>636
専用と言い切ったらダメだろw
あくまで慣習的に使われてるだけだし

638:デフォルトの名無しさん
08/06/09 01:38:32
>>635

どうかわるの?

639:デフォルトの名無しさん
08/06/09 01:41:33
使いたきゃ使えばいいが、書いた全てのfor文のループカウンタに対して、どのような意味を持っているか説明できないようじゃダメだな
for文といえばiだろ?とか言ってるようじゃ学生レベル

640:デフォルトの名無しさん
08/06/09 01:43:01
i, j, k, と増えていくのは文化でしょ?

641:デフォルトの名無しさん
08/06/09 01:43:32
i回目以上の意味がない場合多いだろw

642:デフォルトの名無しさん
08/06/09 01:44:22
回数以外に意味がないからこそiが多用されてるんだしな

643:デフォルトの名無しさん
08/06/09 01:45:43
回数って何の回数ですか?><

644:デフォルトの名無しさん
08/06/09 01:47:45
ループカウンタはi, ii, iii, iv, v,...

645:デフォルトの名無しさん
08/06/09 01:52:13
もともとはふぉーとらんだっけ?iカウンタ

646:デフォルトの名無しさん
08/06/09 01:53:29
>>638
教科書読め

647:デフォルトの名無しさん
08/06/09 01:58:00
fortranだとI J K L M N あたりが宣言なしで整数だったか
視野に納まる範囲のループカウンタは一文字で十分
広範囲に及ぶならなんか名前を付けたほうがいいかもしれないが、
そうならないように関数を分割するなどの努力をすべきだろう

648:デフォルトの名無しさん
08/06/09 02:01:30
DO文か、懐かしいな。

649:デフォルトの名無しさん
08/06/09 02:03:44
Linuxで作りたいんだけど、
プロジェクトとかって自分のディレクトリに置いてやってけばいいの?
ディレクトリが沢山あってlinuxの正解というか常識がわからん

650:デフォルトの名無しさん
08/06/09 02:13:56
簡単な本は理解した
次に進みたいので何かいい本ある?

651:デフォルトの名無しさん
08/06/09 02:15:41
>>650
推薦図書/必読書のためのスレッド 40
スレリンク(tech板)

652:デフォルトの名無しさん
08/06/09 04:02:21
これを実行して一つ目の数値を入力すると
「問題が発生したためtest.exeを終了します」って出るんですが
何がいけないんでしょうか?

#include <stdio.h>

int main(void)
{
int array[10];
int i;

for(i=0;i<10;i++){
printf("%d番目の数を入力してください:",i+1);
scanf("%d",array[i]);
}

for(i=9;i<0;i--){
printf("%d\n",array[i]);
}

return 0;
}

653:デフォルトの名無しさん
08/06/09 04:07:06
>>652
ヒント:scanfのarray[i]引き数があやすい
scanfのマニュアルあるいは教科書を読み直す

654:デフォルトの名無しさん
08/06/09 04:09:10
>>652
釣りはやめようね

655:デフォルトの名無しさん
08/06/09 04:11:32
>>653
わかりました
「&」ですよね
あとどうでもいいんですけど二つ目のfor文の条件式はi>=0にしないとなんもならないですね
ありがとうございました!
>>654
マジで気づかなかったです
自分の持ってる教本にも
初心者はscanf使う時に&忘れやすいから気をつけてって書いてたんで
これからは忘れずちゃんと&つけたいと思います
簡単すぎる質問でスレ汚したかもしれないです
すいませんでした

656:デフォルトの名無しさん
08/06/09 04:12:15
>>652
scanf("%d",array[i]); > scanf("%d",&array[i]);
なんだかなぁ。

657:デフォルトの名無しさん
08/06/09 04:16:58
コンパイラによってはそれは忠告してくれるようにできるからしとけば?

658:デフォルトの名無しさん
08/06/09 05:48:39
C(hinko)++

659:デフォルトの名無しさん
08/06/09 07:38:27
無料のVC2005使ってデバッカ使ってみれば?

660:デフォルトの名無しさん
08/06/09 11:39:13
入門書にscanfが記載されているのは何でだろう?

661:デフォルトの名無しさん
08/06/09 11:59:02
たぶんこう

定数同士の計算じゃつまらないので何か入力させてその値に対して計算をさせたい
でもまだ文字列の説明はしていない
→ scanf

662:デフォルトの名無しさん
08/06/09 12:01:15
おまじないでおk
#include とか
scanf printf みたいな可変長引数をとる関数とか
気にしてたら何もできない

663:デフォルトの名無しさん
08/06/09 12:07:58
本の構成を変えればいいのに。。。。

664:デフォルトの名無しさん
08/06/09 13:54:00
>>663
無理だろwww
プリプロセス単体の説明からはじめるのかよwwwww

665:デフォルトの名無しさん
08/06/09 14:04:43
別にscanfから初めてもいいと思う
前置きで、あまり使うべきでない関数だと断った上で

666:デフォルトの名無しさん
08/06/09 15:01:00
#include <stdio.h>

int zel(int y, int m , int d) {
if(m<=2) { y--; m+=12; } // 1,2月は前年の13,14月として扱う
return ( y + (y/4) - (y/100) + (y/400) + ((13*m+8)/5) + d) % 7;
}

int main(void)
{
int year,month,cnt;

for (year=2001,cnt=0; year<=2100; year++) {
for (month=1; month<=12; month++) {
if( zel(year,month,13)==5 ) {
cnt++;
}
}
}
printf("%d回\n",cnt);
return 0;
}

このプログラムをmain関数のみで作ることって出来ますか?
if文とfor文ぐらいしか習ってないんですが…

667:デフォルトの名無しさん
08/06/09 15:07:35
出来ます。

668:デフォルトの名無しさん
08/06/09 15:10:12
>>667
すみませんが、教えてもらえませんか??

669:デフォルトの名無しさん
08/06/09 15:27:04
#include <stdio.h>

int main(void)
{
     int year,month,cnt,zelAns,y,m,d;

     for (year=2001,cnt=0; year<=2100; year++) {
          for (month=1; month<=12; month++) {
               y = year;
               m = month;
               d = 13;
               if(m<=2) { y--; m+=12; } // 1,2月は前年の13,14月として扱う
               zelAns = ( y + (y/4) - (y/100) + (y/400) + ((13*m+8)/5) + d) % 7;
               if (zelAns == 5) {
               //if( zel(year,month,13)==5 ) {
                    cnt++;
               }
          }
     }
     printf("%d回\n",cnt);
     return 0;
}

これでOKかな・・・?間違ってたら指摘にょろ

あと2chでインデント維持のためTAB1個を全角スペースx5に変換してるので
コピーする場合はエディタなどで修正必要?

670:デフォルトの名無しさん
08/06/09 15:29:20
>>668

#include <stdio.h>
int main(void) {
int year,month,cnt, y, m;
for (year=y=2001,cnt=0; year<=2100; year++) {
y = year;
for (month=1; month<=12; month++) {
m = month;
if (m <= 2) {
y--;
m+=12;
}
if (((y + (y/4) - (y/100) + (y/400) + ((13*m+8)/5) + 13) % 7) == 5) {
cnt++;
}
}
}
printf("%d回\n",cnt);
return 0;
}

適当なのであってるかしらんよ。
で、これ宿題?

671:デフォルトの名無しさん
08/06/09 15:41:55
>>669 >>670
ありがとうございます。

これ宿題です。

672:デフォルトの名無しさん
08/06/09 15:45:03
>>671

今度から宿題はここで聞くといいよ。

スレリンク(tech板)



673:デフォルトの名無しさん
08/06/09 16:43:53
リナックスの問題で
1+(1+2)+(1+2+3)+(1+2+3+・・・+n)
二重ループを用いて書いてください。
よろしくお願いします

674:デフォルトの名無しさん
08/06/09 16:47:24
宿題は宿題スレへ

675:デフォルトの名無しさん
08/06/09 16:51:56
for(s=0, i=1; i<=n; i++) for(j=1; j<=i; j++) s+=j;

676:デフォルトの名無しさん
08/06/09 16:59:58
++習ってないw

677:デフォルトの名無しさん
08/06/09 17:07:49
すみません教えてください・・・頭から湯気でた
入力文字を5文字制限に制限をして、あふれたら収まるまで警告を出すプログラム
を考えているんですがめちゃくちゃになってしまいました・・・

#include <stdio.h>
int main(void){
char namae[5];
do{
scanf("%s", namae);
if(namae[5] > sizeof(namae)){
printf("文字数オーバーです。もう一度入力してください。");
}
else if(namae[5] < sizeof(namae)){
break;
}
}
while(namae[5] > sizeof(namae));
printf("%d", sizeof(namae));
}

文字数の比較でsizeof()を使ってます・・・上記のコードでやると、
namaeの中身がリセットされずに延々と増えていってしまいどうしたらいいのかわからなくなりました・・・

スマートなやり方はないでしょうか?どうかご教授ください・・

678:デフォルトの名無しさん
08/06/09 17:09:26
printf("%d", sizeof(namae));
↑これ間違えました・・・・さっき実験してたやつです・・・
printf("%s", namae)でした・・・

679:デフォルトの名無しさん
08/06/09 17:18:52
namae[5] < sizeof(namae))
  ↑
そもそも、これが(namae[5])何を指しているのか、良く考えた方がいい

つstrlen()



680:デフォルトの名無しさん
08/06/09 19:42:17
URLリンク(www.geocities.jp)
こういうプログラムを実行したときに
void型はnode型に変更できませんってなるのはなぜでしょうか

681:デフォルトの名無しさん
08/06/09 19:48:35
なんとなくだけど
voidはmallocで確保した際の戻りアドレスで
nodeは構造体

キャストがうまく出来てない?

682:デフォルトの名無しさん
08/06/09 19:59:05
エラーだそうと思ったらそのままコンパイル通ってしまって確認が出来ん

>>681の通りだと
111行目あたりの
new_node = malloc( sizeof( struct node ) );

new_node = (struct node*)malloc( sizeof( struct node ) );
に変えてみるとかどうだろうか

683:デフォルトの名無しさん
08/06/09 20:02:40
>>680
こういう・・・ということは自前で用意した物ってことか?
うまく行かないソースとエラーになる行番号をせめて書いたほうがいいよ。

684:デフォルトの名無しさん
08/06/09 20:18:57
winapiとかdirectxとかそういうの使わないでGUIって作れるもんなの?

685:デフォルトの名無しさん
08/06/09 20:20:13
そういうのってのがどういうのを指してるのかは知らんが
標準Cだけじゃ無理

686:デフォルトの名無しさん
08/06/09 20:26:36
C言語そのものには画面という概念すらないからねぇ

687:デフォルトの名無しさん
08/06/09 20:29:36
一応バックスペースとかラインフィードとかあるけど、
このあたりは画面というよりむしろプリンタを想定している所が大きいんだよな。

688:デフォルトの名無しさん
08/06/09 20:31:19
windowsのような環境は無理だろうな
DOSとかのようなシングルタスクな環境だと
VRAMのアドレスとかわかれば直接アクセスできたりするんだけど。

689:デフォルトの名無しさん
08/06/09 20:34:23
PC-98はDOS画面に壁紙貼ったりできたなぁ‥‥なつかしい。

690:デフォルトの名無しさん
08/06/09 20:37:05
CでOSから書けばいいじゃん。

691:デフォルトの名無しさん
08/06/09 20:43:40
>>690
一からOS作ってもwindowsのようなGUI形態とる場合は
結局同じようなAPIの道を歩むと思うので無駄。
素直にAPIたたけ。
それがいやなら、DOSでやれってことだな。
でもDOSでやるとなると今度はもっと大変なんだけどな。

692:680
08/06/09 20:49:49
>>681 >>682 >>683

実行時のエラーです、行数は同じです,お願いします

> C:\borland\bcc55\Bin\make.exe -fDebug\test.mak -B TARGET
MAKE Version 5.2 Copyright (c) 1987, 2000 Borland
bcc32 -WC -3 -Od -w- -AT -pc -H- -k -b -v -y -DDEBUG -nDebug -c C:\MyC\test\test.cpp
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
C:\MyC\test\test.cpp:
エラー E2040 C:\MyC\test\test.cpp 15: 宣言が正しく終了していない
エラー E2034 C:\MyC\test\test.cpp 24: 'void *' 型は 'node *' 型に変換できない(関数 main() )
エラー E2158 C:\MyC\test\test.cpp 50: 'delete' のオペランドは非 const ポインタでなければならない(関数 main() )
エラー E2034 C:\MyC\test\test.cpp 111: 'void *' 型は 'node *' 型に変換できない(関数 add(int) )
エラー E2040 C:\MyC\test\test.cpp 124: 宣言が正しく終了していない
*** 5 errors in Compile ***

** error 1 ** deleting Debug\test.obj

Build End !! (Elapsed time 0:00.871)

693:デフォルトの名無しさん
08/06/09 20:54:37
CのコードをC++としてコンパイルして上手くいくわけないだろ。違う言語だぞ。

694:デフォルトの名無しさん
08/06/09 20:55:07
>>689
おっ・・・オサー・・・ん?

695:デフォルトの名無しさん
08/06/09 21:00:10
E:\Test>bcc32 a.cpp
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
a.cpp:
エラー E2040 a.cpp 15: 宣言が正しく終了していない
エラー E2034 a.cpp 24: 'void *' 型は 'node *' 型に変換できない(関数 main() )
エラー E2158 a.cpp 50: 'delete' のオペランドは非 const ポインタでなければならない(関数 main() )
エラー E2034 a.cpp 111: 'void *' 型は 'node *' 型に変換できない(関数 add(int) )
エラー E2040 a.cpp 124: 宣言が正しく終了していない
*** 5 errors in Compile ***

E:\Test>ren a.cpp a.c

E:Test>bcc32 a.c
Borland C++ 5.6.4 for Win32 Copyright (c) 1993, 2002 Borland
a.c:
Turbo Incremental Link 5.66 Copyright (c) 1997-2002 Borland

こういうこったな

696:デフォルトの名無しさん
08/06/09 21:09:24
mallocで確保したメモリ領域のサイズの求め方について分からないので
教えてください。下記のコードでは、出力される結果はchar型へのポインタの
サイズだと思いますが、メモリで確保した領域を取得する関数などは在りますか?

処理系はcygwin + gcc です。ウェブで検索するとmalloc.hにてmalloc_usable_size
という関数が紹介されていたのですが、私の環境では関数がない様でした。

int main (void){
  char *str;

  str = malloc(sizeof(char)*10);
  printf("sizeof(str)=%d\n", sizeof(str));

  return 0;
}

また、こういった動的に確保した場合の処理は皆さんはどの様に処理していますか?
やはり、自分でメモリ領域管理変数などを用意するのでしょうか?

697:デフォルトの名無しさん
08/06/09 21:10:29
>>692
C++ コンパイラ使うなら 15行目の delete は使えない(C++ のキーワードだから)

修正は次の通り
delete() → del() とかにする。3箇所
15: int del(int);
50: if( del(data) != 0)
124: int(del int data)


C++ ならキャストをしっかりと。2箇所
24: root = (node*) malloc(...
111: new_node = (node*)malloc(...


>>693
この程度 C ソースなら少し気をつければ C++ で動くで。

698:デフォルトの名無しさん
08/06/09 21:11:02
初心者はSTL

699:デフォルトの名無しさん
08/06/09 21:14:55
sizeof(str)
これだとポインターのサイズじゃねーの?

sizeof(char)*10
これを確保してるんだから
char型は1バイト、それを10個確保してるのが今回のサンプル

でmallocの場合は確保するサイズは自分でわかってないと無理でしょ・・・

int main (void){
  char *str;
unsigned long malloc_size;

malloc_size = sizeof(char)*10;

  str = malloc(malloc_size);
  printf("sizeof(str)=%d\n", sizeof(str));

  return 0;
}

700:デフォルトの名無しさん
08/06/09 21:15:39
  printf("sizeof(str)=%d\n", sizeof(str));

じゃないや

  printf("sizeof(str)=%d\n", malloc_size);

701:デフォルトの名無しさん
08/06/09 21:22:21
>>696
自分が確保するときに指定したサイズを知る方法を教えてくれってw

702:696
08/06/09 21:31:51
>699
レスありがとうございます。


>sizeof(str) これだとポインターのサイズじゃねーの?
 この書き方だとポインタサイズになってしまうが、mallocした領域サイズを
自分でずっと管理するのは面倒だな・・・。もしかして、領域サイズを取得する関数や、
手法がないのかなと思い、サンプル的にそのコードを出しました。
かえって意図が伝わり難くなったようですいません。


>701
やはり、動的取得の場合は無理なのですね。自分で管理することにします。

703:デフォルトの名無しさん
08/06/09 21:31:57
>>696
free(); を忘れないでね

704:680
08/06/09 21:32:06
>>697
ありがとうございます
エラーなく実行できました

705:デフォルトの名無しさん
08/06/09 21:34:25
>>696
sizeof(str) はあくまでも ポインタのサイズ。
ポインタの実態はアドレスの番地が管理されているため
環境にもよるが、アドレスを2^32まで割り当てられる環境では
変数の型がなんであれ、ポインタ自身のサイズは 4byte かと。

706:デフォルトの名無しさん
08/06/09 21:35:50
atoi(change)=="キムタクの頭"

707:デフォルトの名無しさん
08/06/09 21:47:46
すでに分かってる数字を改めて別のところから求めなおすのはムダ以外の何者でもない

708:696
08/06/09 21:59:30
>707
少数の変数を使用して、確保するので有ればその通りだと思います。
しかしながら、確保する領域が処理したいデータによって動的に、しかも多数
管理していく必要が出てきた場合、メモリ管理を自動化できるならば、
(この場合はメモリ確保領域をシステムに任せたいということですが)そうした方が
楽だと思います。また、そういったニーズは出てくるものではないでしょうか?

ここの方ならば、そういったノウハウをもしかして持っているのではないかと思い、
質問した次第です。


それならC以外の言語を使えというのはもっともだと思いますが。



709:デフォルトの名無しさん
08/06/09 22:02:15
うん、そういうことを自分でやるのが嫌ならC以外を使えでイナフ

710:デフォルトの名無しさん
08/06/09 22:02:31
gccの独自拡張とかc99でよければこうすればsiseofできるようになるけどwwww
int main()
{
int x;
x = 10;
char (*y)[x];
y = malloc(x);
printf("%d\n", sizeof(*y));
return 0;
}

711:デフォルトの名無しさん
08/06/09 22:03:35
typedef struct
{
    int length;
    char *str;
}VARCHAR;
みたいにくっつけて扱え

712:デフォルトの名無しさん
08/06/09 22:04:56
>>710
意味ねぇー(笑

713:デフォルトの名無しさん
08/06/09 22:05:06
>>710
変更できねーじゃんw

714:デフォルトの名無しさん
08/06/09 22:05:08
できないこともないけど、取り扱い注意

715:696
08/06/09 22:09:35
>710
ありがとうございます。参考にさせていただきます。


>711
やはり、そのように管理するのがスマートですね。その様に実装していこうと
思います。


みなさん、変な質問に答えてください、ありがとうございました。


716:デフォルトの名無しさん
08/06/10 00:06:55
文系大学生なんですが画像処理のためにC言語を覚えることにしました。
そこで今日書店に指南書を探しにいったのですがいまいちどれもとっつきにくく帰ってきました。
プログラムとはそもそも何かという概念的な事から始まり、揃えるべき環境(ツール)が細かく指定されてる超入門書ってないでしょうか?

717:デフォルトの名無しさん
08/06/10 00:09:20
推薦図書/必読書のためのスレッド 40
スレリンク(tech板)

718:デフォルトの名無しさん
08/06/10 00:09:35
>>716
>>651

719:デフォルトの名無しさん
08/06/10 00:12:31
>>716
本いるか・・・?

ネットで十分だろ。

720:デフォルトの名無しさん
08/06/10 00:13:29
さぁなぁ、それよりもまず 基本 仕組み を理解した方が良い。
いきなりコードを書いて、なんかで(・∀・)キターーじゃ話にならん。
どんな環境、プログラム言語も、動作させるコンピュータの仕組み
内面的な部分に命令を与えているわけだし、0と1の演算処理を
様々な変数、演算子、アルゴリズムで制御しているわけだ。

また、どんなコンピュータでもいえる事が、何かデータ、数値を与えて
与えられたデータを目的に応じて処理した結果を扱っているわけだ。
あとはそれを、人間が解釈できる形、例えば文字、色、画像、音声などで
表現できるコンピュータで都合よく見て理解しているわけだ。
画像だろうと音声データだろうと文字データだろうと、所詮は0と1の
バイナリーで他の塊に過ぎんのさ。

必要に応じて物を用意する。それは他のことでも言えること。
ただ、何があって何が出来るか?それを多少なりと把握しておく必要はある。

さて、何を見れば良いか?それは、他の人に聞いてくれ。

721:デフォルトの名無しさん
08/06/10 00:14:41
すいません既出でしたか、そちらを見てみます。
>ネットで十分だろ。
どうも実体があると落ち着くもので・・・。

722:デフォルトの名無しさん
08/06/10 00:16:39
とっとと消えろカス

723:デフォルトの名無しさん
08/06/10 00:36:59
>>722

724:デフォルトの名無しさん
08/06/10 02:08:41
何でも良いとは言えんが、とりあえずありきたりの内容が載っているものを。
って、何がありきたりか・・・配列、文字列、ポインタ、関数の自作、
素数、最大公約数、ソート、ファイルのダンプなど等、もちろんそれ以外でも
あれこれ挙げたらキリがないが。結局、何が目的か?

725:デフォルトの名無しさん
08/06/10 02:12:17
目的ありきだろ。

韓流スター見たさに、韓国語覚えたおばちゃんを見習え。
何もする予定無いのにC言語覚えても身につくわけない。

726:デフォルトの名無しさん
08/06/10 03:26:19
>>725
>>716をもう一度読むんだ

727:デフォルトの名無しさん
08/06/10 03:42:29
画像処理ったって、結局画像データを構成している実態は
0と1の組み合わせの塊を、必要に応じて展開、処理するわけでしょ?
BMPだと分かりやすいが、SVGはおりはさっぱりでやんす。
一応、XMLで記述されているとのことで、テキストエディタでも可能とかなんとか。
まぁ、それは画像編集であって、そんな編集するプログラムを作れるかは別だが。

728:デフォルトの名無しさん
08/06/10 03:44:05
画像処理ってのがかなり大きなくくりなんだよな・・・
画像処理でもwindows上でUSBカメラからの映像を・・・とか
マイコンで処理・・・とか

でぜんぜん扱いも違うしな。

729:デフォルトの名無しさん
08/06/10 05:10:54
GOTO文を使うなって学校教えられましたが、
実際の会社のプログラムとかでもやはり使わないのですか?

730:デフォルトの名無しさん
08/06/10 05:15:51
>>729
使わないね・・・

使わないように組めるようになるよ。

731:デフォルトの名無しさん
08/06/10 07:39:19
エラー処理と多重ループから抜けるのとで使う。
それ以外では使わない。

732:デフォルトの名無しさん
08/06/10 07:45:30
個人開発なら好きにしてもいいと思うが、仕事じゃ絶対ダメだな
俺は個人でも絶対使わないが

733:デフォルトの名無しさん
08/06/10 08:36:14
GOTO使わないからといってもプログラムがきれいになるわけでもないけどな。

734:デフォルトの名無しさん
08/06/10 09:45:50
なぜ使うなと言われるのかをちゃんと理解した上で
それでもここでは使うべきだ!と思うなら使っていい

735:デフォルトの名無しさん
08/06/10 11:16:09
むしろ仕事では使うが個人では絶対使わない

736:デフォルトの名無しさん
08/06/10 11:19:31
うまく機能分割して関数化していくとreturnで
GOTOの代わりのようにしちゃうこともあるな。

737:デフォルトの名無しさん
08/06/10 13:23:51
>>729
Cやその他の構造化言語を使うほぼ全ての人が、みだりに goto を使うことはよくないと考えている。
構造化プログラミングの恩恵は、コードの総体が構造的であるときに最もよく受けられるものだが、
goto はまったく構造的でないからである。特に複数の人間が長期に渡ってプロジェクトに関わるような
プログラム開発の現場では、保守性を低下させるとの観点から絶対に認めないとする場合も多い。

goto を使いたくなる全ての場面は、goto を使わなくても構造的な手法によって解決することができる。
特に小さいけれど結構ややこしい処理を敢えて関数に分割することで解決することができる。
あるいはちょっと手間をかけてフラグ変数を配備したり、ブロックの構成を工夫することなどがある。

しかし、ある種の処理を行う場合には goto を使うことをためらうことはないと考えている人も少なくはない。
最たるものはエラー処理である。エラーというものはその性質上、予定していた処理を全て切り上げて
制御を呼び出し元に返すことになる場合がほとんどだが、プログラムが複雑なものになってくると、
特にメモリの動的な割り付けを噛ませている場合などは、率直に return する前のちょっとした後片付けが
どうしても必要になってくることが多々ある。もちろんこれは構造的に解決することができるものであるが、
しかし構造が複雑化して却って可読性が低下したり、やたらと細かい関数分割になってしまう場合もある。
そういうことを嫌う人は、関数の末尾にだけジャンプして最低限の後始末だけを行うという限定つきで、
goto を使うことを容認していることがある。

構造化と効率は決してトレードオフの関係ではないが、どんな場合でも構造化を押し通そうとすると、
性能や保守性を低下させてしまうこともある。プログラムは常に構造的に書くことができるけれど、
プログラムで実際に解決しようとしている現実の諸問題、そして人間の思考方式そのものは、
必ずしも構造的でないからである。もちろん大抵は取るに足らない性能差で、コンパイラの最適化や
プロセッサの能力で消されてしまうが、問題となることももちろんある。そのような場面に直面したとき、
ここは goto を使うべきだと信じるなら、そうすればよい。それ以外では思いとどまったほうが無難である。

738:デフォルトの名無しさん
08/06/10 13:37:11
ループが最後まで回ったときだけ実行されるものがあるとgoto使いたくなるな。
実際はフラグにして使わないけど。

739:デフォルトの名無しさん
08/06/10 13:56:51
内容が長くなりすぎて削ってしまったが念のため書いておくと、
switch や break や continue や return も構造的でないジャンプ構文であり、
本質的には goto の同類である。これらの中から特に goto が取り上げられるのは、
そのジャンプする先を知ることが特別に難しいためだ。
だから goto を容認する人は、上の例でもあるように「関数の末尾にだけ飛ぶ」と言うような
処理の追跡を容易にするためのルールを作っていることがほとんどである。

740:デフォルトの名無しさん
08/06/10 14:08:15
ろ、longjmp・・・

741:デフォルトの名無しさん
08/06/10 14:10:10
>>737
>739だけ読んだ。

742:デフォルトの名無しさん
08/06/10 15:48:34
構造化以前のBASIC、77より古いFORTRAN、85より古いCOBOL
みんなGOTOで大きくなった。
そんななかでもGOTOの使い方にはマナーはあったのだ。

743:デフォルトの名無しさん
08/06/10 15:55:16
GOTOで戻ってループを作らないとかそんなんだろ

744:デフォルトの名無しさん
08/06/10 16:44:43
ifとgotoさえあればいいよね。

745:デフォルトの名無しさん
08/06/10 16:53:54
宿題のスレで goto 使ってみるかな。

嫌がらせかな?

746:デフォルトの名無しさん
08/06/10 16:57:14
ECHO OFF
:LOOP
ECHO 続けますか?
PAUSE
GOTO LOOP

747:デフォルトの名無しさん
08/06/10 16:59:22
続行するには何かキーを押してください . . .

748:デフォルトの名無しさん
08/06/10 17:02:34
^C

749:デフォルトの名無しさん
08/06/10 17:08:57
>>745
gotoは習ってないので使わないでお願いします
って言われるのがオチ

750:デフォルトの名無しさん
08/06/10 17:27:21
>>749
今の学校では習わないのかな?


751:デフォルトの名無しさん
08/06/10 17:27:59
おしえなくていいよ

752:デフォルトの名無しさん
08/06/10 17:33:38
だな~
GOTOはどうしようも無いケースで使う最後の手段と思ってたほうがいいな。


753:デフォルトの名無しさん
08/06/10 17:48:37
ふむ、俺は教えて方が言いとおもうけどな。

まぁ、使うことが「滅多に」無いのは認めるがね。

754:デフォルトの名無しさん
08/06/10 17:58:29
GOTOスレあったけど、もう使い切ってたか。

755:デフォルトの名無しさん
08/06/10 19:02:45
最初に教えると使っちゃうんだよ、決まった場所に飛ぶだけから超初心者には分かりやすいと感じるんだよ
forなんか人によってはなかなかわかってくれないもの

756:デフォルトの名無しさん
08/06/10 19:39:34
goto文がスパゲッティーとよく言われるが、
俺的にはgoto文は適度に使う分には全く問題ない。むしろ見やすい
1関数に1個なら大丈夫だろ

757:デフォルトの名無しさん
08/06/10 19:42:26
>>756
スパゲッティってのは時間をおいて固まってからが本領発揮なんだぜ?

758:デフォルトの名無しさん
08/06/10 19:42:47
自分で書いたソースだからじゃね?

759:デフォルトの名無しさん
08/06/10 19:52:05
そもそもスパゲッティはスパッゲティコードと呼ばれるような絡まり方はしない。

760:デフォルトの名無しさん
08/06/10 20:05:42
スパゲッティーミートクソース

761:デフォルトの名無しさん
08/06/10 20:06:21
ほそい麺でぺペロンつくると案外からまる

762:デフォルトの名無しさん
08/06/10 20:06:46
イヤホンコードが最強

763:デフォルトの名無しさん
08/06/10 21:06:09
最強は素麺でしょ?

764:デフォルトの名無しさん
08/06/10 21:13:23
物置にしまっといたロープ

765:デフォルトの名無しさん
08/06/10 21:28:20

void main(void)と
int main(void)の使い方の違いを教えて下さい

main関数はint型で戻り値が0かどうかで正常かエラーか判断するから
int main(void)の方が使い方としては正しいみたいだけどじゃあなぜ
void main(void)なんて教えたりするんでしょう?
return 0;を省略できるからでしょうか?

766:デフォルトの名無しさん
08/06/10 21:31:34
>>765
void main(void) は常に間違いである。
int main(void) または int main(int argc, char **argv) を使え。)

767:デフォルトの名無しさん
08/06/10 21:32:29
>void main(void)なんて教えたりするんでしょう?
教えてる人間がバカだから

768:デフォルトの名無しさん
08/06/10 21:32:34
最強は釣り糸でしょ?

769:デフォルトの名無しさん
08/06/10 21:36:22
>>766
void main(void) は常に間違いである。は間違いである。

770:デフォルトの名無しさん
08/06/10 21:37:28
11.14:
void main()と宣言してうまくいかないわけがないと思う。なぜならmain()から戻る代わりに、exit()を呼んでいるから。だいたい今使っているOSはプログラムのexit値/戻り値を無視する。

A:

main()から戻ってくるかどうかは関係ないし、そのステータスを見るかどうかも関係ない。問題はmain()の宣言がおかしいと、呼び出し側(実行時のスタートアップのコード)がmain()を正しく呼び出すことすらできないかもしれないことにある。

君が使っているOSは終了時のステータスを無視して、void main()でもうまく動くかもしれない。しかし、このやりかたは移植性が低いし、正しくもない。



771:デフォルトの名無しさん
08/06/10 21:37:47
Cなら、int main(void) か int main(int argc, char** argv) です。
それ以外は、間違いである。

(動くけどね)

772:デフォルトの名無しさん
08/06/10 21:38:33
引数はもっとおおくてもいいんじゃねーの?

773:デフォルトの名無しさん
08/06/10 21:39:51
処理系がもっと引数の多いエントリポイントを認めているなら、もっとおおくてもいい

774:デフォルトの名無しさん
08/06/10 21:42:33
逆に言えば、処理系が文書で認めていればvoid main(void)もありだよ。
良しと書いてあるマニュアルなんて今まで見たことがないけど。

775:デフォルトの名無しさん
08/06/10 21:43:59
取りあえず、void main(void) とか書いてある書籍は買うな。


776:デフォルトの名無しさん
08/06/10 21:45:49
失礼ですが、この意味を教えていただけないでしょうか?
まだC言語などを始めたばかりの初心者です。
エラーメッセージでこのような文章が出てきました。
undefine:n
どなたかよろしくお願いします

777:デフォルトの名無しさん
08/06/10 21:46:31
まず辞書を引けカス
naが定義されてないようです

778:デフォルトの名無しさん
08/06/10 21:50:47
分かりました。
void main(void)は使わないようにします

779:デフォルトの名無しさん
08/06/10 22:32:05
int main()
じゃあかんの?

780:デフォルトの名無しさん
08/06/10 22:33:13
いいよ

781:デフォルトの名無しさん
08/06/10 22:34:39
実験で書いたソース、ことごとくmain()でごめんなさい。

782:デフォルトの名無しさん
08/06/10 22:37:13
Cでは、明示的にvoid を書かないといけなかったはず。

783:デフォルトの名無しさん
08/06/10 22:37:51
じゃあ書かなかったらどうなるの?


784:デフォルトの名無しさん
08/06/10 22:38:23
たまには調べたら

785:デフォルトの名無しさん
08/06/10 22:39:12
皮肉もわかんないんですか?w

786:デフォルトの名無しさん
08/06/10 22:42:25
>>782
嘘をつくな

787:デフォルトの名無しさん
08/06/10 22:42:57
かかないと、古い形の函数定義になる。
C89ではblessed。

788:デフォルトの名無しさん
08/06/10 22:46:15
おまいら、勉強不足だね

789:デフォルトの名無しさん
08/06/10 22:47:04
>>788
煽るだけですか?w

790:デフォルトの名無しさん
08/06/10 22:48:40
>>785

日本語、勉強しておいで

791:デフォルトの名無しさん
08/06/10 22:49:58
お前らいい加減にしろよ!

792:デフォルトの名無しさん
08/06/10 22:50:41
今日は大漁ですな。

793:デフォルトの名無しさん
08/06/10 22:51:06
ここまで俺の自演

794:デフォルトの名無しさん
08/06/10 22:57:50
>>789

お前もだろw


795:デフォルトの名無しさん
08/06/10 23:36:11
int main (int argc, char *argv[], char *envp[])

796:デフォルトの名無しさん
08/06/10 23:47:49
またしょーもないことでのびてんんあ

797:デフォルトの名無しさん
08/06/10 23:52:53
こういう専門スレだと知識がない奴は揚げ足を取るぐらいしかレスできないからな…

798:デフォルトの名無しさん
08/06/11 00:00:45
取りあえず、無視しましょう。

799:デフォルトの名無しさん
08/06/11 00:08:49
#if 0
aori();
#endif

800:デフォルトの名無しさん
08/06/11 00:10:40
11.13:
main関数の3番目の引数envpは。

A:

これは(よく見かけるけれど)標準でない拡張である。標準で用意されているgetenv()関数が提供すること以上に環境の情報が必要ならば、グローバル変数environを使うほうがまだましな手段だろう(これも同 じように標準ではないが)。

References:
ANSI Sec. F.5.1; ISO Sec. G.5.1; H&S Sec. 20.1 pp. 416-7.

801:デフォルトの名無しさん
08/06/11 00:12:41
C99って、広まってるの?

802:デフォルトの名無しさん
08/06/11 00:14:14
いいえ

803:デフォルトの名無しさん
08/06/11 00:19:48
VC++はシカトしてます
C++と互換性のない部分はやる気なし

804:デフォルトの名無しさん
08/06/11 00:21:18
C++と分化しちゃってってなぁ・・・

805:デフォルトの名無しさん
08/06/11 00:29:14
VC++は%aとかintptr_tとかおいしい(?)とこだけかじっている。
ほかには__restrictや__pragmaなども。

806:デフォルトの名無しさん
08/06/11 00:39:37
>>766
ダウト。”常に”も”間違い”でもないよ。環境による。
とりわけ、ISO、ANSI 準拠では main は int 型の変数を返すことになっている。
環境にもよるということで、必ずしもそうとは言えないし、少なくとも 間違い ではない。

807:デフォルトの名無しさん
08/06/11 00:43:16
日本語でおk。

void main(void) は移植性は悪いが
その処理系で定義されているなら
その処理系でしかそのプログラムをコンパイルできない可能性があってもいいのであれば
使っても構わない。

ただ、入門書で使うのはどうかしてるよね。
VC++ しかコンパイラ知らないんじゃないかと。

808:デフォルトの名無しさん
08/06/11 00:43:53
vcでこそ怒られるとおもうがw

809:デフォルトの名無しさん
08/06/11 01:00:43
最近のVCは怒るのか

810:デフォルトの名無しさん
08/06/11 01:02:49
VCは、比較的厳しい方だと思うぞ
gccの方が柔軟なイメージがある

811:デフォルトの名無しさん
08/06/11 01:05:30
void mainにしたところでどれくらい変わるか知らないけど、
わかりやすい説明ができるなら入門書の内容に移植性なんか必要無いと思う

コンパイラとか環境までオマケでついてるような書籍なら。

812:デフォルトの名無しさん
08/06/11 01:08:33
必要ありすぎる。
移植性の無いコードなんて初心者に見せるもんじゃない。

813:デフォルトの名無しさん
08/06/11 01:13:08
なにも知らない初心者のうちからint main(void)で叩き込んどけば
後からの余計な手間がかからないだろ。

814:デフォルトの名無しさん
08/06/11 01:23:27
gccはデフォルトはデレデレ。-Wall -pedantic-errorsでツンツンになるよ。

815:デフォルトの名無しさん
08/06/11 01:25:49
-ansi -pedantic-errors -Wall
-std=c99 -pedantic-errors -Wall

のどちらかは必ず付けるね。

816:デフォルトの名無しさん
08/06/11 01:26:03
-Wもつけないと

817:デフォルトの名無しさん
08/06/11 01:28:28
man gcc にはそんなの載ってないけど、バージョンによるのかな。

818:デフォルトの名無しさん
08/06/11 01:30:31
gccだと、enum定義でカンマの後ろに}を書いてもコンパイル通るんだっけ

819:デフォルトの名無しさん
08/06/11 01:31:30
>>818
c89だとだめで独自拡張でアリでc99だとアリだった気がする

820:795
08/06/11 01:31:51
>>800
>>774
ANSIにも参考情報として載るくらいメジャーな拡張を書いただけだが
わざわざ補足ありがとうね

821:デフォルトの名無しさん
08/06/11 01:32:21
>>773だったorz

822:デフォルトの名無しさん
08/06/11 02:00:15
>>806
「規格には反しているが処理系によっては動く」ということを間違いでないと断定することは、
ありとあらゆる規格に反する書き方が間違いでないことになる可能性があることに気付いているか。
文法が正しいか正しくないかは、プログラムが動くか動かないかとは本質的に別の問題である。
文法は守るべきものであり、仮に文法に反することが容認されるとしても、それは正しいからではない。



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