clang ポインタとおともだちになりたい

ポインタとお友達になりたくて

9cguide.appspot.com をやってる。 (環境はmacOS + VSCode)

めっちゃおもしろい(いまのところ) railsメインで開発してるんだけど、 無意識に使っていて(使っている自覚もない)、 名前だけしか聞いたことないポインタの秘密が徐々に明らかになって行く感覚があって、とても興奮する。はすはす

めもったやつぺたーって貼る。

Clang ポインタ

&付の変数
  • &は変数のアドレスを求める演算子である

    - &演算子を使うと,その変数のアドレスを知ることができる

    定義

ex)int型変数のアドレスを記憶するpという変数

int *p - int* p - 2つ以上の変数宣言で,2つ目以降は見かけの型名と違ってしまう

代入

理屈上ではPCに積んでるメモリ番号の範囲内ならOKだが、仮想メモリによりそうはいかない。

=> もう一つ別の変数を宣言し,そのアドレスを代入する

int *p
int i;
p = &i; // &i: iのアドレス(ポインタ型)

モード切替

  • ポインタ変数モード
    • p : とくになにもつけない
  • 通常変数モード
    • *p : 変数の前に*をつける
    • *付きのポインタ変数は,通常変数と同じ機能になる

【変数定義の*とモード切替の*(間接参照演算子)は何の関係もない別記号である】

ポインタ変数モードで読み書きしたいメモリアドレスを代入,
-> 通常変数モードに切り替えて操作する

ポインタの役割

  • ショートカット

関数の引数に配列が入る場合

  • 値渡しでなくアドレスを渡す

    • []演算子:配列の要素番号を指定する
    • 配列名というアドレスに足し算を起こっなっている
  • 配列名 = その配列の先頭要素のアドレス値として扱われる

  • なので、ポインタ変数は配列のようにも使える
配列宣言の[] : 要素数を指定する
配列の要素を使う時の[] : 配列名のアドレスに足し算する演算子
(*同様,別記号)
int main(void)
{
    int *data;
    int i, avarage = 0, array[10] = {1,2,3,4,5,6,7,8,9,10};

    data = array; //ポインタ変数にはいれつの先頭アドレスを代入

    for(i = 0; i < 10; i++) {
        // []演算子は配列名の先頭アドレスからの足し算
        avarage += data[i]; // よって配列のように扱える
    }

    printf("%d\n", avarage / 10); // 5
    return 0;
}