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


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

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



1 名前:デフォルトの名無しさん mailto:sage [2008/10/31(金) 20:15:31 ]
C言語の入門者向け解説スレです。

教えて欲しいのではなく宿題を丸投げしたいだけなら
↓宿題スレ↓へ行ってください。
  C/C++の宿題を片付けます 117代目
  pc11.2ch.net/test/read.cgi/tech/1225320579/

・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
  # 抜粋/整形厳禁、コンパイラに渡したソースをそのまま貼ること
  # サイズが大きい場合は宿題スレのアップローダ等を利用してください
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
  C言語なら俺に聞け(入門篇) Part 37
  pc11.2ch.net/test/read.cgi/tech/1224000127/
過去スレ
  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

449 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:23:22 ]
>>445
えーとだな、まず64ビット整数はたとえば0x0000000012345678 という数値なわけだ。
これをスタックに積んで、32ビットで取り出すと、0x12345678 と 0x00000000の2つの数字がとれるわけ。
なんで2番目が0になるかわかったろ?

450 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:26:17 ]
>>445
>printf ("time2=%ld\n",t2)
この場合も、0x0000000012345678を積んで、0x12345678だけ取り出したから
たまたまうまくいってるように見えるだけで、上位32ビットは切り捨てられている。

451 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:26:44 ]
>>448
それは少し古い時代のint型だな
今は大抵4バイトなんで-2147483648 to 2147483647 を表せることが多い


452 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:26:45 ]
intが16ビットなんて8ビットパソコンの時代じゃないか(80年代)
参考書が古すぎ

453 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:35:38 ]
>>451
そうですか、分かりました。
どうもありがとうございます。


454 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:52:02 ]
>>449-450

ありがとうございます。上手くいきました。

t1-long(t2) ってやってました。>>445を読むまで理屈が判りませんでした。

VC6とかだと上手くいってたのかな?サンプルコードも油断ならないですね

455 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 10:56:54 ]
× >>445を読むまで理屈が判りませんでした。
○ >>449を読むまで理屈が判りませんでした。

安価間違えたorz

456 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 11:00:00 ]
>>454
long(t1)は、time_t型のt1の値を、long型にキャストすると言うことだ。
t1 - long(t2)では、time_t型のt1からlong型にキャストされたt2の値を引こうとしてしまうので、
time_t型の実態であるlong long型にキャストして引き算を行なってしまうので結果はlong long型のまま。
引き算する場合はlong(t1 - t2)としなくては意味がない。

そもそもtime_t型は実態が32ビット整数だった時代が長いから無理もないとは思うが、
32ビット整数である保証がないのでちゃんとキャストするべき。それをしていないサンプルは、当てにならないと言うこと。

尚、time_t型同士の引き算は本来なら、difftime()を使うべき。

457 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 11:09:00 ]
>>456
結局のところ、printf("%g\n", difftime(t1, t2))ってことね。
# だからといって、printf("%g\n", difftime(t1, 0))する奴ぁいねぇと思うが。



458 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 11:34:56 ]
対角要素に0があっても正しく動く逆行列を求めるソースおちてないですかね?

459 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 12:48:52 ]
同じx86-64bitでも、Windows系の64と、Unix/BSD/Linux系の64アーキテクチャの違いも・・・

460 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:07:30 ]
>>427
自分もプログラミング入門者なんだが、苦しんで覚えるC言語ってサイトがわかりやすいと思う

お互い頑張りましょう。

461 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:13:02 ]
>>446
コードそのものは正しい
16bit環境には対応していないというだけ

462 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:23:20 ]
>>460
俺も昔、苦しんで覚えたなw
血便、下血、終電、睡眠デバッグ・・・

463 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:32:19 ]
>>460
「苦しんで覚えるC言語」リンク先のsetjump/longjump
>プログラムの流れをグチャグチャにする凶悪な関数であり、よほどの事情でもない限り使用してはいけない。
ワラタ
後に例外処理 try 〜 chatch に衣替えして支持を得る、元祖例外処理サポート関数のデビュー作なのに、
誰も正しい使い方を広められず、gotoと併せて鵜呑み受け売りで語り継がれて忌み嫌われたんだよね。

464 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:39:18 ]
longjumpが悪だとは決して思わないけれど
忌み嫌われる程度には危険で使いにくいと思う

465 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:41:11 ]
海の怖さを知って初めて一人前の猟師
そういうことさ

466 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:44:09 ]
コードの海は俺の海

