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


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

スレを勃てるまでもないC/C++の質問はここで 5



1 名前: ◆h6A7qfFFu6 mailto:sage [2008/12/29(月) 11:05:07 ]
スレを勃てるまでもない低俗なC/C++の質問はここでお願いします。

過去ログ
スレを勃てるまでもないC/C++の質問はここで
pc11.2ch.net/test/read.cgi/tech/1167476845/
スレを勃てるまでもないC/C++の質問はここで 2
pc11.2ch.net/test/read.cgi/tech/1178503366/
スレを勃てるまでもないC/C++の質問はここで 3
pc11.2ch.net/test/read.cgi/tech/1187521676/
スレを勃てるまでもないC/C++の質問はここで 4
pc11.2ch.net/test/read.cgi/tech/1221633708/

522 名前:デフォルトの名無しさん mailto:sage [2009/01/03(土) 23:43:49 ]
俺も面白いと思った。

while("無限ループ")
{
  /* なんか */
}

まあ、しないけど

523 名前:デフォルトの名無しさん mailto:sage [2009/01/03(土) 23:44:49 ]
>>519
さすがにお前の粘着ぶりがキモイ

524 名前:デフォルトの名無しさん [2009/01/03(土) 23:46:13 ]
while(j=10-i++) を書いた奴が指摘されて、まだファビョってるのか?
基地外だろ、こいつ。指摘した方が言ってもいないことを思っているとか言い出すし。

525 名前:デフォルトの名無しさん mailto:sage [2009/01/03(土) 23:49:41 ]
whileの括弧の中が条件式でなければ駄目とは言っていないし、変数を用いて
0か否かで繰り返し条件を指定することもかのうだが、あの式は紛れもなく
代入式で、jの値を使うにしては、不適切だとコンパイラも指摘しているのだが・・・

526 名前:デフォルトの名無しさん mailto:sage [2009/01/03(土) 23:51:04 ]
プw

527 名前:デフォルトの名無しさん mailto:sage [2009/01/03(土) 23:53:39 ]
いやぁがんばってるね

528 名前:デフォルトの名無しさん mailto:sage [2009/01/03(土) 23:55:30 ]
while(*dst++=*src++);

529 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:00:53 ]
>>525
>while文の括弧の中は、
>本来は条件式が入るんだが、それは代入だろ。例え括弧で代入式を括っても、
>それに対して条件式にあう措置をとるべき。

530 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:03:01 ]
>>524
ファビョってるのは「while文の中は、条件式が適切なのに、代入式で…」うんぬん
いってる>>442だろ
ながれ読めよ

>>525
>>456 で結論出てるのにいつまでやってんの?



531 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:04:48 ]
>>530
>>524=>>442で本人だからしょうがないんだよw

532 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:15:46 ]
最近よく喧嘩するね

533 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:29:14 ]
テュルー

534 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:29:51 ]
冬休みだからしかたない

535 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:30:16 ]
出た、「冬休み」

536 名前:デフォルトの名無しさん [2009/01/04(日) 00:37:35 ]
connect(sock,( struct sockaddr * ) &echoservaddr, sizeof(echoservadr))

この文の * が意味することがまったくわかりません
*の後に文字もないのですが、ポインタとしてありえなくないでしょうか?

537 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:38:30 ]
ポインタ型でキャストしてるだけ

538 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:51:54 ]
人はなぜ>>534のような発言をするのか。
それは「私は子供ではない」と誇示したいからである。

では、「私は大人だ」と主張する人間が「大人」なのだろうか。
答えは否、断じて否である。

539 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:56:57 ]
で?

540 名前:536 [2009/01/04(日) 00:57:57 ]
つまり&echoservaddr構造体のポインタを
sockaddr構造体のポインタとしてあつかうってことでしょうか?

まったく何をしているか理解できないのですが



541 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 00:58:58 ]
>>539

542 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:00:57 ]
>>540
その通りの事をやっている。
sockaddr_in 構造体を sockaddr 構造体であるかのように
無理矢理見なして渡している。
sockaddr_in 構造体と sockaddr 構造体はサイズが同じで、
かつ、こうやってキャストしてもいいと問題ないとされている。

