サイトマップ / C言語講座>出入り口>総目次>目次:ポインタ>ポインタの型と初期化
/* 今日から 23 回連続でポインタの話が続きます。ポインタを理解することは、Cをマスターする上で大きな障壁と言われています。ポインタを使いこなすことができれば、Cをマスターできる可能性が大です。
重要:メモリはアドレスで管理されています。データにアクセスするにはそのデータのアドレスにアクセスすれば良いわけです。そのアドレスを保持している変数がポインタです。
上記はそれぞれのデータ型を指すのに用いられます。ソースプログラム中にある ”int *b;”はbがint型のポインタであることを宣言しています。ポインタを宣言するには変数名の前に'*'を付けます。
    a = 7;
    b = &a;
int型の変数aに 7 を代入し、aのアドレスをbに代入しています。bはaのアドレスを指しているので、その中身はaの値です。'&a'はaのアドレスのことです。
このような操作をポインタの初期化といいます。初期化していないポインタはメモリのどこを指しているかわかりません。初期化していないポインタを通してデータの読み込み書き込みを行ってはいけません。最悪の場合、システムがクラッシュして暴走してしまいます。
最重要:初期化していないポインタを通してデータを読み書きしてはならない。
ポインタを指すポインタは何に使われるかというと、ポインタは変数の配列と密接な関係があり、2次元配列を指すのに使用されます。
    int ***d;
上記のコードはポインタを指すポインタを指すポインタになります。このようなポインタを使うことは少ないかも知れません。
    char *s;
sはchar型のポインタです。ソースプログラムの終わりの方に、次の表現があります。
    s = str;
strは配列の名前です。配列の名前は配列の先頭要素のアドレスを指しています。
s はchar型のポインタとして宣言されているので、strのアドレスをsに代入しているわけです。strはアドレスを指しているので、&は不要です。
ポインタの指す中身を見るには'*'を付けます。下記のコードで、ポインタcの指している中身を表示します。
    printf("%c", *c);
ソースプログラムの説明はコメントを沢山入れておいたので省略します。 */
#include <stdio.h>
void main(void);
void main(void)
{
    int a;           /* int 型の変数 */
    int *b;          /* int 型の変数へのポインタ */
    int **c;         /* int 型のポインタへのポインタ */
    int ***d;        /* int 型のポインタへのポインタへのポインタ */
    char *s;         /* char 型の変数へのポインタ */
    char str[ ] = "abcd";
    a = 7;         /* a に 7 を代入 */
    b = &a;        /* a のアドレスを b に代入 */
    c = &b;        /* b のアドレスを c に代入 */
    d = &c;        /* c のアドレスを d に代入 */
      /* 実行結果と見比べて下さい */
    printf("a=%d\t*b=%d\t**c=%d\t***d=%d\n\n", a, *b, **c, ***d);
    s = str;        /* 配列の名前は配列の先頭の要素のアドレスを指す */
                    /* s は "abcd" の 'a' を指す */
    printf("str[ ] = \"abcd\";\n");        /* '\"' で " を表示 */
    while (*s != '\0') {                   /* 文字列の末尾まで */
        printf("*s = %c\n", *s);           /* s の指している中身を表示 */
        printf("s++;\n");                  /* 次の行を表示 */
        s++;                               /* ポインタの指す場所を 1 進める */
    }
}
    | 
  
/* 今日は、ポインタへのポインタが出て来ました。下記の式は何をしているのでしょうか。
    x***y;
    x+++y;
文法的には正しくても何をしようとしているかわかりません。人間にとっても、コンパイラにとってもわかりにくいコードです。
    x * **y;
    x * (**y);
    x++ + y;
    x + ++y;
    (x++) + y;
    x + (++y);
スペースを入れるか、もっと明示的にカッコを使いましょう。 */
/* (C) 2000- YFプロ. All Rights Reserved. */ 提供:C言語講座−それ自体コンパイルできる教材を使った講座です−