#include <stdio.h> void test_print(char* array) { printf("%d\n", *array); } int main() { char array[] = {0, 2, 4, 6, 8, 10}; test_print(array + 1); return 0; }
出力は2です。
まぁこれtest_print(&array[1]);
と同義なんですけど。いわゆるポインタ演算というやつ。
なんでわかりにくいかっていうとポインタ演算って普通、以下のような感じじゃないですか。
(これの出力も2)
char test = *(array + 1); printf("%d\n", test);
記事にしようと思ったけど途中でめんどくさくなってやめた
ポインタ理解しにくい3つの理由の筆頭に上がるであろう
「アスタリスクに意味持たせすぎ問題」
がめちゃくちゃ混乱を招いてしまうわけですよ。
引数の*
はポインタという型を意味していて、
後者の右辺にある*(array + 1)
の *
はポインタの中身を意味しているわけですよ(printfとかでよく使うのも後者)。
で、結局引数としてポインタ(アドレス)を渡しているので、指定したindexの配列のアドレスとしても置き換えられるのです。(test_print(&array[1]);
と同義のところの解説)
(アドレスっていうと&
だろ。っていう連想もポインタ理解しにくい3つの理由のうちのひとつなんですが、話すと長くなるのでまた今度)
ポインタ演算の突っ込んだ解説(おまけ)
ポインタ演算がなんでできるかっていうと、型が決まっているからなんですね。
つまり、型によって +1 で進むbyte数が違うんですよ。
実験してみましょう。
先ほどのコードのtest_printのprintfは*
でそこのポインタ(の中)の値をとってきていたので、この*
外すとアドレスをprintfできます。
というわけで以下のような感じ
#include <stdio.h> void test_print(char* array) { printf("%p\n", array); } void test_print_int(int* array) { printf("%p\n", array); } int main() { char char_array[] = {0, 2, 4, 6, 8, 10}; int int_array[] = {0, 2, 4, 6, 8, 10}; test_print(char_array); test_print(char_array + 1); test_print_int(int_array); test_print_int(int_array + 1); return 0; }
この結果は私の環境では以下の通り
0x7fff4e19d500 0x7fff4e19d501 0x7fff4e19d4e0 0x7fff4e19d4e4
最初の2つがchar型
最後の2つがint型
同じ+1だけど、差分が違うのがわかると思います。
もっと知りたい方は以下の本に詳しく書いてあります。
- 作者: 前橋和弥
- 出版社/メーカー: 技術評論社
- 発売日: 2017/12/07
- メディア: 大型本
- この商品を含むブログを見る