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

Microsoft PowerPoint L07-Imperative Programming Languages-4-students ( )

N/A
N/A
Protected

Academic year: 2021

シェア "Microsoft PowerPoint L07-Imperative Programming Languages-4-students ( )"

Copied!
21
0
0

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

全文

(1)

プログラミング言語論 A

(Concepts on Programming Languages)

趙 建軍

(Jianjun Zhao)

1

命令型言語 (4)

(Imperative Programming Languages)

手続き(関数)の呼び出し

2019.05.30

第7回

(2)

3

今日の講義

手続きとは

手続きの定義

引数渡し

スコープ規則

今日の講義

手続きとは

手続きの定義

引数渡し

スコープ規則

(3)

手続きとは

プログラムの一部に名前を付けるものである

その部分のことを手続きの本体という

手続きが呼ばれると、手続きの本体が実行さ

れる

この手続きの本体の実行のことを手続きのactivation

という

関数 (function)

は、値を返す手続きのことであ

関数、手続きという用語を区別をしないで用いる

場合もある

5

手続きとは

手続き: 一連の処理を行う機能単位

手続き(関数)が名前をつけることができ,

その名前で何度でも

呼び出す

ことができる

名称

言語

サブルーチン(subroutine)

FORTRAN, Basic

手続き(procedure)

Pascal

関数 (function)

C, C++, Go

(4)

手続きとは

手続きの必要性

システムの大規模化、複雑化

要求機能を、より簡素化された複数の機

能に分解し、各々を手続きとして実装す

る。

これらを組み合わせて全体を実現

モジュール化

7

手続きの構文

手続きの定義

手続きにおける引数は

仮引数 (formal parameter)

と呼ばれる

手続き呼び出しにおいて、引数が0個でも括

弧が必須の場合が多い

C, Modula-2など

Pascalでは引数がない場合は括弧を書かない

<

手続き名

>

(

<

仮引数列

>

)

(5)

手続きの構文

手続き呼び出し文の構文

手続き呼び出し文における引数は実引数

(actual parameter)と呼ばれる

<返り値の型名>

<手続き名>

(

<実引数列> )

9

手続きの呼び出し

(6)

関数の戻り値

11

手続き呼び出しの例

