• 検索結果がありません。

第 10 章 「ポインタ」のまとめ

N/A
N/A
Protected

Academic year: 2021

シェア "第 10 章 「ポインタ」のまとめ"

Copied!
4
0
0

読み込み中.... (全文を見る)

全文

(1)

10 章 「ポインタ」のまとめ

10.1 用語のまとめ

教p.226 関数の引数 (復習)C言語の関数呼出しは である。つまり、ふつうは関数の中で呼出し

側の変数を変更することはできない。

教p.227 アドレス C言語の変数には(register変数などの例外を除き)メモリ上の (address)

がある。

教p.228 アドレス演算子 単項 演算子を変数(や配列の要素など=演算子の左辺に置けるもの)に適用する

と、そのアドレスが得られる。単項&演算子は とも呼ばれる。

アドレスをprintfで出力するときの書式指定は%pである。

教p.229 ポインタ アドレスを変数に格納することができる。このような変数を という。ポイン

タ型の変数の宣言は*を変数名の前につける。

int sato = 178;

int *isako;

isako = &sato; /* isakoは int型のオブジェクトのアドレスを格納することができる。 */

/* ‘‘isakoはsatoを指す’’という。 */

• isakoはint型のオブジェクトを指すためのポインタ型(“intへのポインタ型”)である。(*の 部分が主でintが従である。)

なお、型の一部であることを強調するために*を型のほうにくっつけて、

int* isako;

のような書き方をすることもある。(意味はまったく変わらない。)

ポインタ変数宣言の*はそれぞれの変数名の前につける必要がある。

int *isako, hiroko; /* isakoはintへのポインタ型、hirokoはint型になる。*/

int* isako, hiroko; /* intのほうに*をくっつけても同じ。

isakoはintへのポインタ型、hirokoはint型になる。*/

int *isako, *hiroko; /* isakoも hirokoもintへのポインタ型になる。*/

プログラミングII授業資料X - 1

(2)

教p.231 間接演算子 ポインタの前に単項 演算子をつけると、それが指すオブジェクトそのもの(ここでは

変数と思って良い)を表す。単項*演算子は とも呼ばれる。

*hiroko = 180; /* hirorkoの指すオブジェクトに180を代入 */

/* この例の場合 masaki = 180と同じ効果を持つ */

教p.232 関数の引数としてのポインタ 関数の引数としてポインタを渡すと、次のようなことが可能になる。

• サイズの大きなデータをコピーせずに受渡しする。

• 呼出し側の変数の値を書き換える。

(C言語の関数の引数は値渡しなので、ポインタを使わなければ、呼出し側の変数の値を書き 換えることはできない。)

複数の値を返す。

教p.216

scanf関数とポインタ scanf関数でint型(%dに対応)や、double型(%lfに対応)を受取ると

き、変数の前に&をつけたのも、 である。

教p.238

ポインタの型 ポインタの型は、それが指すオブジェクトの型と正しく対応しなければならない。

この点は、ポインタのインクリメント・デクリメント(後述)のとき、さらに重要になる。

教p.240

ポインタと配列 ポインタは配列の要素を指すこともできる。

int vc[5] = {10, 20, 30, 40, 50};

int *ptr = &vc[0];

&vc[0]で配列の先頭要素のアドレスを表す。(p.177演算子の一覧表参照)

注意:

• int *ptr = &vc[0]; のようにポインタ変数の宣言と初期化を一度に行う宣言は、

int *ptr;

ptr = &vc[0];

と同じ意味になる。

int *ptr;

*ptr = &vc[0];

ではないので、注意が必要である。

教p.241

• ptr + iは、(配列の要素の型にかかわらず)ptrが指す要素のi個後ろの要素を指すポインタ

になる。

• * (ptr + i)はptr[i]と書くこともできる。(2つの書き方はCではまったく等価である。)

プログラミングII授業資料X - 2

(3)

• []を伴わず現れた配列名は、 と見なされる。(ただし、

sizeofのパラメータとなるときなど、いくつかの例外がある。)

scanfで文字列(%sに対応)を受取るためにcharの配列を渡すとき、&を付けない(教

科書p.212)のは、このためである。

ポインタ同士の比較(==,<,>など)や減算(-)も可能である。

教p.255 ポインタのインクリメント・デクリメント 配列の要素を指すポインタをインクリメント(++)・デ

クリメント(--)すると、それぞれ配列の ・ を指すようになる。

教p.244 配列の受渡し 関数の仮引数の宣言としては、int vc[]とint *vcはまったく同一である。このプ

ログラムの関数int_setの定義は、

void int_set (int *vc, int no, int val) { . . .

}

と書いてもまったく意味は同じである。

ポインタ使用上の注意 以下のプログラムはどこが間違っているか?

1.

#include <stdio.h>

/*--- n1とn2の和・差をsumとdiffに格納 ---*/

void sum_diff(int n1, int n2, int *sum, int *diff) {

*sum = n1 + n2;

*diff = (n1 > n2) ? n1 - n2 : n2 - n1;

}

int main(void) { int na, nb;

int *wa, *sa; /* ← ここを変えた */

puts("二つの整数を入力してください。");

printf("整数A:"); scanf("%d", &na);

printf("整数B:"); scanf("%d", &nb);

sum_diff(na, nb, wa, sa);

printf("和は%dです。Y=n差は%dです。Y=n", *wa, *sa);

return (0);

}

プログラミングII授業資料X - 3

(4)

2.

#include <stdio.h>

int *sum_diff(int n1, int n2) { int ret[2];

ret[0] = n1 + n2;

ret[1] = (n1 > n2) ? n1 - n2 : n2 - n1;

return &ret[0]; /* 先頭要素へのポインタを返す */

}

int main(void) { int na, nb;

int *wasa;

puts("二つの整数を入力してください。");

printf("整数A:"); scanf("%d", &na);

printf("整数B:"); scanf("%d", &nb);

wasa = sum_diff(na, nb);

printf("和は%dです。Y=n差は%dです。Y=n", wasa[0], wasa[1]);

return (0);

}

大抵の場合、問題がないように実行されてしまうので、こういう間違いはすぐに見つかる間違いより タチが悪い。

プログラミングII授業資料X - 4

参照

関連したドキュメント

緒 言  第圏節 第二節 第四章 第一節 第二節 第五章 第口節 第二節第六章第七章

鍵蕊鍵jli篝i識 鑓郷 砕盤饒瀧 》-1壗 ノlj一雄達守らなかった友達悪鯉鞄な瀧

第一章 ブッダの涅槃と葬儀 第二章 舎利八分伝説の検証 第三章 仏塔の原語 第四章 仏塔の起源 第五章 仏塔の構造と供養法 第六章 仏舎利塔以前の仏塔 第二部

2(1)健康リスクの定義 ●中間とりまとめまでの議論 ・第

平成25年3月1日 東京都北区長.. 第1章 第2章 第3 章 第4章 第5章 第6章 第7 章

第1章 生物多様性とは 第2章 東京における生物多様性の現状と課題 第3章 東京の将来像 ( 案 ) 資料編第4章 将来像の実現に向けた

バーチャルパワープラント構築実証事業のうち、「B.高度制御型ディマンドリスポンス実

第五章 研究手法 第一節 初期仮説まとめ 本節では、第四章で導出してきた初期仮説のまとめを行う。