08/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:デフォルトの名無しさん
08/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
08/11/07 19:50:57
>>482
関数で一次限の配列の要素数を書かない理由はポインタ渡しにしたいからですか?
それとも別の理由?
484:デフォルトの名無しさん
08/11/07 19:50:58
K&R で書くなら ANSI 混ぜるなよ
485:デフォルトの名無しさん
08/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]) …②
int func(double data[][Y]) …③
②は配列そのものを表しているが、既に述べたように関数が配列そのものを受け取ることはない。
そこで、関数の仮引数に配列が書かれたときには、配列がその先頭要素へのポインタに置き換わるのと同様に、
その配列要素へのポインタを宣言したのと同じに扱われることになっている。だから②の持つ意味は①と同じである。
ここで②がポインタに置き換わるとき、当然最初の添字Xは無視されることとなる。つまり③のように省略が可能である。
486:デフォルトの名無しさん
08/11/07 19:59:26
>>483
最初の添字が無意味だから
したかろうがしたくなかろうが配列を引数に書いたら 絶 対 に ポインタ渡しになる
487:デフォルトの名無しさん
08/11/07 20:02:33
配列を値渡ししようとしてもポインタの値渡しになるから
値そのものは渡せない
488:476
08/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:デフォルトの名無しさん
08/11/07 20:23:24
まったく理解できてねぇwwwwwww
490:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/11/07 20:41:33
>>488
dataがポインタだから
data[0]は構造体自体
492:デフォルトの名無しさん
08/11/07 20:42:27
>>488
[]演算子に*の意味が入っているから。
493:デフォルトの名無しさん
08/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
08/11/07 21:11:52
>>491-493
またまた詳しい説明、ありがとうございました。
ポインタに関して理解していないところの多さを感じました。
まだまだ勉強不足ですね。
さて、名無しに戻って元々したかった質問をします。
495:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/11/07 21:33:13
>>493
> 3 &data[0] 先頭要素のポインタ。
> 4 data だけ書いたら↑3と同じ。
ダウト
sizeof &data[0] != sizeof data
497:デフォルトの名無しさん
08/11/07 21:46:16
>>496
それは例外事項
data だけなら先頭要素のアドレスで正しい
498:デフォルトの名無しさん
08/11/07 21:49:47
ん?
499:デフォルトの名無しさん
08/11/07 21:52:25
不毛だ
500:デフォルトの名無しさん
08/11/07 21:58:46
うるせーな
気にしてんだよ
501:デフォルトの名無しさん
08/11/07 22:18:19
data と p が等価で、 sizeof data が例外なのか。
p = data ができるのが例外なのか。