ポインタ型
間違っている場所あったら優しく教えてね
C言語を含むプログラミング言語は,メインメモリを使って実行している. メインメモリは1バイト(8ビット)ごとに区切られている.
ポインタ型
ポインタ型と一言に行ってもint型のポインタ型やchar型のポインタ型が存在する.
なぜかというとポインタ型は参照する場所のアドレスの情報を持つだけでなく参照先の型がなんの型なのかも情報として知る必要があるからである.
宣言
int *p
これでint型ポインタ型のp
が宣言される.
*
記号は間接参照演算子を用いている.
この定義を日本語にすると
ポインタ型の変数pを定義します.参照先はint型です.
こうすると理解できました.しかしこの状態ではpはどこのアドレスも参照していない.参照場所を定義しただけでポインタ型に何も値を入れていないので出力は0となっている.(初期化もしていないので)
int *p; printf(" %p\n " , p ); // 出力は, 0x0
ポインタ型は宣言しただけで初期化を行なっていません.そのため初期値が不定となっています
int *p; *p = 10; // ポインタ型のpは初期化されていないためエラーが起きる.
(参考2を参照)
int *p; int a = 10; p = &a; printf(" %p\n " , p ); // 出力は, アドレスが返される printf'" %d\n " , *p ); // 出力は 10 *p = 20; printf(" %d\n" , a ); // 出力は 20
3行目でアドレス演算子をaに使用してポインタ型のpに対してaのアドレスを代入している. intのaとポインタ型のpは同じアドレスを参照している. そのため6行目で間接参照演算子を用いてaの値を変更することができる.
配列とポインタ
ポインタが威力を発揮するのは配列とともに使うときです.
- 配列の宣言
大きさ3の配列を宣言します
int array[3]; array[1] = 2;
このように array[ 添字 ] を使用して配列にアクセスすることができました. この配列のアドレスを見てみます.
#include <stdio.h> int main(void) { int array[3]; printf("array[0] : %p\n", &array[0]); printf("array[1] : %p\n", &array[1]); printf("array[2] : %p\n", &array[2]); return 0; } ////////出力/////////////// array[0] : 0x7ffeed74c85c array[1] : 0x7ffeed74c860 array[2] : 0x7ffeed74c864
下3桁だけ表示すると上図のように並んでいることがわかります. 配列はint型なので4バイト(環境によって異なる場合あり)使われています.
#include <stdio.h> int main(void) { int array[3]; printf("array[0] : %p\n", &array[0]); printf("&array : %p\n", &array); printf("array : %p\n", array); return 0; } ///////////出力//////////////// array[0] : 0x7ffeeba2985c &array : 0x7ffeeba2985c array : 0x7ffeeba2985c
配列に添字をつけずにarray
のアドレスがどこに存在するかをみていきます. array
が参照している先は,array[0]のアドレスと同じ場所でした.
#include <stdio.h> int main(void) { int array[3]; array[0] = 10; array[1] = 20; printf("&array[0] : %p\n", &array[0]); printf("array[0] : %d\n", array[0]); printf("&array : %p\n", &array); printf("array : %p\n", array); printf("*array : %d\n", *array); return 0; } ////////////////出力/////////////// &array[0] : 0x7ffee88d085c array[0] : 10 &array : 0x7ffee88d085c array : 0x7ffee88d085c *array : 10
arrayがarray[0]と同じアドレス値を返すならそこからarray[0]の値を取れることができると思いやってみたらできました.間接参照演算子でアドレスが同じ場合はその値を拾ってくることができます.