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

プログラミング演習

N/A
N/A
Protected

Academic year: 2021

シェア "プログラミング演習"

Copied!
23
0
0

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

全文

(1)

プログラミング演習

プログラミング演習

IIII

20042004

年 年

1111

月 月

22

日(第 日(第

33

回) 回)

理学部数学科・木村巌

理学部数学科・木村巌

(2)

前回までの復習 前回までの復習

関数の宣言 関数の宣言

複数のファイルからなるプログラム 複数のファイルからなるプログラム

複数のファイルからなるプログラムでの 複数のファイルからなるプログラムでの スコープ スコープ

標準ライブラリ関数とは何か 標準ライブラリ関数とは何か

標準ライブラリ関数の使い方 標準ライブラリ関数の使い方

(3)

今日学ぶこと 今日学ぶこと

メモリとアドレス メモリとアドレス

ポインタ変数 ポインタ変数

アドレス演算子 アドレス演算子

&, &,

間接参照演算子 間接参照演算子

**

ポインタを引数とすることで、呼び出し ポインタを引数とすることで、呼び出し 元の実引数を変更できる

元の実引数を変更できる

constconst

を仮引数に付けることで、実引数の を仮引数に付けることで、実引数の 変更を抑制できる

変更を抑制できる

教科書 教科書

9.19.1

から( から(

p. 272p. 272

~) ~)

(4)

アドレスって?

アドレスって?

変数の値は、コンピュータの「メモリ」 変数の値は、コンピュータの「メモリ」

に記憶される に記憶される

メモリには、 メモリには、

1616

進表記で通し番号が振ら 進表記で通し番号が振ら れている れている

この通し番号を、 この通し番号を、 アドレス( アドレス(

addressaddress

)と )と

いう いう

(5)

変数のアドレスを見る 変数のアドレスを見る

変数が格納されているメモリのアドレス 変数が格納されているメモリのアドレス をしるには、

をしるには、 アドレス演算子 アドレス演算子

&&

を使う を使う

アドレス演算子の使い方 アドレス演算子の使い方

&

&

変数名 変数名

例えば、 例えば、

aa

が が

intint

型の変数なら、そのアド 型の変数なら、そのアド レスは レスは

&a &a

で知ることが出来る で知ることが出来る

アドレスを端末に表示するには、 アドレスを端末に表示するには、

%p %p

書 書 式指定子を使う(

式指定子を使う(

Sample1.cSample1.c

を打ち込んで を打ち込んで

、コンパイル・実行してみよう)

、コンパイル・実行してみよう)

(6)

アドレスは、メモリ上の位置 アドレスは、メモリ上の位置

アドレス演算子を使うと、変数 アドレス演算子を使うと、変数

aa

の値が、 の値が、

メモリ上のどの位置に記憶されているか メモリ上のどの位置に記憶されているか

、が分かる

、が分かる

Sample1.cSample1.c

で、さらに で、さらに

intint

型の変数 型の変数

b, cb, c

を追 を追 加し、それらのアドレスも表示させてみ 加し、それらのアドレスも表示させてみ よ。 よ。

気がつくことがあるか? 気がつくことがあるか?

(7)

ポインタ ポインタ

アドレスを格納する変数を、 アドレスを格納する変数を、 ポインタ型 ポインタ型 の変数 の変数 という という

ポインタ型の変数の事を、単にポインタ ポインタ型の変数の事を、単にポインタ ということも多い

ということも多い

ポインタ型の変数の使い方は、これまで ポインタ型の変数の使い方は、これまで 学んできた、他の型の変数と同じ

学んできた、他の型の変数と同じ

(8)

ポインタの宣言 ポインタの宣言

型名 型名

**

ポインタ変数名 ポインタ変数名

;;

ポインタ変数であることが分かるような名 ポインタ変数であることが分かるような名 前を付けることも多い

前を付けることも多い

例: 例:

int *pA;

int *pA;

int *Aptr; /*

int *Aptr; /*

どちらも どちらも

intint

型へのポインタ 型へのポインタ

*/*/

変数名はあくまで 変数名はあくまで

pApA

と と

AptrAptr

Sample2.cSample2.c

を入力し、コンパイル・実行し を入力し、コンパイル・実行し

てみよう てみよう

(9)

ポインタ変数にアドレスを代入 ポインタ変数にアドレスを代入

Sample2.cSample2.c

の の

pA = &a;

pA = &a;

という行は、ポインタ変数 という行は、ポインタ変数

pApA

に、 に、

intint

型 型 の変数 の変数

aa

のアドレスを代入している のアドレスを代入している

pApA

には、例えば には、例えば

0x22ef3c 0x22ef3c

といった値が入 といった値が入 る る