543 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:02:07 ]
connect()の第2引数はstruct sockddr *型(struct sockddr型へのポインタ)を取る。
そこで、&echoservaddr(echoservaddrのアドレス)をstruct sockddr *型(struct sockddr型へのポインタ)へキャストしている。

544 名前:536 [2009/01/04(日) 01:03:51 ]
>>542
見なす理由がわからないのです。
sockaddr_inのほうが入ってる情報というか入力する情報は多いし
その情報はconnectする際に必要だと思います。
なのに、何故必要な情報がすべてあひってないsockaddr構造体とみなすのかがよくわかりません

545 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:07:27 ]
www.linux.or.jp/JM/html/LDP_man-pages/man2/connect.2.html

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

2番目の引数の型には、const struct sockaddr *が”必要”

546 名前:536 [2009/01/04(日) 01:08:58 ]
必要な理由がわからないのです。
ていうか、入れてしまっては前述した疑問がわいてしまって

547 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:10:08 ]
理由は、connect()がそういう仕様だから。
connect()を作った人間がそういう風に作ったから。

548 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:11:16 ]
>必要な理由がわからないのです。

なんというか……

549 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:12:22 ]
>>544
総称的な型として sockaddr を用意して、
connect は sockaddr* を受け取る汎用的な形にしておいて、
より詳細な構造体として sockaddr_in を用意し、
それをキャストして渡す、という風になってんじゃないのかね。
場合によっては sockaddr_in 以外のものも作るつもりだった、
あるいは将来作れるように、そういう風にしてんじゃない?
void* でいいような気もするけど、
それだと何でもキャスト無しに渡せちゃうから、
渡していい構造体なのかどうか注意して指定させるように、
キャスト無しでは渡せないようにしているんだと思う。
まあ、全部推測だけどね。

550 名前:536 [2009/01/04(日) 01:13:40 ]
つまりsockaddr_in 構造体の中にある入力したアドレスに接続するわけですよね。
しかしsockaaddr構造体にはアドレスがない。それなのに、sockaddr構造体とみなしてしまっては、
アドレスないから接続できなくないのでは?ということです。





551 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:14:33 ]
っていうか、全部が全部
現状が正しい前提で理由を付けなくてもいいと思うけど。
頭いいひとにありがちだよね。

552 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:16:41 ]
後の改造のために凝った事やって、
結局改造なんてしなかった、
ってこともよくある話で。
互換性のために、とかもよくある話。

553 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:18:58 ]
>>546
int connect(int sockfd, const void *addr, socklen_t addrlen);
なら、キャストする必要はないが、connect の第二引数が struct sockaddr である以上、
キャストする必要がある。
ここではキャストする型が重要なのではなく、socket作成時に指定したプロトコルファイミリーが重要。
プロトコルファミリーごとにconnectに必要な情報量は異なり、
kernelでもプロトコルファミリーごとに呼ばれるconnecが異なる。
kernelではaddrlen分ユーザー空間からメモリをコピーし、
所望の処理を行うので、struct sockaddr が重要なのではない。

554 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:20:44 ]
>>550
ああ、そういうことか。
sockaddr_inはsockaddrをIPv4に特化したもの。
sockaddr_inを使うのはIPv4だけだ。
connect()はIPv4以外でも使われる。

www.linux.or.jp/JM/html/LDP_man-pages/man2/socket.2.html

AF_INETの他に
AF_APPLETALKとかあるだろ。

555 名前:536 [2009/01/04(日) 01:26:58 ]
>>554
socketでAF_INETを指定しているのですが、
この場合だとIPv4でconnectしてるということでは?

556 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:34:20 ]
>>555
そう。
sockaddr_inを使うのはsockaddrを使うより便利だから。
IPv4を使う場合でもsockaddrにアドレスを設定してもいいよ。でも面倒だよ。
ともかく、connect()が必要とするのはsockaddr_inではなくsockaddrなの。

/usr/include/sys/socket.h にstruct sockaddrとstruct sockaddr_inの定義があるから見比べてみてよ。

557 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:36:55 ]
>>550
sockaddrとしてもsa_familyが読み取れる。
そこがAF_INETならsockaddr_inにキャストしてアドレスを読み取るという風になっている。
ほかのAF_*にも対応するsockaddr_*が存在しうるという仕組み。

>>549
そういうことなんだろうけど、IPv6を収めるには小さすぎたのが惜しかった。