467 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:51:00 ]
そして怖い膿を知った



468 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 13:57:00 ]
まあデストラクタが呼ばれないから実際使えなかったわな。

469 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 18:26:41 ]



「今は大抵○バイト」



一番ダメな考え方

こうやって決め打ちすると、そこから変わった場合に一切対処できずに泣いて誰かに助けを頼むことになる


「ママが○バイトだって言ってたから○バイトじゃなきゃダメなんだあああウワアアアアン!」




470 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 18:30:46 ]
分かったからお前が解説してやってくれ

471 名前:デフォルトの名無しさん [2008/11/07(金) 18:47:01 ]
>>468
おまえC使いのくせにスタックの巻き戻し程度のものが自分で実装できんのか?

472 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:17:37 ]
関数にn次の2次元配列を渡す場合はどう書けばいいですか?

double data[n][n]とかいう配列です


473 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:31:08 ]
void func(double **data)

474 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:32:14 ]
>>472
void hoge(double *pData)
とか
void hoge(double Data[n][n])
じゃだめ?

475 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:35:34 ]
>>473
渡すときは func(data)ですか?

476 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:38:37 ]
ああ間違えた。>>473が正しい。
ポインタじゃなくて実体そのものをコピーしていいなら俺のでもいい・・・はず・・・

pc11.2ch.net/test/read.cgi/tech/1225320579/
の379の質問か。


477 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:40:15 ]
>>475
そう

>>476
間違っています
勉強しなおしましょう



478 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:40:44 ]
>>476
>>475+>>473だとコンパイルがとおらないんです

479 名前:デフォルトの名無しさん [2008/11/07(金) 19:43:19 ]
>>473 であるべき、と強硬に言い張る奴が昔いた
一生懸命 malloc してたw

480 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:44:01 ]
>>473は大嘘
普通は func(double data[][n])

481 名前:476 mailto:sage [2008/11/07(金) 19:45:25 ]
>>477
あ、下のほうって意味だったんですが、VC++で動くけど問題なんでしょうか?
以下のソースで動きました。

void test(int data[2][2])
{
printf("%d\n", data[0][0]);
printf("%d\n", data[0][1]);
printf("%d\n", data[1][0]);
printf("%d\n", data[1][1]);
}
int main(int argc, char *argv[])
{
int data[2][2] = {0,1,2,3};
test(data);

return(0);
}

482 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:48:29 ]
void test(int data[][2])
{
printf("%d\n", data[0][0]);
printf("%d\n", data[0][1]);
printf("%d\n", data[1][0]);
printf("%d\n", data[1][1]);
}
int main(int argc, char *argv[])
{
int data[2][2] = {0,1,2,3};
test(data);

return(0);
}

これでいい

483 名前:476 [2008/11/07(金) 19:50:57 ]
>>482
関数で一次限の配列の要素数を書かない理由はポインタ渡しにしたいからですか?
それとも別の理由?

484 名前:デフォルトの名無しさん [2008/11/07(金) 19:50:58 ]
K&R で書くなら ANSI 混ぜるなよ

485 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:56:33 ]
>>472
関数に配列を渡すことはできない。渡されるのは常に配列の戦闘要素へのポインタである。
double data[X][Y] という配列があるとき、data は double の配列の配列であり、
これを関数呼び出しの引数に書くと、それは double の配列へのポインタに変換される。
実際に関数にわたるのはこのポインタで、その型は double (*)[Y] である。
だから関数の仮引数の宣言は以下のようになる。

int func(double (*data)[Y]) …@

ただし、これは次のように書いてもいい。

int func(double data[X][Y]) …A
int func(double data[][Y])  …B

Aは配列そのものを表しているが、既に述べたように関数が配列そのものを受け取ることはない。
そこで、関数の仮引数に配列が書かれたときには、配列がその先頭要素へのポインタに置き換わるのと同様に、
その配列要素へのポインタを宣言したのと同じに扱われることになっている。だからAの持つ意味は@と同じである。
ここでAがポインタに置き換わるとき、当然最初の添字Xは無視されることとなる。つまりBのように省略が可能である。

486 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 19:59:26 ]
>>483
最初の添字が無意味だから
したかろうがしたくなかろうが配列を引数に書いたら 絶 対 に ポインタ渡しになる

487 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 20:02:33 ]
配列を値渡ししようとしてもポインタの値渡しになるから

値そのものは渡せない



