プログラミング学習日記

プログラミング学習時のメモ帳。

ポインタ型

間違っている場所あったら優しく教えてね

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

f:id:topaz1-3:20190616102145p:plain
下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]の値を取れることができると思いやってみたらできました.間接参照演算子でアドレスが同じ場合はその値を拾ってくることができます.

参考

http://www.cc.kyoto-su.ac.jp/~yamada/programming/pointer

http://rainbow.pc.uec.ac.jp/edu/program/b1/Prob4-1.htm

ブログを見ていただきありがとうございました