2019-03-31 11:00:21 +00:00
---
title: 『新版C言語プログラミングレッスン 入門編』第11章・ポインタ
author: kazu634
date: 2008-05-02
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:3971;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- C
- Programming
---
< div class = "section" >
< p >
難関に入ります。
< / p >
< h4 >
「ポインタ」とは何か?
< / h4 >
< blockquote title = "http" cite = "http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10" >
< p >
「ポインタとは、変数のアドレスをもつ変数である」
< / p >
< p >
< cite > < a href = "http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10" onclick = "__gaTracker('send', 'event', 'outbound-article', 'http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10', 'http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10:title');" target = "_blank" > http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8& s=books& qid=1209639049& sr=1-10:title< / a > < / cite >
< / p >
< / blockquote >
< p >
とりあえず研修でハードウェアについてたたき込まれているので、この説明でなんとなくわかる。要は主記憶上のアドレスを格納できる変数を「ポインタ」という…みたいです。
< / p >
< p >
< a name = "seemore" > < / a >
< / p >
< h4 >
「ポインタ」の定義の仕方
< / h4 >
< p >
こんな感じだよー。
< / p >
< pre class = "syntax-highlight" >
< span class = "synType" > int< / span > *p;
< / pre >
< h4 >
「ポインタ」への代入
< / h4 >
< p >
「& 」演算子を用いると変数のアドレスがわかります。例:
< / p >
< pre class = "syntax-highlight" >
p = & x;
< / pre >
< h4 >
「ポインタ」の参照
< / h4 >
< p >
printfではこんな感じになる。
< / p >
< pre class = "syntax-highlight" >
printf(< span class = "synConstant" > " </ span >< span class = "synSpecial" > %p\n</ span >< span class = "synConstant" > " </ span > , p);
< / pre >
< p >
また、ポインタが指している他の変数の値も参照できる。例えば
< / p >
< pre class = "syntax-highlight" >
< span class = "synType" > int< / span > x;
< span class = "synType" > int< / span > *p;
x = < span class = "synConstant" > 123< / span > ;
p = & x;
*p = < span class = "synConstant" > 456< / span > ;
< / pre >
< p >
とすると、xの値が456になる。
< / p >
< h4 >
「ポインタ」のインクリメントとか
< / h4 >
< blockquote title = "http" cite = "http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10" >
< ul >
< li >
「p++」: ポインタpが「一つ次」の変数を指すようになる
< / li >
< li >
「p– 」: ポインタpが「一つ前」の変数を指すようになる
< / li >
< / ul >
< p >
< cite > < a href = "http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10" onclick = "__gaTracker('send', 'event', 'outbound-article', 'http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10', 'http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8&s=books&qid=1209639049&sr=1-10:title');" target = "_blank" > http://www.amazon.co.jp/%E6%96%B0%E7%89%88C%E8%A8%80%E8%AA%9E%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%AC%E3%83%83%E3%82%B9%E3%83%B3-%E5%85%A5%E9%96%80%E7%B7%A8-%E7%B5%90%E5%9F%8E%E6%B5%A9/dp/4797336781/ref=sr_1_10?ie=UTF8& s=books& qid=1209639049& sr=1-10:title< / a > < / cite >
< / p >
< / blockquote >
< h4 >
例
< / h4 >
< pre class = "syntax-highlight" >
< span class = "synPreProc" > #include < / span > < span class = "synConstant" > < stdio.h> < / span >
< span class = "synType" > void< / span > swap_int(< span class = "synType" > int< / span > *xp, < span class = "synType" > int< / span > *yp);
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > );
< span class = "synType" > void< / span > swap_int(< span class = "synType" > int< / span > *xp, < span class = "synType" > int< / span > *yp)
{
< span class = "synType" > int< / span > tmp;
tmp = *xp;
*xp = *yp;
*yp = tmp;
}
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > )
{
< span class = "synType" > int< / span > x, y;
x = < span class = "synConstant" > 4< / span > ;
y = < span class = "synConstant" > 5< / span > ;
printf (< span class = "synConstant" > " x = </ span >< span class = "synSpecial" > %d</ span >< span class = "synConstant" > , y = </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , x, y);
swap_int(& x, & y);
printf (< span class = "synConstant" > " x = </ span >< span class = "synSpecial" > %d</ span >< span class = "synConstant" > , y = </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , x, y);
}
< / pre >
< p >
ここで個人的に注意すべきなのは、void swap_intのところでの「*xp」などといった表記は、「変数がポインタである」ことを示す。それに対して、以降の「*xp」などは「xpに入っているアドレスが参照している変数」を指す。この違いが分からず、ちょっと混乱してしまった。
< / p >
< h4 >
配列とポインタの関係
< / h4 >
< p >
ポインタのインクリメントは、おそらく配列の内部で使うことを想定しているのだと思われる。
< / p >
< pre class = "syntax-highlight" >
< span class = "synPreProc" > #include < / span > < span class = "synConstant" > < stdio.h> < / span >
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > );
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > )
{
< span class = "synType" > int< / span > x[< span class = "synConstant" > 3< / span > ] = {< span class = "synConstant" > 1< / span > , < span class = "synConstant" > 3< / span > , < span class = "synConstant" > 9< / span > };
< span class = "synType" > int< / span > *p_x;
< span class = "synType" > int< / span > i;
p_x = & x[< span class = "synConstant" > < / span > ];
< span class = "synStatement" > for< / span > (i = < span class = "synConstant" > < / span > ;i < < span class = "synConstant" > 3< / span > ;i++) {
*p_x = *p_x * *p_x;
p_x++;
}
< span class = "synStatement" > for< / span > (i = < span class = "synConstant" > < / span > ;i < < span class = "synConstant" > 3< / span > ;i++) {
printf (< span class = "synConstant" > " x[</ span >< span class = "synSpecial" > %d</ span >< span class = "synConstant" > ]: </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , i, x[i]);
}
< span class = "synStatement" > return< / span > (< span class = "synConstant" > < / span > );
}
< / pre >
< p >
これは
< / p >
< pre class = "syntax-highlight" >
< span class = "synPreProc" > #include < / span > < span class = "synConstant" > < stdio.h> < / span >
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > );
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > )
{
< span class = "synType" > int< / span > x[< span class = "synConstant" > 3< / span > ] = {< span class = "synConstant" > 1< / span > , < span class = "synConstant" > 3< / span > , < span class = "synConstant" > 9< / span > };
< span class = "synType" > int< / span > i;
< span class = "synStatement" > for< / span > (i = < span class = "synConstant" > < / span > ;i < < span class = "synConstant" > 3< / span > ;i++) {
x[i] = x[i] * x[i];
}
< span class = "synStatement" > for< / span > (i = < span class = "synConstant" > < / span > ;i < < span class = "synConstant" > 3< / span > ;i++) {
printf (< span class = "synConstant" > " x[</ span >< span class = "synSpecial" > %d</ span >< span class = "synConstant" > ]: </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , i, x[i]);
}
< span class = "synStatement" > return< / span > (< span class = "synConstant" > < / span > );
}
< / pre >
< p >
と結局同じことをしていることになる< span class = "footnote" > < a href = "/sirocco634/#f1" name = "fn1" title = "でも、私には二つ書き方があることは分かっても、二つの違いは分からなかったりorz。たぶん、効率とかなんかが違うのだと思われる" > *1< / a > < / span > 。
< / p >
< h4 >
構造体と「ポインタ」の関係
< / h4 >
< pre class = "syntax-highlight" >
< span class = "synPreProc" > #include < / span > < span class = "synConstant" > < stdio.h> < / span >
< span class = "synPreProc" > #include < / span > < span class = "synConstant" > < string.h> < / span >
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > );
< span class = "synType" > struct< / span > student
{
< span class = "synType" > int< / span > id;
< span class = "synType" > char< / span > name[< span class = "synConstant" > 20< / span > ];
< span class = "synType" > int< / span > japanese;
< span class = "synType" > int< / span > math;
< span class = "synType" > int< / span > eng;
};
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > )
{
< span class = "synType" > struct< / span > student yukari;
< span class = "synType" > struct< / span > student *p;
yukari.id = < span class = "synConstant" > 1< / span > ;
strcpy(& yukari.name[< span class = "synConstant" > < / span > ], < span class = "synConstant" > " Yukari" < / span > );
yukari.japanese = < span class = "synConstant" > 80< / span > ;
yukari.math = < span class = "synConstant" > 70< / span > ;
yukari.eng = < span class = "synConstant" > 100< / span > ;
p =
< span class = "synComment" > /* 構造体のポインタを用いた参照はこのように書く */< / span >
(*p).id = < span class = "synConstant" > 2< / span > ;
printf (< span class = "synConstant" > " Yukari's id: </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , (*p).id);
< span class = "synComment" > /* もしくはこのように書く */< / span >
p-> id = < span class = "synConstant" > 3< / span > ;
printf (< span class = "synConstant" > " Yukari's id: </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , p-> id);
< span class = "synStatement" > return< / span > (< span class = "synConstant" > < / span > );
}
< / pre >
< h4 >
練習問題
< / h4 >
< p >
一つ目の変数の阿智が二つ目より小さいときには値を交換し、そうでないときには何もしない関数をポインタを用いて作るよ。
< / p >
< pre class = "syntax-highlight" >
< span class = "synPreProc" > #include < / span > < span class = "synConstant" > < stdio.h> < / span >
< span class = "synType" > void< / span > swap_bigint(< span class = "synType" > int< / span > *x, < span class = "synType" > int< / span > *y);
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > );
< span class = "synType" > void< / span > swap_bigint(< span class = "synType" > int< / span > *x, < span class = "synType" > int< / span > *y)
{
< span class = "synType" > int< / span > tmp;
< span class = "synStatement" > if< / span > (*x < *y) {
tmp = *x;
*x = *y;
*y = tmp;
}
}
< span class = "synType" > int< / span > main(< span class = "synType" > void< / span > )
{
< span class = "synType" > int< / span > x, y;
x = < span class = "synConstant" > 5< / span > ;
y = < span class = "synConstant" > 3< / span > ;
printf (< span class = "synConstant" > " Setting Value: x -> </ span >< span class = "synSpecial" > %d</ span >< span class = "synConstant" > , y -> </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , x, y);
swap_bigint(& x, & y);
printf (< span class = "synConstant" > " After the swap_value: x -> </ span >< span class = "synSpecial" > %d</ span >< span class = "synConstant" > , y -> </ span >< span class = "synSpecial" > %d\n</ span >< span class = "synConstant" > " </ span > , x, y);
< span class = "synStatement" > return< / span > (< span class = "synConstant" > < / span > );
}
< / pre >
< / div >
< div class = "footnote" >
< p class = "footnote" >
< a href = "/sirocco634/#fn1" name = "f1" > *1< / a > : でも、私には二つ書き方があることは分かっても、二つの違いは分からなかったりorz。たぶん、効率とかなんかが違うのだと思われる
< / p >
2019-04-02 16:06:15 +00:00
< / div >