558 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:39:57 ]
どうせサイズ渡してんだし、
sockaddr::sa_family だけでよかった気もする。

559 名前:536 [2009/01/04(日) 01:42:07 ]
struct sockaddr {
u_short sa_family;
char sa_data[14];
};

sockaaddr構造体はこのようになっているが、何も入力していない

struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};

inのほうはこのようになっていて、アドレスはポートやファミリーは入力している。

で、このinの方を
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
これとして扱う。しかし、ここにはアドレスが入っていない。
だとしたら、どうやってサーバーに接続する?という疑問がわきます。

けれど、inに入力したファミリーがsockaaddrに引き継がれて、
sockaddrのファミリがわかって、そこからまた、inの構造体を参照?するのでしょうか
どうやって参照するかがまた謎ですが

560 名前:536 [2009/01/04(日) 01:44:22 ]
>sockaddrとしてもsa_familyが読み取れる。
>そこがAF_INETならsockaddr_inにキャストしてアドレスを読み取るという風になっている。

これだと、sockaaddrをキャストしてもsockaaddrにはポートやアドレス入力してなければ
読み取れないのでは?





561 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:45:14 ]
4.2BSDのsockaddrはsa_lenは無くて、sa_familyだけだった。

562 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:46:55 ]
IPv4として使う場合、
アドレスファミリをAF_INETにして
sockaddr_inにアドレス詰めて
connect()に渡すときはsockaddrにキャストして
connect()の内部ではsockaddr_inとしてアドレスを読み出す。

563 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:48:29 ]
>>561
それが合理的だな。

>>560
sockaddr_in を渡すのなら
sa_family に AF_INET を入れないといけないし、
sa_family に AF_INET を入れるのなら
渡す物は sockaddr_in でなくてはいけない。
それ以外の使い方して変になっても
それはそんな変な使い方をした人が悪い。

564 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:48:51 ]
>>560
入力してなければ読み取れないが、入力するためにsockaddr_inにしてポートやアドレスを入力するんだろ?
キャストしてもメモリの内容は変わらない。

565 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 01:50:49 ]
echoservaddr.sin_family = AF_INET;
echoservaddr.sin_port = xxx;
echoservaddr.sin_port = yyy;
connect(sock,( struct sockaddr * ) &echoservaddr, sizeof(echoservadr))

――connectの中
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
if (addr->sa_family == AF_INET)
{
const const struct sockaddr *addr_in = (const const struct sockaddr *)addr;
だいたいこんな感じのはず。
ここでaddr_in->sin_portを読めばxxxだし、addr_in->sin_addrからはもちろんyyyが読み取れる。

566 名前:536 [2009/01/04(日) 01:58:56 ]
>connect()に渡すときはsockaddrにキャストして
>connect()の内部ではsockaddr_inとしてアドレスを読み出す。

つまり、connectに渡す情報は、空の
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
これであって、特に決まりで中に何も入力されてなくても意味はない。

で、内部でどこのアドレスに接続するか処理するのが、
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
この入力しておいたinの方。ってことでいいのでしょうか。

inをsockaddrにキャストしても入力しておいた値で共通する変数名とかないですもんね
だからキャストしても??

567 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 02:00:32 ]
空じゃなくてアドレス等を入力したものをsockaddrとみなして渡してる。
(( struct sockaddr * ) &echoservaddr)->sa_data[2]〜[5]とか見れば納得するのかな?

568 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 02:04:55 ]
>>566
connectに渡しているのは構造体のアドレス。内容は渡していない。

569 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 02:10:06 ]
#include <stdio.h>

void print_bytewise(const unsigned char *buf, size_t size) {
 size_t i;
 for (i = 0; i < size; i++) {
  printf("%02X ", buf[i]);
 }
 putchar('\n');
}

int main(void) {
 int n = 0x12345678;
 print_bytewise((const unsigned char*)&n, sizeof n);
 return 0;
}

これとやってる事は本質的に同じ。

570 名前:536 [2009/01/04(日) 02:13:08 ]
>>567
struct sockaddr_in {
u_short sa_family;
char sa_data[14];
[0]short sin_family;
[1]unsigned short sin_port
[2]struct in_addr sin_addr
[3]char sin_zero[8];
};

つまり、イメージ的にはこうなのかな?