「 「

pApA

は は

aa

を指すポインタ」などという を指すポインタ」などという

(10)

ポインタから変数の値を知る ポインタから変数の値を知る

ポインタ変数の値(つまり、別の変数のアド ポインタ変数の値(つまり、別の変数のアド レス)から、元の変数の値を知ることが出来 レス)から、元の変数の値を知ることが出来 る る

間接参照演算子 間接参照演算子

**

をつかう をつかう

** ポインタ変数名ポインタ変数名 ;;

例: 例:

pApA

が が

intint

型の変数 型の変数

aa

のアドレスを格納し のアドレスを格納し たポインタ変数なら、

たポインタ変数なら、

aa

の値は、 の値は、

*pA /*

*pA /*

これは これは

intint

型 型

*/*/

Sapmle3.cSapmle3.c

を入力し、コンパイル・実行してみ を入力し、コンパイル・実行してみ

よう よう

(11)

ポインタについて整理する ポインタについて整理する

aa

変数 変数

aa

&a

&a

変数 変数

aa

のアドレス のアドレス

pApA

変数 変数

aa

のアドレスを格納したポイン のアドレスを格納したポイン タ変数 タ変数

*pA*pA

変数 変数

aa

のアドレスを格納したポイン のアドレスを格納したポイン タ変数が指している変数

タ変数が指している変数

== ==

変数 変数

aa

(12)

ポインタに別のアドレスを代入す ポインタに別のアドレスを代入す

る る

ポインタ変数とは、アドレスを格納する変数 ポインタ変数とは、アドレスを格納する変数

普通の変数と同じく、プログラムの途中で、 普通の変数と同じく、プログラムの途中で、

ポインタ変数の値を変更することが出来る ポインタ変数の値を変更することが出来る

ただし、 ただし、

intint

型を指すポインタ変数には、 型を指すポインタ変数には、

intint

型の変数のアドレスしか格納できない

型の変数のアドレスしか格納できない

Sample4.cSample4.c

を入力し、コンパイル・実行して を入力し、コンパイル・実行して

みよう みよう

(13)

初期化されていないポインタ変 初期化されていないポインタ変

数 数

ポインタ変数は、宣言しただけでは使え ポインタ変数は、宣言しただけでは使え ない ない

特定の変数のアドレスを代入し、初期化 特定の変数のアドレスを代入し、初期化 しなければならない

しなければならない

初期化していないポインタ変数を使うと 初期化していないポインタ変数を使うと

、ゴミが表示されたり、実行時エラーに

