このことを具体例をつかって,説明しよう.リスト7のプログ
ラムでは,pがポインター変数でhogeがオブジェクトである.この関係は図
1のように表すことができる.
1 #include <stdio.h>
2
3 int main(void)
4 {
5 int hoge=3;
6 int *p;
7
8 p=&hoge;
9
10 printf("hoge=%d\n",*p);
11
12 return 0;
13 }
hoge=3
このような結果が得られるのは,リスト7の10行目でポインター pがhogeを指し示すからである.オブジェクトとポインターの関係は8行目で hogeで決められている; オブジェクトの先頭アドレス3 をポインター変数に代入している.
1 #include <stdio.h>
2
3 int main(void)
4 {
5 typedef struct{ // 構造体の定義
6 char name[16];
7 int math;
8 int info;
9 }student;
10
11 student yama={"yamamoto",72,83}; // 宣言と初期化
12 student *p; // 構造体 student 型へのポインター
13
14 p=&yama; // 先頭アドレスの代入
15
16 printf("name = %s\n", p->name); // メンバーへのアクセスは,アロー演算子
17 printf("math = %d\n", p->math);
18 printf("info = %d\n", p->info);
19
20 return 0;
21 }
name = yamamoto math = 72 info = 83
1 #include <stdio.h>
2
3 int add(int i, int j); // プロトタイプ選言
4
5 //============ メイン関数===============================
6 int main(void)
7 {
8 int (*fp)(int, int); // 関数へのポインター
9
10 fp=add; // 関数のアドレスを代入
11
12 printf("%d\n",fp(5,9));
13
14
15 return 0;
16 }
17
18 //============ ユーザー定義関数==========================
19 int add(int i, int j)
20 {
21 return i+j;
22 }
14
これは使い方によってはかなり便利である.サブルーチンへ関数を渡すことが可能となる. リスト10がそれを使った例である.ここで,関数定義の仮引数の double (*f)(double)が関数へのポインターの宣言で,
戻り値の型 (*関数へのポインター変数)(引数の型)と書く.この関数へのポインター変数に関数のポインター--先頭アドレス--を代入する と,ポインター変数が関数のように使える.関数のポインターへの代入は関数名を右辺値 として,代入するだけである.
1 #include <stdio.h>
2 #include <math.h>
3
4 void print_func(double (*f)(double)); // プロトタイプ選言
5
6 //======== メイン関数 ========================================
7 int main(void)
8 {
9
10 print_func(sin);
11 print_func(cos);
12
13 return 0;
14 }
15
16 //========== 関数の値を表示する関数 ============================
17 void print_func(double (*f)(double))
18 {
19 int i;
20 double dx=0.1;
21
22 printf("--------------------------\n");
23 for(i=0; i<=5; i++){
24 printf("%f\t%f\n", i*dx, f(i*dx));
25 }
26 }
-------------------------- 0.000000 0.000000 0.100000 0.099833 0.200000 0.198669 0.300000 0.295520 0.400000 0.389418 0.500000 0.479426 -------------------------- 0.000000 1.000000 0.100000 0.995004 0.200000 0.980067 0.300000 0.955336 0.400000 0.921061 0.500000 0.877583
1 #include <stdio.h>
2
3 int main(void)
4 {
5 char *animal[]={"cat", "dog", "rabbit", "horse"};
6
7 printf("1st : %s\n", animal[0]);
8 printf("2nd : %s\n", animal[1]);
9 printf("3rd : %s\n", animal[2]);
10 printf("4th : %s\n", animal[3]);
11
12 return 0;
13 }
1st : cat 2nd : dog 3rd : rabbit 4th : horse
C言語では大雑把に言って,コード(code)、データ(data)、ヒープ(heap)、スタック (stack)の4つの領域にメモリーを分けて,管理する.これらの使い分けに,プログラマー はほとんど気にする必要はない.ただし,変数--配列や構造体を含む--を使う場合, メモリーは次のような使い方があると,プログラマーは認識しておくべきである. -4pt
大きな配列を使いたい場合,ヒープ領域をつかう.malloc()関数によりメモリーを
確保して,free()関数によりメモリーを開放する.その例をリスト
12に示す.
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main(void)
5 {
6 int *a;
7
8 a=malloc(sizeof(int)*1024*1024*10);
9
10 a[0]=1;
11 printf("a[0]=%d\n",a[0]);
12
13 free(a);
14
15 return 0;
16 }
a[0]=1malloc()関数を使って,メモリーを確保している.ただし,この関数でいつも思い 通りのメモリーを確保できるとは限らない.この関数は,メモリー確保に失敗した場合,NULLポ インターを返す.