571 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 02:17:05 ]
こう。

sa_family          ⇔ sin_family (2 バイト)
sa_data[0]〜sa_data[1] ⇔ sin_port (2 バイト)
sa_data[2]〜sa_data[5] ⇔ sin_addr (4 バイト)
sa_data[6]〜sa_data[13] ⇔ sin_zero (8 バイト)

572 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 02:23:51 ]
connect(2)ってだいたいこんな感じで使うだろ。

struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(80),
.sin_addr = {
.s_addr = inet_aton("192.168.1.1")
}
};

connect(skfd, (struct sockaddr *)&addr, sizeof(addr);

>>536はなにか勘違いしてる気がしてならない。

573 名前:536 [2009/01/04(日) 02:34:31 ]
>>571
お!
もしかして
sockaddr_inは、計16バイトでその情報はsockaddrに全て対応する
sa_family はsinfamilyに
sa_data[14]には残りの14バイトのアドレスが格納されるということになってるのかな

だとすると、どちらかの構造体だけ入力しとけばいいってのも納得できるのですが
これでいいのでしょうか?

574 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 02:46:42 ]
>>573
いままでの回答全て無駄っぽい。
sockaddrはアドレスファミリーから見れば関係ないんだって。
例えばUNIX ドメインソケットなら sockaddr_un だし、
IPv4なら sockaddr_in がconnectには必要。
ただ、歴史的背景かなにかはしらないが、connect(2)のインターフェースが
「void *」ではなく、「sockaddr *」になってるってだけ。

575 名前:536 [2009/01/04(日) 02:56:41 ]
>>574
つまり>>571ではないと?
ますますわけわかんなくなってきた

struct sockaddr* をキャストの型として &echoservaddrするってのがよくわからないのかなぁ

&echoservaddrには>>572にかいてあるようなin構造体のアドレスが入力ずみではあるけど
それをキャストすると、どう扱われるってのがよくわかんないかも

いや、本当にみなさんに色々教えてもらっているのに理解がたりなくて申し訳ないです。
キャストとかsockaaddrとかぐぐってるけど、いまいち理解できない・・・

576 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:01:20 ]
>>575
>>571 であってる。
まず、>>569 が理解できるか確認してくれ。

577 名前:536 [2009/01/04(日) 03:11:36 ]
>>576
すみません。まったくわかりません。
const unsigned char*)&n
char型(nの値が格納されている)アドレスへのポインタ

なんかもうわかりません

578 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:18:13 ]
ま、深夜だし思う存分続けてくれたまえ

579 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:27:31 ]
>>577
典型的な「ポインタを理解していない」状態だね。
まあ、初心者は大抵一度は通る道だ。

ポインタを理解するのは簡単だ。メモリを理解すれば良い。ただそれだけだ。

変数とかの中身はメモリに置かれている。
メモリは1バイト単位に分割されていて、それぞれのバイトに住所が割り振られている。

[0番地][1番地][2番地]・・・

でも、例えば int とかのサイズは1バイトではない。現在は4バイトが主流だね。
こういうのは、メモリ上の連続した領域を占有することになる。
そして、int 型の変数(例えば >>569 の n)に & をつけると、
この連続した4バイトの領域の先頭のバイトの住所が取得できる。

[----------------------- int n ------------------------]
[12938100番地][12938101番地][12938102番地][12938103番地]   (住所は一例)
   ↑
  先頭   &n == 12938100番地

でも、別にこの4バイトの領域を int の値と見なさなくてはいけないわけではない。
例えば勝手に char 4要素の配列だと見なしても構わないわけだ。

[-- char [0] --][-- char [1] --][-- char [2] --][-- char [3] --]
[12938100番地][12938101番地][12938102番地][12938103番地]

んで、この char 4要素の配列の先頭要素の住所もやっぱり12938100番地なわけだ。

こういう解釈の変更を行っているのが、
(const char*)&n みたいなキャストになるわけだ。

580 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:39:44 ]
ポインタってのは2つの属性から構成されている。
1つはメモリ上の占有している領域の先頭の住所(アドレス)と、
そしてそのアドレスにある値を「何の型の値だと見なすか」だ。
ある変数のポインタは、変数に & をつけることで得られる。