488 名前:476 [2008/11/07(金) 20:09:51 ]
>>485-487
丁寧な説明ありがとうございます。
おかげでポインタの理解が深まりました。
人の質問に答えて見るもんですね。
同様に構造体の配列も要素数書いてもポインタになるのを始めて知りました。
試してみたらアドレス一緒でビックリ!
でも、なんでdata[0]->data1じゃなくてdata[0].data1なんでしょうか?

typedef struct{
int data1;
int data2;
}TEST_TABLE;

void test(TEST_TABLE data[2])
{
printf("%d\n", data[0].data1);
printf("%d\n", data[0].data2);
printf("%d\n", data[1].data1);
printf("%d\n", data[1].data2);
}

int main(int argc, char *argv[])
{
TEST_TABLE data[2] = {0,1,2,3};

test(data);
return(0);
}

489 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 20:23:24 ]
まったく理解できてねぇwwwwwww

490 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 20:40:40 ]
>>429
これでいいじゃない。
struct tm *v_localtime(time_t t)
{
return localtime(&t);
}

strftime(buf, sizeof buf, "%Y%m%d", v_localtime(time(0));


491 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 20:41:33 ]
>>488
dataがポインタだから
data[0]は構造体自体

492 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 20:42:27 ]
>>488
[]演算子に*の意味が入っているから。

493 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 21:03:43 ]
1 TEST_TABLE data[10]; TEST_TABLEを要素とする配列。
2 data[0] 先頭要素。
3 &data[0] 先頭要素のポインタ。
4 data だけ書いたら↑3と同じ。
5 TEST_TABLE *p = &data[0]; 配列先頭要素へのポインタで変数 p を初期化。
6 TEST_TABLE *p = data; ↑5 と同じ。
7 p->data1 ポインタを使って要素へアクセス。
8 data->data1 ↑6,7 から、これは 7 と等価。
9 data と p は等価だから、data[0] は p[0] と等価。
10 つまり *p は p[0]。
11 (*p).data1 *演算子はポインタから実体を返す。だから要素アクセスはドット。
12 (*data).data1 上と同じ。
13 data[0].data1 ↑2で書いたように要素なのでアクセスはドット。
14 data[1] 二番目の要素。
15 &data[1] 二番目の要素のポインタ
16 以下 data[0] と同じ。
17 data[2] 三番目の要素。
18 以下↑と同じ。
19 p = dataのとき、 data[1] は *(p + 1) と同じ。
20 つまり、&data[1] は p + 1
21 data[1] は data[0] の後ろにくっついてるわけだから
22 &data[1] と &data[0] の間のアドレス距離は data[0] の大きさ分ある。
23 つまり、 p+1 と p では data[0] の大きさだけ移動してる。
24 等価等価言ってきたけど、 p++ はできて、data++ はできない。

25 以上とは関係なく、関数の仮引数では data[] は配列じゃなくポインタ。

494 名前:476 mailto:sage [2008/11/07(金) 21:11:52 ]
>>491-493
またまた詳しい説明、ありがとうございました。
ポインタに関して理解していないところの多さを感じました。
まだまだ勉強不足ですね。
さて、名無しに戻って元々したかった質問をします。

495 名前:デフォルトの名無しさん [2008/11/07(金) 21:16:40 ]
VC++でファイルからデータを読み込み分解するプログラムを作りたいです。
ファイルには
hoge:aaa\r\n
hage:bbb\r\n
のように記述されていて、
hoge:に対する記述は
hoge:aaa\r\n
hoge:bbbb;012\r\n
と";"の後にもデータが続いている場合があります。
aaaやbbbbの文字数は一定ではないです。
これを読み出すときに、
sscanf(bBuf,"hoge: %s",&data[HOGE][0]);
としているのですが、";"以降がdataに入りません。
どうしたらいいでしょうか?

496 名前:デフォルトの名無しさん [2008/11/07(金) 21:33:13 ]
>>493
> 3 &data[0] 先頭要素のポインタ。
> 4 data だけ書いたら↑3と同じ。

ダウト
sizeof &data[0] != sizeof data

497 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 21:46:16 ]
>>496
それは例外事項

data だけなら先頭要素のアドレスで正しい



498 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 21:49:47 ]
ん?

499 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 21:52:25 ]
不毛だ

500 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 21:58:46 ]
うるせーな
気にしてんだよ

501 名前:デフォルトの名無しさん mailto:sage [2008/11/07(金) 22:18:19 ]
data と p が等価で、 sizeof data が例外なのか。
p = data ができるのが例外なのか。






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

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

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