、ゴミが表示されたり、実行時エラーに なったりする(どのような挙動を示すか なったりする(どのような挙動を示すか

は、予言できない

は、予言できない

(14)

ポインタを使って変数を変更 ポインタを使って変数を変更

Sample5.cSample5.c

を入力し、コンパイル・実行し を入力し、コンパイル・実行し てみよう てみよう

pApA

が が

intint

型を指すポインタ変数の時、 型を指すポインタ変数の時、

*p*p AA

は は

intint

型.よって、 型.よって、

*pA = 50; *pA = 50;

のように のように

、代入できる

、代入できる

この仕組みを使って、関数に引数を渡す この仕組みを使って、関数に引数を渡す と、面白い応用がある

と、面白い応用がある

(15)

引数とポインタ 引数とポインタ

intint

型の 型の

22

つの値を つの値を 交換する関数

交換する関数

void svoid s wap (int x, int y)

wap (int x, int y)

を を 書きたい 書きたい

→ → は思った通りに は思った通りに は動かない

は動かない

void swap (int x, int y) void swap (int x, int y) {{

int tmp;

int tmp;

tmp = x;

tmp = x;

x = y;

x = y;

y = tmp;

y = tmp;

}}

(16)

なぜ前の なぜ前の

swap()swap()

は動かないのか? は動かないのか?

Sample6.cSample6.c

を入力し、コンパイル・実行して を入力し、コンパイル・実行して みよう→思ったように値が交換されない

みよう→思ったように値が交換されない

関数の引数には、変数の 関数の引数には、変数の 値のコピーが渡さ 値のコピーが渡さ れる れる

これを、値渡し( これを、値渡し(

pass by valuepass by value

)とか、値 )とか、値 呼び( 呼び(

call by valuecall by value

)とかいう )とかいう

コピーを交換しても、元の変数には影響が コピーを交換しても、元の変数には影響が

及ばない 及ばない

(17)

ポインタを使って解決 ポインタを使って解決

仮引数をポインタ 仮引数をポインタ 変数とする

変数とする

→ → 参照 参照

Sample7.cSample7.c

を入力し を入力し

、コンパイル・実

、コンパイル・実 行してみよう

行してみよう

void

swap (int *pX, int *pY) {

int tmp;

tmp = *pX;

*pX = *pY;

*pX = tmp;

}

(18)

ポインタを使って解決(続)

ポインタを使って解決(続)

前のスライドを 前のスライドを

swap()swap()

を使う。 を使う。

引数として、 引数として、

&num1, &num2&num1, &num2

のように、変数 のように、変数 のアドレスを渡す

のアドレスを渡す

仮引数は、 仮引数は、

&num1&num1

と と

&num2&num2

で初期化される で初期化される

pX = &num1; pY = &num2;pX = &num1; pY = &num2;

*pX = num1; *pY = num2;*pX = num1; *pY = num2;

これらが入れ替えられると、 これらが入れ替えられると、

num1, num2num1, num2

その その ものが入れ替えられる

ものが入れ替えられる

参照渡し( 参照渡し(

pass by referencepass by reference

) )

(19)

実引数を変更したくない場合 実引数を変更したくない場合

constconst

という指定で、ポインタがさす実引 という指定で、ポインタがさす実引 数を変更できなくなる

数を変更できなくなる

void func (const int *pX); void func (const int *pX);

というプロトタイ というプロトタイ プ宣言をみると、この関数は

プ宣言をみると、この関数は

pXpX

が指す変 が指す変 数を変更しないことがわかる

数を変更しないことがわかる

同時に、 同時に、

func()func()

を作成する際に、誤って を作成する際に、誤って

pp XX

が指す変数を変更してしまっても、コ が指す変数を変更してしまっても、コ

ンパイラがその誤りを指摘してくれる

ンパイラがその誤りを指摘してくれる

(20)

今日学んだこと 今日学んだこと

メモリとアドレス メモリとアドレス

ポインタ変数 ポインタ変数

アドレス演算子 アドレス演算子

&, &,

間接参照演算子 間接参照演算子

**

ポインタを引数とすることで、呼び出し ポインタを引数とすることで、呼び出し 元の実引数を変更できる

元の実引数を変更できる

constconst

を仮引数に付けることで、実引数の を仮引数に付けることで、実引数の 変更を抑制できる

変更を抑制できる

(21)

レポート課題 レポート課題

void mod (int *pA, int *pM) void mod (int *pA, int *pM)

というプロト というプロト タイプを持つ関数

タイプを持つ関数

mod()mod()

は、 は、

*pA*pA

を を

(*p(*p A) % (*pM)

A) % (*pM)

に置き換える.キーボードか に置き換える.キーボードか ら ら

intint

型の値 型の値

aa

と と

mm

を入力し、次のよう を入力し、次のよう

に出力するプログラムを作成せよ:

に出力するプログラムを作成せよ:

ヒントは教科書 ヒントは教科書

p. 298p. 298

の練習問題 の練習問題

3.3.

(22)

レポート課題(続)

レポート課題(続)

input a and m:

input a and m:

77

(ユーザの入力) (ユーザの入力)

55

(ユーザの入力) (ユーザの入力)

7 modulo 5 = 2 modulo 5.

7 modulo 5 = 2 modulo 5.

(23)

レポート課題(続)

レポート課題(続)

締め切り: 締め切り:

20042004

年 年

1111

月 月

88

日一杯(日本 日一杯(日本 時間で) 時間で)

提出:メールで木村( 提出:メールで木村(

iwao@sci.toyama-u.ac.jp

iwao@sci.toyama-u.ac.jp

)まで. )まで.

感想などあると木村が喜びます 感想などあると木村が喜びます

参照

関連したドキュメント

c加振振動数を変化させた実験 地震動の振動数の変化が,ろ過水濁度上昇に与え る影響を明らかにするため,入力加速度 150gal,継 続時間

その次の段階は、研磨した面を下向きにして顕微鏡 観察用スライドグラスに同種のエポキシ樹脂で付着 させ、さらにこれを

(1)〈添加・例示・提題などをあらわすもの〉では、A〈添加〉L「風三二」の「さ

昭33.6.14 )。.

 我が国における肝硬変の原因としては,C型 やB型といった肝炎ウイルスによるものが最も 多い(図

つの表が報告されているが︑その表題を示すと次のとおりである︒ 森秀雄 ︵北海道大学 ・当時︶によって発表されている ︒そこでは ︑五

QRコード読込画面 が表示されたら、表 示された画面を選択 してウインドウをアク ティブな状態にした 上で、QRコードリー

現行の HDTV デジタル放送では 4:2:0 が採用されていること、また、 Main 10 プロファイルおよ び Main プロファイルは Y′C′ B C′ R 4:2:0 のみをサポートしていることから、 Y′C′ B