変数に & を付ける事によって得られるポインタの型は、
元の変数の型に * をつけた形で表現する。
ポインタは基本的にただアドレスなんつー単なる値を保持するだけのもんなので、
ポインタを保持する変数なんかも作る事ができる。
例えばこんな感じだ。

int *p = &n;

変数 p は n のアドレス、例えば12938100番地などといったような値を保持しているわけだ。
んでさらに、p は int* という型なわけだが、
この int って部分は、12938100番地から始まる領域を int 型の値だと見なすよ、って意味を持っている。

これを char 型の値だと見なしたい場合は、char* にキャストしてしまえばいい。

char *c = (char*)p;

これで、やっぱり変数 c には p に入れられていた領域と同じ場所を指すアドレスが入れられるわけだけど、
c の型は char* なんで、その領域を char 型の値だと見なすようになるわけだ。

この話の int と char を sockaddr_in と sockaddr に置き換えれば、
connect に関する話も分かるはず。



581 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:46:11 ]
ポインタ……それは恋だ!

582 名前:デフォルトの名無しさん [2009/01/04(日) 03:48:03 ]
>>580
ポインタの正確な定義わ?

583 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:53:40 ]
ボイン太、それはAVだ!

584 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 03:56:43 ]
残念ながらボッシュートで〜す

585 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 05:24:40 ]
ってか、ぶっちゃけお前らの一番好きなC89基本型ってなんなの

586 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 05:50:24 ]
int
異論は認めない

587 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 05:58:07 ]
unsigned long int

588 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 05:59:37 ]
size_t 異論 は 色ん なものがあるだろうから認める

589 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 06:10:51 ]
char
ちゃ〜

590 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 06:21:28 ]
size_tって中身はint?



591 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 06:33:26 ]
符号なしのint型が一般的らしい。time_tとかも。

592 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 06:33:54 ]
grepすりゃすぐ判るかと

593 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 06:39:50 ]
>>592 だから何?

594 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 06:44:36 ]
にしても
>>588>>589はひどいなww

595 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 07:06:34 ]
俺は断然


bool

596 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 08:34:21 ]
し、bool……?

597 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 09:30:43 ]
いやいやいや
void*

598 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 09:31:48 ]
√とかはC言語で使えないのでしょうか・・?
特殊相対性理論における時間の遅れ、運動してる物体の速度を入力することによって
運動してる物体の時間の刻みを出すプログラムを作りたのですが、・・C言語で√は使えないのでしょうか・・?


599 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 09:34:48 ]
>>598
確かに特殊相対論は中学生でも理解できるが、お前は別の勉強をした方がいいよ

600 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 09:35:15 ]
#include <math.h>




601 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 09:36:56 ]
あえて俺はLPVOIDと書く

602 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 09:43:28 ]
>>600-601
サンクス

603 名前:536 [2009/01/04(日) 10:55:21 ]
>>580
丁寧にありがとうございます。
しかによくわからない点があります。

>変数に & を付ける事によって得られるポインタの型は、
>元の変数の型に * をつけた形で表現する。

つまりこれで先ほどの例だと
int n; という宣言が先に必ずある
int *p = &n;    その上で、元の変数の型はint n よりint型であることがわかっているので
p の型はintにしないといけない。よって、nのアドレスが格納されているpは、
(元の変数の型)intに*をつけて int *pとあらわすということですよね。
しかしよくわからないのですが、p = &n; とint *p = &nの違いがわかりません
前者はpにはnのアドレスの値が入っている。
後者はpにはnのアドレスの値が入っているのではないのでしょうか?
前者だと先にint p; と宣言しておけばp はint型になるのでは?



604 名前:536 [2009/01/04(日) 10:57:59 ]
あと、もう1点ですが
>char *c = (char*)p;

int *p = &n;  としたのなら、
char*c = (char*)*p もしくはchar*c = (char)*p となるのではないのでしょうか?

605 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:04:19 ]
二段ダブルベット

606 名前:536 [2009/01/04(日) 11:10:16 ]
すみません、もうひとつ
先ほどの例の場合

int型をchar型にする利点というか意味がわからないのですが
サイズが異なる構造体をキャストしたら中身が全然違うのに型を変えるとか想像がつきません



607 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:13:34 ]
>>603
>>580ではないけど、
その日本語だと君がどこまで理解できたのかが分からない
材料は揃ってるようだから、手を動かしたほうがいいよ。

