■ちょっと進んだ内容

Last modified: Mon April 03 2017
このページは,基礎工学部システム科学科機械科学コース2年生向けの 「コンピュータ基礎演習」における演習1の教材の1つです.

●文字列定数とポインタ

プログラム中に文字列定数(""で囲まれた文字列)を書くと, それを格納する領域が用意され,値としてその領域の先頭のアドレスを持つ. その値をポインタ変数に代入することができる. ただし,その領域の内容を書き換えることはできない. 変数の宣言部におけるポインタ変数の初期値の設定としても, 文字列定数を使うことができる.

    char *s1 = "abc";   → 初期値の設定
    char *s2;

    s2 = "ABC";        → 文字列定数の先頭アドレスの代入
    *s1 = 'x';         → 不可
    s2[2] = 'y';       → 不可
配列の初期値の設定と混同しないように.
    char a1[] = "abc"; → 初期値の設定
    char a2[10];

    a2 = "ABC";        → 不可
    *a1 = 'x';         → 要素の書き換えは可能
    a2[2] = 'y';       → 要素の書き換えは可能

●ポインタ配列

ポインタを要素とする配列を作ることができる.

    型名 *変数名[要素数];

    (例)
    char *pa[100];
アクセスする場合は,pa[12][34]と2次元配列のようにも書くことができるが, 2次元配列とは領域の確保のされ方が全く異なる.以下の具体例で比較しよう.

例1-8 example18.c

文字型のポインタ配列の例.

●記憶領域を動的に確保する

C言語では,変数に割り当てられるメモリ上の領域の大きさは, あらかじめ決まっていないといけない. 例えば,配列の要素数を,ある時には100, ある時には1000というような割り当て方はできない.

それでは不便なので,標準ライブラリには,OSの助けを借りて, 実行時に記憶領域を指定した量だけ割り当てる関数malloc()が用意されている.

    ポインタ変数 = malloc(割り当てに必要なバイト数);
という使い方をする.戻り値は割り当てられた記憶領域の先頭アドレス. 割り当てに失敗した場合はNULLを返す.

割り当てるばかりでは,メモリをどんどん消耗してしまうので, その領域が不要になったら,解放する.そのためには,関数free()を使う.

    free(mallocした時の先頭アドレス);
malloc()で割り当てた先頭アドレス以外を引数にした場合は, 正しく処理されない. また,解放された領域がどのようにリサイクルされるかは, ライブラリ任せであり,ユーザの関知するところではない.

malloc()やferr()を使う場合は, 必ず標準のヘッダファイルstdlib.hを#includeする.

    (例)
    #include <stdlib.h>
    (中略)
    int    *pi;
    double *pd;

    pi = malloc(sizeof(int));        → int型1個分の領域を確保.
    pd = malloc(sizeof(double)*10);  → double型10個分の領域を確保.

    *pi = 100;
    pd[3] = 3.14;

    free(pi);
    free(pd);

例1-9 example19.c

可変な人数分の点数を入力し,その平均値と標準偏差を計算する. 情報処理演習で配列を習ったときの例によく似ているが, プログラムの中で配列を使っていない(配列流のアクセスの記述は使っている). プログラムが実行されてから, 必要な人数分の記憶領域をmalloc()を使って確保する. 1組の計算が終了したら,確保された領域を解放し,処理を繰り返している. 試しに人数に非常に大きな数を指定してみよう.


[演習1のインデックス] [前の教材(文字列)] [次の教材(補足(1):C言語におけるポインタの役割)]
hirai@me.es.osaka-u.ac.jp