int plus(int z, int y) { int d = 0; while (d < y) { z++; d++; } return z; } main() { int z = 0; int c = 0; while (c < y) { z = plus(z, y); c++; } 関数plusの定義(関数宣言) 関数plusの呼出し

(7)

手続きの型

int plus(int z, int y) {

int d = 0; while (d < y) { z++; d++; } return z; } main() { int z = 0; int c = 0; while (c < y) { z = plus(z, y); c++; } }

すべての関数は型を持つ。

関数定義と呼出し側で型が

一致してなければならない

13

値を返さない手続き

値を返さない手続きは以下のように定義する

Java, C, C++: 戻り値を

void

VB:

サブルーチンプロシージャとして定義

void

sample(int x) {

x:= x+1:

printf(“%d¥n”, x);

}

main() {

sample(9);

式として扱われない

(値を評価できない)

(8)

再帰呼び出し(1)

関数の中で関数を呼出すことが可能

main() {

printf(“%d¥n”, max3(12, 15, 11)); }

int max3(int x, int y, int z) { return max2(max2(x, y), z); }

int max2(int x, int y) { if (x >= y) return x; else return y; } 15

再帰呼び出し(2)

関数の中で自分自身を呼び出す

int

factorial(int x) {

if

(x == 1) {

return

1;

} else

{

return

x * factorial(x – 1);

}

}

(9)

17

今日の講義

手続きとは

手続きの定義

引数渡し

スコープ規則

引数 (parameters)

仮引数

(formal parameters)と

実引数

(actual parameters)

仮引数と実引数の対応付け

その位置によって対応付ける: positional parameters

仮引数の名称を指定: keyword parameters

引数に関するその他のしくみ

デフォルト値を持つ引数

仮引数と実引数の個数が異なる

実引数が足らない → 未定義を許す

実引数があまる

→ 複数の実引数をリストにしてまと

(10)

引数結合方法

C 言語での引数結合の例

宣言

呼び出し

19

int func(int x, double y) {・・・}

func( n, x + 3.5 );

引数渡しの原理

実引数を仮引数に渡す方式には複数ある

引数の渡し方式

Call-by-value (値呼び、値渡し)

Call-by-reference (参照呼び、参照渡し)

Call-by-name (名前呼び、名前渡し)

どのように引数を渡すのですか?

via. the

stack

via. the

registers

(11)

21

値呼出し(call-by-value)

仮引数には実引数の評価結果の値が渡される

1.

実引数の値を求める

2.

仮引数は、手続き内の局所変数として生成する

3.

実引数の値をその変数の初期値とする

4.

手続きの本体を実行する

手続き内で局所変数の内容が変化しても、呼出し

側に影響しない

局所変数の生成と値のコピーの必要がある

値呼出し(call-by-value)

C 言語は、値呼出しの機能のみである

宣言

呼出し

int func(int x, double y) {・・・}

(12)

23

参照呼出し(call-by-reference)

仮引数には実引数のアドレスが渡される (渡された

アドレスが仮引数のアドレスとなる)

仮引数への変更は、実引数に反映するので、結果

を返すためとして使える

局所変数の生成、コピーの必要がない

実引数は変数等であり、式は許されない

変数の衝突に注意が必要

変数呼出し

(call by variable) ともいう

名前呼出し(call-by-name)

手続きの本体の中の仮引数を実引数の式で置き換えて

実行する

この置き換えで名前の衝突が起こる場合は、名前の付

け替えを行う

1. 手続きの本体にある仮引数を、対応する実引数の式で置換す る 2. ただし、これによって手続き内の局所変数と衝突する場合は、 局所変数の名前の付け替えをする 3. できあがった手続き本体を、手続き呼出しのところに挿入す る 4. ただし、この挿入によって手続き内の大域変数が呼出し側の 局所変数と衝突する場合は呼出し側の局所変数を付け替える 5. そのまま実行する

名前の衝突

 実引数と手続き内の局所変数との衝突 手続き内の大域変数と呼出し側の局所変数の衝突

(13)

25

名前呼出しの例

呼出しプログラム begin integer i, n; n:=n+1; p(A[i]) … end; proc p(x) begin integer i; x:=x+i+n end; begin integer i; A[i]:=A[i]+i+n end; begin integer j; A[i]:=A[i]+j+n end; begin integer i, n; n:=n+1; begin integer j; A[i]:=A[i]+j+n end; … end; begin integer i, m; m:=m+1; begin integer j; A[i]:=A[i]+j+n end; … end; ①手続きp本体の 仮引数xを実引数 A[i]で置換 ②iが衝突するの で局所変数をj に付け替え ③呼出し箇所に手 続きを挿入 ④ 手続き内の大域 変数 n が呼出し 側の局所変数と 衝突するので、 名前の付け替え

引数渡しと評価方式

引数渡しの方式は式の評価方式と関係する

p(X,Y,Z)

begin if X>0 then Y else Z end;

において、呼出し

p(f(x), g(x), h(x))

を考える

参照渡しでは → こうした呼出しはできない

値渡しでは → f(x), g(x), h(x)を計算し、その値を渡す

名前渡しでは → f(x), g(x), h(x)をそのまま式として渡し、

(14)

27

今日の講義

手続きとは

手続きの定義

引数渡し

スコープ規則

コード(code)

データ(data)

Procedures

Control Flow

Statements

Data Access

Global Static Variables

Global Dynamic Data

Local Variables

Temporaries

Parameter Passing

Read-only Data

プログラミング言語の構成要素

(15)

プログラムのメモリレイアウト

各プログラムに割り当てられるメモリの領

域は以下のようになっている

0x0000番地 0xffff番地 プログラム領域 静的領域 スタック領域 ヒープ領域 書き換え不可能 領域が増減する 1プログラムに 割り当てられる 領域 29

各領域の説明

プログラム領域 (program)

プログラムの実行コード(機械語)が格納される

静的領域 (static)

プログラムが持つ定数などが格納される

char *a = “This is a string.”; printf(“Hello World!!”);

ヒープ領域 (heap)

大域変数が格納される

スタック領域 (stack)

(16)

自動変数

関数呼出し, ブロック開始時に生成される

関数からの復帰, ブロック終了時に消滅する

スタック領域上に確保される

main () { int i, j; func(); } func() { int x, y; } mainの中でのみ使用可能 mainを抜けると消滅 funcの中でのみ使用可能 funcを抜けると消滅 31

静的変数

自動変数と同様,宣言した関数内でしか見れ

ない

関数からの復帰時に消滅せず値が保持される

ヒープ領域に確保される

main () { int i, j; tick(); tick(); } tick() {

static int count = 0; count++;

funcの中でのみ使用 可能次回呼出し時に 値が残っている 静的変数であることを示す記憶指定子

(17)

大域変数(外部変数)

関数の外で宣言する

複数の関数で値を共有できる

プログラム実行中消滅しない

ヒープ領域に確保される

int i, j; main () { i = 1; j = 2; func(); } func() { printf(“[%d,%d]”, i, j); } mainでもfuncでも使用可能 消滅しない [1,2]が表示される 33

有効範囲 (スコープ, scope)

名前(変数名、手続き名等)とその束

縛に対し、その名前でその束縛が参照

されるとき、その名前は

可視 (visible)

いう

ある名前が可視であるプログラムの範

囲を

スコープ(scope)

という

(18)

35

有効範囲 (スコープ)

コープ規則:

1.

ある手続きを実行中に変数

が表れたとき、

の宣言がその手続きにあるならば、この宣

言が

の束縛を決める

2.

その手続きにないなら、この手続きを定義し

ている手続き(親手続き)の中に宣言を探す。

そこにあれば、その宣言が束縛を決める

3.

さらに、そこになければ…その親…

有効範囲 (スコープ)

通常のスコープの規則

静的スコープ規則 (static scope rule)

静的スコープ規則は、プログラムによって

予め決められる規則である

プログラムの字面で決まるので、

lexical scope

rule

ともいう

逆に、プログラムのある箇所での束縛の全

体を

環境(environment)

という

(19)

変数のスコープと寿命

スコープ: その変数を見れる範囲

寿命: その変数に値が保持されている期間

37

スコープ

寿命

自動変数

関数内

プログラムの全実行

静的変数

関数内

プログラムの全実行

大域変数

プログラム全体

プログラムの全実行

スコープと可視性

別々のスコープで同じ名前を使用できる

名前が衝突したときは,内側のスコープを優先

int i, j; main () { func1(); func2(); } func1() { int i, j; } func2() { int i, j; } main内における i , j func1内における i , j func2内における i , j

(20)

39

手続きのスコープ関係

main var x

procA var y

procB var z

(procB本体)

procC var u

(procC本体)

procD var v

procE var w

(procE本体)

各手続き本体で可視の名前:

main: procA, procD,

変数x

procA: procA, procB, procC, 変数x, y

procB: procA, procB, 変数x, y, z

procC: procA, procB, procC,

変数x, y, u

procD: procA, procD, procE,

変数x, v

procE: procA, procD, procE, 変数x, v, w

その手続きの本体で、名前が可

視であれば手続きは呼べる

自分よりも後ろのものは通常可

視でない

(procA本体)

(procD本体)

(main本体)

スタック領域の詳細

関数呼出しに応じてスタック

領域が確保される

main () { int x = 1; x = input(x); } int input(int y) { char s[10]; scanf(“%s”, s); printf("%s¥n", s); return y + 1; } 0xffff番地 x y 戻り番地 s[0] s[1] : : 自動変数用 28バイト 引数用 20バイト input用 main用

(21)

バッファオーバーフロー攻撃

scanfなどで戻り番地を上書きする

戻り番地は29~32文字目

main () { int x = 1; x = input(x); } int input(int y) { char s[10]; scanf(“%s”, s); printf("%s¥n", s); return y + 1; } 0x0000番地 0xffff番地 x y 戻り番地 s[0] s[1] : : 自動変数用 28バイト 引数用 20バイト input用 main用

不正な

コード

41

参照

関連したドキュメント

講義の目標.

日臨技認定センターの認定は 5 年毎に登録更新が必要で、更新手続きは有効期間の最終

本手順書は複数拠点をアグレッシブモードの IPsec-VPN を用いて FortiGate を VPN

第1条

・条例手続に係る相談は、御用意いただいた書類 等に基づき、事業予定地の現況や計画内容等を

出典:第40回 広域系統整備委員会 資料1 出典:第50回 広域系統整備委員会 資料1.

者は買受人の所有権取得を争えるのではなかろうか︒執行停止の手続をとらなければ︑競売手続が進行して完結し︑

それゆえ︑規則制定手続を継続するためには︑委員会は︑今