問題の値をそれぞれprintf()してどうなったか、
試すくらいはしてから再度の質問はするものだ


608 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:18:19 ]
型宣言の *と
演算子の*を混同している・・・・?

609 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:20:10 ]
C言語でおk

610 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:28:42 ]
>p の型はintにしないといけない。よって、nのアドレスが格納されているpは、
p の型は int へのポインタ型。

>しかしよくわからないのですが、p = &n; とint *p = &nの違いがわかりません
>前者だと先にint p; と宣言しておけばp はint型になるのでは?
int *p; と宣言してあれば両者はほぼ同じ。

int* っていうのは「int へのポインタ」っていう「型」だってのは OK?
ポインタと元の型はきちんと区別するべき。

>int *p = &n;  としたのなら、
>char*c = (char*)*p もしくはchar*c = (char)*p となるのではないのでしょうか?
c は char へのポインタ型。p は int へのポインタ型。*p は int 型。
(char*)*p だと int 型を char へのポインタという型に変換している(c と型は一致するが普通意味を持たない)。
(char)*p だと int 型を char 型へ変換している(c と型が違うのでコンパイルできない)。

>int型をchar型にする利点というか意味がわからないのですが
>サイズが異なる構造体をキャストしたら中身が全然違うのに型を変えるとか想像がつきません
int へのポインタ型を char へのポインタ型にしても大抵メリットはない。
sockaddr 型と sockaddr_in 型は >571 の通り sa_family の部分は共通しているので >557 の通り
sockaddr へのポインタ型を経由して sa_family を読み出し、AF_INET だったら実は sockaddr_in を指していたんだとして
キャストしてきちんと読み出すことができる。
つまり関数の引数の型としては sockaddr へのポインタ型としてまとめておいて、実際には sa_family に応じて
正しい型にキャストして使うことができる。



611 名前:536 [2009/01/04(日) 11:33:40 ]
int へのポインタ型。ってのがよくわからないのですが
一つのプログラムでintを宣言する変数なんてたくさんでてくるとおもうのですが、
この場合、intへのポイントとはどうなるのでしょうか?

612 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:43:30 ]
>536
キャストもポインタもないこのコードは理解できる?
sockaddr, sockaddr_in, connect() についても本質的にはこのコードみたいなことをしている(type が sa_family)。

#include <stdio.h>

struct Any
{
    enum { CHAR, INT, DOUBLE } type;
    union {
        char c;
        int n;
        double d;
    } u;
};

void print(struct Any a)
{
    if(a.type == CHAR) printf("%c\n", a.u.c);
    if(a.type == INT) printf("%d\n", a.u.n);
    if(a.type == DOUBLE) printf("%f\n", a.u.d);
}

int main(void) {
    struct A a;
    a.type = CHAR; a.u.c = '>'; print(a);
    a.type = INT; a.u.n = 536; print(a);
    return 0;
}

もっとも共用体が分かるなら最初っから理解できているような気もするけど。
分からなかったら余計混乱する気がするんで無視してくれ。

613 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 11:49:45 ]
>611
>一つのプログラムでintを宣言する変数なんてたくさんでてくるとおもうのですが、
>この場合、intへのポイントとはどうなるのでしょうか?
そうだね。だから色んな場所を指せるし、指し直したりできる。

char c1;
char c2;
int n;
char *p; /* どこも指してない */

p = &c1; /* c1 のアドレスを指す */
p = &c2; /* c2 のアドレスを指す */
p = (char*)&n; /* n は char型じゃないけどキャストして無理矢理 n の(先頭)アドレスを指す */

614 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:15:32 ]
麻雀は分かるか? 二盃口は七対子と見た目は同じだよね。

|二|二|三|三|四|四|七|七|八|八|九|九|發|發|
|萬|萬|萬|萬|萬|萬|索|索|索|索|索|索|  |  |

これを一盃口を1かたまりで解釈すると二盃口と解釈できるし、

|二|二|三|三|四|四|  |七|七|八|八|九|九|  |發|發|
|萬|萬|萬|萬|萬|萬|  |索|索|索|索|索|索|  |  |  |

全部対子で解釈すると七対子と解釈できる。

