第3回:ポインタ入門


 今週は,C言語を学習する上でもっとも挫折することの多い,でも,C言語のもっともC言語らしいところである,ポインタについて取り上げます.


【先週の演習】

キーボードから文字列を入力すると,何文字入力されたかを画面に表示するプログラムを作成する.

ヒント:文字列の終わりはnull文字で判断する.

[答え]

#include <stdio.h>

void main()
{
    char c[256];
    int i;

    printf("文字列を入力してください:");
    scanf("%s", c);

    for(i=0; c[i] != 0; i++);        /* これで,文字数を数えている.null文字は,0 */

    printf("入力された文字列は,%s で,%d 文字です\n", c, i);       /* なぜ,i が文字数なのか */
}


 ポインタの前に,ウォーミングアップとして アドレス について復習します.


アドレスとは?

 変数や配列は,コンピュータのメモリ上にあります.このメモリには,アドレスという連続した番号がついていて,管理されています.

 では,ある変数の使っているメモリのアドレスを調べるには,どうしたらよいでしょうか.変数名の頭に「&」を付けると,そのデータがしまわれているメモリのアドレスを意味します.

#include <stdio.h>

void main()
{
    int a;
    
    printf("aのアドレスは,%p です\n", &a);
}

 逆にあるアドレスにしまわれている値を調べるには,どうしたらよいでしょうか?


ポインタ変数とは?

データのメモリアドレスを指し示す(ポイントする)ための変数のことをポインタ変数と呼びます.

ポインタ変数の値 = メモリアドレス

  参考 : 普通の変数の値 = 数値や文字


ポインタ変数の基本的な書式

int *p;
ポインタ変数の宣言.型を指定し,変数名の前に*をつける
p = &a;
ポインタ変数pにはint型変数aのアドレスが入る.ポインタ変数にアドレスを入れるには,対象となる変数の前に&をつける
b = *p;
ポインタ変数に格納されているアドレスに格納されているを取り出すには,ポインタ変数の前に*をつける

例:

#include <stdio.h>

void main()
{
    int a, b;
    int *p;

    a = 3;
        printf("aのアドレスは,%p です\n", &a);  
    p = &a;
        printf("ポインタ変数の値(アドレス)は,%p です\n", p);  
        printf("ポインタ変数のさしている値は,%d です\n", *p);  
    p++;
        printf("ポインタ変数を一つ増やすと,%p です\n", p);
}

値「3」が格納された変数aと,ポインタ変数pを宣言し,pに変数aのアドレスを代入する.

次に,変数pの値(アドレス)と,そのアドレスに格納されている値を表示する.

さらに,アドレスを一つ増やしたアドレスを表示する.


いろいろな型の変数のアドレスを調べよう.

#include <stdio.h>
void main()
{
    int a, b;
    double x, y;
    char c, d;
    int e[3];

    printf("%p %p\n", &a, &b);
    printf("%p %p\n", &x, &y);
    printf("%p %p\n", &c, &d);
    printf("%p %p %p\n", &e[0], &e[1], &e[2]);
}

どのような,結果になったかな?この結果から,各型がメモリ上でどれくらいの大きさかがわかる.


配列とポインタの関係

配列は,メモリの連続した区間を使っています.ポインタを使って,配列の要素を扱ってみましょう.

 例を見てみましょう.

#include <stdio.h>

void main()
{
    int a[5] = {10, 20, 30, 40, 50};   /* 配列 */
    int b;
    int *p;   /* ポインタ変数 */

    p  =  &a[0];          /* 配列の先頭のアドレスを代入する */ 

    printf("配列aの先頭のアドレスは,%p です\n", p);
    printf("pのさしている値は,%d です\n", *p);

    p += 2;    /* pは,先頭から2つ先をさします */
    printf("a[2]の中身は,%d です\n", *p);

    b = *(p-1); 
    printf("bの中身は,%d です\n", b);  
}

今日の演習

【1】

変数a,bに数字をキーボードから入力し,a+bを求めて表示するプログラムをポインタ変数を使って書き換えよ.

元になるプログラム:

#include <stdio.h>

void main()
{
    int a, b;

    scanf("%d", &a);
    scanf("%d", &b);

    printf("a + b = %d\n", a+b);
}

書き換えるプログラム:

#include <stdio.h>

void main()
{
    int a,b;
    int *pa,*pb;

    pa = &a;
    pb = &b;

    scanf("%d",?????);
    scanf("%d",?????);

    printf("a + b = %d\n",?????????);
}

【2】

整数型配列に初期値として,(10,20,30,40,50)を設定したとき,全ての要素の値を表示するプログラムをループとポインタを用いて作成しなさい.


プログラムには必ず,学年,組,番号,氏名を記入すること.