趣味の開発ノート

ITの学習やプログラミング・ノーコードアプリ開発のことなど。

【C言語】int型変数・int型配列変数とポインタの出力値についてまとめ

C言語について学習し始めて、ポインタ周りで苦戦している。

今回は、int型変数とint型の配列変数を作成してみて、それぞれいろいろな表記を行ってみて何を指し示しているのかを整理してみた。

変数定義

このようにint型変数・int型の配列変数と、それぞれのポインタ変数を定義。

▼変数定義

int val = 100
int *p_val = &val;

int numbers[5] = {10, 20, 30, 40, 50};
int *p_numbers = numbers;

いろいろな出力値

いろいろな出力値をまとめた。
(出力例のポインタ値は実行環境によって変わる。)

▼変数valについての出力いろいろ

表記例 表記方法 出力例 解説
val 変数名のみ 100 通常値
&val 変数名にアドレス演算子 0x16b1ff5f8 ポインタ値
(*val) 変数名に間接参照演算子 エラー (間接参照演算子はポインタ変数にしか使えない)


ポインタ変数p_valについての出力いろいろ

表記例 表記方法 出力例 解説
p_val 変数名のみ 0x16b1ff5f8 ポインタ値
&p_val 変数名にアドレス演算子 0x16d11b5f0 ポインタのポインタ値
*p_val 変数名に間接参照演算子 100 元の値


配列変数numbersについての出力いろいろ

表記例 表記方法 出力例 解説
numbers 配列変数名のみ 0x16b1ff600 ポインタ値
&numbers 配列変数名にアドレス演算子 0x16ee8b600 先頭要素のポインタ値
*numbers 配列変数名に間接参照演算子 10 先頭要素の値
numbers[0] 配列変数名に添字0 10 先頭要素の値
numbers[3] 配列変数名に添字i 40 i番目の要素の値
&numbers[0] 配列変数名に添字0とアドレス演算子 0x16bc2f600 先頭要素のポインタ値
&numbers[3] 配列変数名に添字iとアドレス演算子 0x16bc2f60c i番目の要素のポインタ値
*numbers[0] 配列変数名に添字0と間接参照演算子 10 先頭要素の値
*numbers[3] 配列変数名に添字iと間接参照演算子 40 i番目の要素の値


ポインタ変数p_numbersについての出力いろいろ

表記例 表記方法 出力例 解説
p_numbers ポインタ変数名のみ 0x16b1ff600 ポインタ値
&p_numbers ポインタ変数名にアドレス演算子 0x16bc2f60c 先頭要素のポインタのポインタ値
*p_numbers ポインタ変数名に間接参照演算子 10 先頭要素の値
p_numbers[0] ポインタ変数名に添字0 10 先頭要素の値
p_numbers[3] ポインタ変数名に添字i 40 i番目の要素の値
&p_numbers[0] ポインタ変数名に添字0とアドレス演算子 0x16bc2f600 先頭要素のポインタ値
&p_numbers[3] ポインタ変数名に添字iとアドレス演算子 0x16bc2f60c i番目の要素のポインタ値
*p_numbers[0] ポインタ変数名に添字0と間接参照演算子 10 先頭要素の値
*p_numbers[3] ポインタ変数名に添字iと間接参照演算子 40 i番目の要素の値

サンプルコード

▼いろいろな出力を実験

#include <stdio.h>

int main()
{
    /* 変数の定義と初期化 */
    int val = 100;
    int numbers[5] = {10, 20, 30, 40, 50};

    /* ポインタ変数の定義と初期化:変数名の先頭に*をつけるとポインタ型を示す(ポインタ定義の*) */
    int *p_val = &val; // 変数名の先頭に&を使うと、その変数のポインタ値を示す(アドレス演算子&)
    int *p_numbers = numbers; // 配列変数の時は、添字なしの変数名がその変数の先頭のポインタ値を示す

    /* 値渡しと参照渡し */
    // 値渡し:通常の関数定義のとき
    int myfunction01(int val);

    // 参照渡し:関数の仮引数にポインタ型を指定したいときはこのポインタ定義の*を使って渡す
    int myfunction02(int *val, int *numbers);

    

    /* 変数valについての出力いろいろ */
    printf("変数名のみ(通常値) val = %d\n", val); // 100
    printf("変数名にアドレス演算子(ポインタ値) &val = %p\n", &val); // 0x16b1ff5f8
    // printf("変数名に間接参照演算子() *val = %d\n", *val); // エラー

    /* ポインタ変数p_valについての出力いろいろ */
    printf("ポインタ変数名のみ(ポインタ値) p_val = %p\n", p_val); // 0x16b1ff5f8
    printf("ポインタ変数名にアドレス演算子(ポインタのポインタ値) &p_val = %p\n", &p_val); // 0x16d11b5f0
    printf("ポインタ変数名に間接参照演算子(元の値) *p_val = %d\n", *p_val); // 100

    /* 配列変数numbersについての出力いろいろ */
    printf("配列変数名のみ(先頭要素のポインタ値) numbers = %p\n", numbers); // 0x16b1ff600
    printf("配列変数名にアドレス演算子(先頭要素のポインタ値) &numbers = %p\n", &numbers); // 0x16ee8b600
    printf("配列変数名に間接参照演算子(先頭要素の値) *numbers = %d\n", *numbers); // 10
    printf("配列変数名に添字0(先頭要素の値) numbers[0] = %d\n", numbers[0]); // 10    
    printf("配列変数名に添字i(要素の値) numbers[3] = %d\n", numbers[3]); // 40
    printf("配列変数名に添字0とアドレス演算子(先頭要素のポインタ値) &numbers[0] = %p\n", &numbers[0]); // 0x16bc2f600
    printf("配列変数名に添字iとアドレス演算子(i番目の要素のポインタ値) &numbers[3] = %p\n", &numbers[3]); // 0x16bc2f60c
    printf("配列変数名に添字0と間接参照演算子(先頭要素の値) *numbers[0] = %d\n", p_numbers[0]); // 10 
    printf("配列変数名に添字iと間接参照演算子(i番目の要素の値) *numbers[3] = %d\n", p_numbers[3]); // 40

    /* ポインタ変数p_numbersについての出力いろいろ */
    printf("ポインタ変数名のみ(ポインタ値) p_numbers = %p\n", p_numbers); // 0x16b1ff600
    printf("ポインタ変数名にアドレス演算子(先頭要素のポインタのポインタ値) &p_numbers = %p\n", &p_numbers); // 0x16ee8b600
    printf("ポインタ変数名に間接参照演算子(先頭要素の値) *p_numbers = %d\n", *p_numbers); // 10
    printf("ポインタ変数名に添字0(先頭要素の値) numbers[0] = %d\n", p_numbers[0]); // 10    
    printf("ポインタ変数名に添字i(要素の値) numbers[3] = %d\n", p_numbers[3]); // 40
    printf("ポインタ変数名に添字0とアドレス演算子(先頭要素のポインタのポインタ値) &p_numbers[0] = %p\n", &numbers[0]); // 0x16ee8b600
    printf("ポインタ変数名に添字iとアドレス演算子(i番目の要素のポインタのポインタ値) &p_numbers[3] = %p\n", &numbers[3]); // 0x16ee8b60c
    printf("ポインタ変数名に添字0と間接参照演算子(先頭要素の値) *p_numbers[0] = %d\n", p_numbers[0]); // 10 
    printf("ポインタ変数名に添字iと間接参照演算子(i番目の要素の値) *p_numbers[3] = %d\n", p_numbers[3]); // 40

    return 0;
}