|二|二|  |三|三|  |四|四|  |七|七|  |八|八|  |九|九|  |發|發|
|萬|萬|  |萬|萬|  |萬|萬|  |索|索|  |索|索|  |索|索|  |  |  |

そして、別に役とか関係無しに単に牌が 14 個並んでいるだけだと解釈することもできる。

|二|  |二|  |三|  |三|  |四|  |四|  |七|  |七|  |八|  |八|  |九|  |九|  |發|  |發|
|萬|  |萬|  |萬|  |萬|  |萬|  |萬|  |索|  |索|  |索|  |索|  |索|  |索|  |  |  |  |

615 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:16:14 ]
ここで、1つの牌を1バイトと考え、
対子を2バイトの toitsu_t 型で、
一盃口を6バイトの ipeko_t 型で表せるとする。

役とは関係無しにただ牌が 14 個並んでいると解釈している時は手牌を

char tehai[14];

というただの char 配列で眺めているのに相当する。
二盃口と解釈している時は手牌を

struct ryanpeko_t {
 ipeko_t ipeko[2];
 toitsu_t toitsu;
};

という構造体だと見なして解釈しているのに相当する。
七対子と解釈している時は手牌を

struct chitoitsu_t {
 toitsu_t toitsu[7];
};

という構造体だと見なして解釈しているのに相当する。

616 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:16:36 ]
#include <iostream>
using namespace std;
#include <math.h>

void atai();
int main()
{
cout<<"こんにちわ。"<< endl;
atai();
return 0;
}
void atai()
{
double v;/*v=物体の速さ*/
double undou;/*運動する物体の時間の刻み*/
double c = 108000000;/*光の速さ*/
cout<<"物体の速さ入力:(km)";
cin>>v;
double ruto;
ruto = sqrt(1 / (1.0000000 - (v/c) * (v/c)));
undou = ruto;
cout<<"物体の時間の刻み"<<undou<<endl;
cout<<"静止している物体が1年間すごしている間"<<endl;
cout<<"運動している物体は"<<1 / ruto<<"年間過ごしてる"<<endl;

}

光の速さより大きい数字を入力すると-1.#INDと、表示されます・・


617 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:17:38 ]
役が成り立っているか脳内で判定してると思うが、
まあそういう役が成り立っているかを判定する関数があるとする。

int check_toitsu(const toitsu_t *toitsu);  /* ちゃんと対子として成り立っていれば 1 を、そうでなければ 0 を返す */
int check_ipeko(const ipeko_t *ipeko);   /* ちゃんと一盃口として成り立っていれば 1 を、そうでなければ 0 を返す */

これを使って ryanpeko_t 型の値が本当に二盃口として成り立っているのかをチェックする関数を作ると、こうなって、

int check_ryanpeko(const ryanpeko_t *ryanpeko) {
 return
  check_ipeko(&ryanpeko->ipeko[0]) &&
  check_ipeko(&ryanpeko->ipeko[1]) &&
  check_toitsu(&ryanpeko->toitsu);
}

chitoitsu_t 型の値が本当に七対子として成り立っているのかをチェックする関数を作ると、こうなる。

int check_chitoitsu(const chitoitsu_t *chitoitsu) {
 int i;
 for (i = 0; i < 7; i++)
  if (!check_toitsu(chitoitsu->toitsu[i]))
   return 0;
 return 1;
}

んで、手牌 tehai をこのチェック関数に渡すには、こんな感じになるわけだ。

if (check_ryanpeko((const ryanpeko_t*)&tehai))
 puts("二盃口として解釈可能です");

if (check_chitoitsu((const chitoitsu_t*)&tehai))
 puts("七対子として解釈可能です");

618 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:18:15 ]
>>616
負の値の平方根はできない

619 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:18:41 ]
とりあえず、「速さ」の単位は「km」じゃないよ。
ローレンツ変換の前に学ぶことがあると思うんだ。。



620 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:19:08 ]
割り込まれてしまったが、
>>614>>615>>617 の順で読んでくれ。



621 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:20:49 ]
すげーな、この流れは
ポインタFAQ用のテンプレとして、是非利用すべきだ
まったく読んでないけど

622 名前:デフォルトの名無しさん mailto:sage [2009/01/04(日) 12:20:59 ]
>>616
#include <complex.h>







[ 続きを読む ] / [ 携帯版 ]

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

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