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

今回と次回は,「関数」に関するプログラミングについて学びます

N/A
N/A
Protected

Academic year: 2021

シェア " 今回と次回は,「関数」に関するプログラミングについて学びます"

Copied!
15
0
0

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

全文

(1)

この授業も後半に入ってきました。これまでは理屈が良くわからなくても,見よう見まねでプログ ラミングができていたかもしれませんが,このあたりから少しずつ難しくなり,ある程度,理屈がわ からないと困ってきますので,気を改めて勉強しましょう。

今回と次回は,「関数」に関するプログラミングについて学びます。今回はその基礎ですが,そ の内容は,つぎのようにちょっと豊富です。

1.まずC言語のライブラリーに事前に登録されている関数の使い方を学びます。

2.続いて,使いたい関数がライブラリーに登録されていないときに,自分のニーズに合わせて ユーザー(=私たち自身)が関数を作成(定義)する方法を学びます。

3.さらに,関数がその内部で別の関数を使って定義されているときの「後方参照の原則」につ いて学びます。

4.最後に,変数の種類にローカル変数(局所変数)とグローバル変数(大域変数)があることを 学びます。

関数の基本概念はすでに中学・高校の数学で習っているわけですが,C言語でいう「関数」は,

数学的には少しあやしく,私なら「関数?」とでも言いたいものなのですが,そのようなことにも少 し触れます。 たとえば,計算結果がない「関数?」や,計算結果がランダムになる「関数?」につ いても触れます。

(2)

数学的によく知られている関数(function)の使い方を学びましょう。それらの多くは,C言語が事 前に用意してあるmath というライブラリー(図書館のようなもの)に登録してあるので,その知識 が必要です。使うときには,math.hというヘッダーファイルをインクルードするために,

#include <math.h>

と書き,コンパイルするときには gcc no8_1.c –o no8_1 –lm

のように–lmというスイッチを付ける必要があります。

mathライブラリーにどのような関数が登録されているかは,C言語の詳しいマニュアルを調べれ ばわかりますが,この授業では主なものを紹介します。

このスライドの最初に書いてある double exp(double x)

は,ライブラリーに登録してある関数exp の仕様の簡単な紹介で,この関数は入力データ(引 数)としてdouble型のデータ(ここでは仮にその値をx という変数に記憶するとしている)を必要と し,その計算結果である出力データ(戻り値)もdouble型であることを示しています。行の右側に は関数の意味を簡潔に書きました。関数exp は自然対数の底 e のx 乗を計算する指数関数で す。たとえば,e のx 乗を計算してy に代入するプログラムコードは,つぎのようになります。

double y = exp(x);

それ以外の関数の使い方や意味も自明でしょう。log は自然対数,pow はべき乗(power),sqrt は平方根(square root),cos は三角関数のコサイン,acosはコサインの逆関数(arccosine)です。

スライドには書きませんでしたが,sin, tan やその逆関数もあります。

最後の4つの関数は数学の教科書では「関数」とはいわないかもしれませんが,C 言語では関 数として扱われます。fabs は絶対値(absolute value),floor は床関数(floor),ceil は天井関数

(ceiling),round は四捨五入(round)です。fabs の名前のf は奇異に感じるかもしれませんが,引

数と戻り値が浮動小数点数(floating-point number)であることから,昔からの慣習でこうなってい ます。

(3)

前のスライドでは,e のx 乗を計算してy に代入するプログラムコードは,

double y = exp(x);

となることを学びました。この例では引数(つまり,左括弧と右括弧の間に書くもの)は,前のスラ イドで関数の仕様の説明に使われていた変数xをそのまま使っています。

しかし,つぎの例のように,別な変数でもよいのです。

double y = exp(a);

また,ここは定数でもよいのです。

double e = exp(1.0);

さらに,一般の数式でもよいのです。

double f = exp(-x*x/2.0);

つまり,みな数学の教科書に書いてある書き方に準じて書けるようになっています。

(4)

前のスライドの例では,関数の計算結果をみなdouble y = … というような代入文を使ってy な どの変数に保存していましたが,実際には必ずしもその必要はありません。こちらのスライドでは,

cos(a) の計算結果を保存せず,その式をそのままprintfの引数に記述することによって,計算結

果をただちにディスプレイに表示するようにしています。

なお,この例では入出力(scanf, printf)を使っているので,math.hに加えて,stdio.hもインク ルードしていることに注意してください。

(5)

ここからは,ユーザー(=私たち)が,必要に応じて独自に関数を定義する方法を説明します。

このスライドでは,まず引数を1つだけもつ簡単な関数の例として,double型の引数x を2乗し て「戻す」(「計算結果」=「戻り値」とすること。「返す」ともいう。)ものを示しています。関数名は,

変数名の付け方と同じ規則によってユーザーが自由に付けることができ,この例ではsquare (=

2乗の意味)としています。

この関数を定義するには,まず double square (double x)

という見出しを書きます。square は自分の付けた関数名,括弧の中のdouble x は引数のデータ 型と変数名,少し戻って左端のdouble はこの関数の戻り値のデータ型を表します。括弧の中に 書かれたx のことを「引数」と呼ぶほかに,「仮引数」(かりひきすう)とか「パラメータ」と呼ぶことも あります。与えられるデータを「仮に」x と名付けているだけだからです。

見出しの後には,左中括弧({)と右中括弧(})で囲むようにして,関数の本体(具体的に関数 の計算を行うプログラムコード)を書きます。

このsquare 関数の場合には,単にx の2乗(=x*x)を計算して戻すだけですが,初心者にわ

かりやすくするため,いったん変数y に結果を代入しています。その直後の return y;

という命令によって,計算結果(= y の値)が呼び出し元に戻されて,関数の実行が終了します。

returnはこのようなときに使う決まり文句(予約語)です。return の右のy の部分は,単なる変数 名以外に,式を書くこともできます。

スライドでは,その下に,この関数を使うmain 関数の例を示しています。b = square(a); という代 入文によって,a の2乗をb に代入しています。このa のように,実際に関数を使うときの引数のこ とを,先ほどの仮引数x と区別するために,「実引数」(じつひきすう)とも呼びます。a は「実際 に」与えられるデータだからです。このように,仮引数の変数名(x)と実引数の変数名(a)は異なっ ていてもOKです。もちろん,同じでもOK。

(6)

今度は引数を2つもつ関数を定義してみます。

distance(=距離)と名付けたこの関数は,引数としてdouble型の2つのデータx, y を受け取り,

2次元座標平面上の点(x, y) と原点O との距離を計算して戻します。

距離はもちろん三平方の定理に基づいて計算できます。プログラムの中では,前のスライドで 自分で定義したsquare 関数を使って,x の2乗とy の2乗の和の平方根を求め,z に代入して,

関数値として戻しています。sqrt は今日紹介したmath ライブラリーの中にある関数で,平方根

(のうち非負のもの)を求めるものです。

main 関数ではdistance 関数を使用しています。theta(=θのこと)という変数に角度を読み込み,

x=cos(theta), y=sin(theta) としたときの,(x, y) と原点との距離を求めています。三角関数の知識 がある人は,theta の値が何であっても計算結果が1.0であると予測できるかもしれませんが,実 際にコンピュータで計算させると,わずかな誤差があるかもしれません。

(7)

関数はふつうは少なくとも1つの引数をもちます。そしてy=f(x) のときは,x の値が変われば,

一般にはy の値も変わります。しかし,特別な場合として,x の値が何であってもy の値が一定

である場合も許されているのです。たとえば,y = 0 がそうです。しかし,定数は引数を持たない 関数として扱い,y=zero( ) などと表しても変ではありません。

このように,引数がない関数は変ではないのですが,いくら何でも,戻り値がない関数というの は変です。数学では,関数は「写像」とも言われ,x の値を何らかのy の値に対応させなければ ならないからです。

しかし,C言語やその他の幾つかのプログラミング言語では,そのようなものも「関数」と呼んで います。そのような言葉づかいに疑問を持つ(理論派の)研究者は,そのようなものを関数と呼ば ず,「手続き」(procedure)と呼ぶこともあります。

このスライドでは,引数や戻り値のない関数の定義の仕方を紹介しています。これは引数も戻り 値もなく,単にHello! とディスプレイに表示するgreeting (=挨拶)という関数です。「引数も戻り 値もない」と言っても,C言語では書くべき場所に何も書かないのではなく,かわりにvoid(=か らっぽ) と書くことになっています。したがって,関数の見出しは

void greeting(void) となります。

スライドにあるmain 関数は,単にgreeting 関数を引数無しで呼び出しているだけです。戻り値 がないので,計算結果を何かに代入しようとするのは,エラーになります。

ところで,ここまで学んでくると,これまで何となく見よう見まねでプログラミングしてきたmain 関 数は,今日勉強した「関数」の書き方にしたがって書かれた,れっきとした関数であることがわかり ます。つまり,関数名はmain,引数はなし(void),戻り値はint 型の関数です!

ふつうはmain 関数の本体の終わりにreturn 0; と書きますが,これは関数値(戻り値)として0

を戻しているのです。main は見出しでint 型を戻すと宣言しているので,何かint 型のデータを 戻す必要があるからです。なんで0 を戻すのか? それは,ふつうはmain 関数が正常に終了し たことを表すエラーコード(=エラーなし)として,main の呼び出し元=Windows やLinux などの オペレーティングシステム(OS,基本ソフトウェア)に戻すためとなっています。

(8)

ここから今日の後半ですが,少し理屈っぽくなってきます。まずこのスライドでは,複数の関数 を定義するときに,その並び順を問題にします。数学では

norm(x,y) = sqrt(f(x,y)) f(x,y) = x*x+y*y

のように,ある関数(上の例ではnorm)を定義するときに,まずf(x)を右辺で使った式を書いてお き,その後にf(x) = … というようにf(x) を定義しても問題ありません。しかし,C言語では,いやら しいことに,これではエラーとなります。正しくは,

f(x,y) = x*x+y*y norm(x,y) = sqrt(f(x,y))

のように,使う前に事前に関数を定義しておく必要があります。

プログラムを書き進めていく下方を「前方」,すでに書き終わった上方を「後方」と呼ぶと,前方 で使われる関数が後方の定義を参照するので,これを後方参照の原則といいます。

スライドの左半分を見てください。add 関数を事前に定義しておき,その後にそれを使うmain 関数が定義されている正しいプログラムです。ここで順番を逆にして,main,add の順に並べると エラーになります。しかし,プログラマーによっては,まずmain の中で種々の関数を使う計算処 理の全体像を示し,その後に各関数の定義を書きたいと考える人も多いです。そのようなとき,

後方参照の原則は困りものです。

この問題を解決するため,C言語ではプロトタイプ宣言というものが用意されています。スライド の右半分を見てください。最初の行に

int add(int a, int b)

と関数の見出しが書かれていますが,その右にセミコロン(;)が打たれて,関数定義はここで終 わっています。このように見出しの部分とセミコロンだけ書くのがプロトタイプ宣言です。これで

add 関数を使うための最低限の情報が得られるので,その後,main 関数などの中でadd を使っ

てもよいのです。addの中味(本体)は,あらためてその後に書きます。これにより,add とmain の 順番を実質的に逆転させ,前方参照により関数を記述できます。

(9)

ここからは,変数には少なくとも2つの種類(ローカル変数,グローバル変数)があることを学び ます。そして,それらの違いを明確に理解してほしいのですが,最初の2枚のスライドではスコー プという観点から違いを理解し,その後の2枚のスライドではライフタイムという観点から違いを理 解します。これらの概念は,多くの関数を定義する必要がある複雑なプログラムにおいて,関数 間での変数の値の干渉を避けたり制御したりすることによって,その複雑さを軽減する機能として 重要なものです。

このスライドのadd 関数を見てください。その中では変数a, b, c が宣言されています。このよう に関数の中で宣言された変数をローカル変数(局所変数)といいます。なぜ「ローカル」という言 葉が使われるかというと,それらの変数を使って良い範囲(スコープ(scope)または有効範囲とい う)はこの関数定義の中に限るという点で局所的だからです。そのスコープの外で同じ名前の変 数が宣言されていたとしても,スコープ内の変数とスコープ外の変数は全く別のものです。ちょう ど,人間の場合,同姓同名であっても別人であることがあるように,スコープの内と外では変数名 が同じであっても別な変数となります。

したがって,add の中で宣言されている変数a,b,cとmain の中で宣言されている変数a,b,cは 同じ名前ですが,別の変数です。混乱を避けて理解するためには,一方のa,b,cをa2,b2,c2 の ような別の名前に付け替えて理解してください。ただし,大規模なプログラムでそのように変数名 を付け替えるには,多くの変数名を考案する必要があり,プログラムの中が多くの変数名であふ れかえり,プログラムを理解しにくくなってしまうので,これは実用上,望ましいことではありません。

さて,このスライドのプログラムの動作を確認してみましょう。main の実行が開始されると,b=2,

c=3 が実引数としてadd 関数に渡されます。それらはadd 関数の仮引数a,bにコピーされて渡さ

れ,a=2,b=3 となります。ただし,main のb=2,c=3 はadd のローカル変数b, c とは別物なので値 は変わりません。add の中では実引数の和a+b=5 がc に代入されますが,このc はmain の

c=3 とは別物です。c=5 の値はコピーされてmain に戻されます。add から戻された5 はmain の

中でa に代入され,printfで表示されます。

このような理解は,add の中のa,b,cとmain の中のa,b,cは別物と理解してなんとか理解できる ものです。変数名が同じなら必ず同じ変数だ,などと考えたら,理解しにくくなるでしょう。

(10)

ローカル変数(局所変数)のように関数(の見出しや本体)の中で宣言されるのではなく,関数 の外で宣言される変数をグローバル変数(大域変数)といいます。このスライドの例では,rate が グローバル変数です。myDol, myYen, d, yen はどれもグローバル変数ではなく,ローカル変数 です。

なぜ「グローバル」という言葉が使われるかというと,グローバル変数のスコープ(有効範囲)は このプログラム(ソースファイル)の全体(=大域)だからです。したがって,このファイルのあちらこ ちらで同じ名前のグローバル変数が使われていたら,それらはすべて同じ変数です。

このスライドの下半分に書かれている関数dol2yen (dol_to_yenと読む)は,米ドルの金額d を 日本円に換算するものです。計算は簡単です。その日の換算レート(1ドル当りの円価)が事前 にグローバル変数rate に代入されてあるとして,それとd の積を関数の値として戻します。

グローバル変数の存在理由を考えてみてください。上の例の場合,もしグローバル変数rate が なかったら,d のほかにrate も関数の引数として,dol2yen(double d, double rate) のように関数を 定義しなければ,この計算はできません。しかし,rate は一定のままとしてd の値をいろいろ変え て計算するような応用を想定すると,毎回rate を引数に渡すのは非効率な感じがするので,rate をグローバル変数とする意義が感じられるでしょう。

ここまで,ローカル変数とグローバル変数のスコープについて学びました。しかし,C言語を厳 密に学ぶと,病的な例外が気になってきます。ある同じ名前の変数が,ローカル変数としても,グ ローバル変数としても宣言されていたら,どう考えればよいでしょうか? それらの2つは同じ変 数なのでしょうか,それとも別な変数(同姓同名の別人)なのでしょうか?(答え:「別な変数」)さら に,それら2つの変数のスコープが重なる(入れ子になる)ことになりますが,その重なっている範 囲でその変数名が使われたら,それはどちらの変数を意味するのでしょうか?(答え:ローカル変 数)こういうことが気になる人はC言語を厳密に学んでください。この授業では,今述べた病的な 状況はないと想定します。実際,専門的な観点から,初心者であろうとプロのプログラマーであろ うと,そのような混乱の元となるプログラムは書かないようにすることを推奨します。

(11)

ここまでで,ローカル変数とグローバル変数について,スコープという観点から違いを理解しま した。スコープは有効範囲ということで,物理学的な言葉を使うと,プログラムテキストを構成する 2次元空間の一部ということです。一方,このスライドでは,ライフタイムという観点から違いを理解 します。ライフタイムはその名のとおり,(空間ではなく)時間の一部を表す概念です。空間とか時 間とか,アインシュタインが喜びそうな言葉が,コンピュータでも出てくるのです。

まずはローカル変数のライフタイムについて説明します。このスライドのプログラムを見てくださ い。やりたいことは,countupという引数無しの関数を定義して,main の中でcountup() を実行す るたびに,整数値count が1ずつ増えて,0, 1, 2, 3,…となるようにしたいのです。

main を見てください。countup() の1回目では1という値が戻されるので,結果をone という変数

に代入しています。2回目のcountup() では,今までの1 に新たに1 が加算されて2が戻される

(本当は違う)かのように,結果がtwo に代入されています。

このようなcountup関数を定義するためには,スライドにあるように,ローカル変数count の初期 値を0 としておき,関数が呼び出されたときに,count = count + 1; あるいはcount++; というコード を実行するようにしておけば良い気がします。しかし,それは間違いです。その理由を説明する ために,ライフタイムという概念が必要になります。

変数のライフタイム(lifetime)とは,プログラムの実行中に,その変数が生まれて使えるように なってから,死んで使えなくなるまでの時間の範囲(生存期間)のことをいいます。関数内で宣言 されたローカル変数のライフタイムは,その関数が実行を始めた時点(そのとき変数が生まれる)

から始まり,その関数の実行が終了した時点(そのとき変数が死ぬ)で終わります。

右側の図を見てください。main でcountup() が2回実行される様子を横軸を時間軸として示し ています。緑色の2つの長方形は,関数countupが実行中の時間の間,時間軸に接しています が,その時間の範囲がライフタイムです。1回目の実行では,ローカル変数の値がcount=0 とな り,その後count=1 となって関数の実行が終了しますが,ここでライフタイムが終了し,count は 死んで使えなくなるのです。countupの2回目の実行では,再びローカル変数count が生まれ,

count=0 となり,その後count=1 となり,死んでいきます。したがって,当初望んでいたように,

count がずっと生き延びて,0, 1, 2, 3,…と増えていくことにはなりません。このように,ローカル変 数のライフタイムは,「関数の実行から終了までの間に限られる」という意味で「局所的」であり,

「ローカル」なのです。

(12)

ローカル変数のライフタイム(生存期間)は局所的でした。このスライドでは,グローバル変数の ライフタイムは大域的であることを学びます。

スライドの2行目で宣言されている変数count は,グローバル変数です。そのスコープ(有効範 囲)はすでに学んだように,このプログラム全体です。

スライドの下半分では,前のスライドに似た関数countup() が定義されています。ただし,前の スライドではcount はローカル変数だったのですが,今回は,count はグローバル変数である点 が異なります。

スライドの右半分は,main 関数からcountup() を2回呼び出して実行したときの様子を表してい ます。count の値は最初は0 で,1回目のcountup() が終了したときは1 になります。前のスライ ドと異なるのは,関数countup() の実行がここで終了しても,count の値は1のまま保持されること です。これはcount のライフタイムが時間軸の上で大域的(言い換えれば永続的)であるからで す。したがって,2回目のcountup() が始まったときはcount = 1 のままなので,それが終了すると count = 2 となります。このような動作は,前のスライドでできなかったこと,すなわち,「countup() を実行するたびに,count が1ずつ増えて,0, 1, 2, 3,…となるようにしたい」ということを実現してい ます。

このように,グローバル変数は,スコープが大域的であることに加えて,ライフタイムも大域的な ので,変数の値をプログラムの全実行時間中に渡って記憶したり更新したりすることができます。

グローバル変数がそんなに便利なら,制限が多いローカル変数なんていらないのではないかっ て? 初心者はそう思うかもしれません。実際,ローカル変数がなくても,グローバル変数があれ ば,どんなプログラムでも書けます。しかし,大規模で複雑なプログラムでは多数の変数が必要 なので,プログラムの狭い文面内で変数を短期間だけ使いたいときはローカル変数とすることで,

プログラムの(空間的,時間的に)他の部分との干渉を少なくし,プログラムの複雑さを軽減して,

わかりやすいものとするのに役立ちます。

(13)

最後に,乱数を発生する関数rand() を紹介します。これは応用でよく使われるので,使い方を 知っておくこと自体が重要ですが,このような関数を定義するときにグローバル変数を効果的に 使えることを見ておくという点でも学習に値します。

rand()は,引数無しの関数で,0 以上のランダム(random)なint 型データを値として戻す関数で

す。たとえば,

int n = rand();

を実行すると,n の値は何かランダムな非負整数値になります。0 かもしれないし,20128 かもし れませんが,-5 ではありません。ただし,4つの注意点を以下に補足します。

1.数学で「引数無しの関数」といえば戻り値は定数であるべきなので,乱数値を戻すrand() は 数学的には「関数」とはいえませんが,C言語では関数と呼んでいます。

2.数学でいう整数とint 型データはやや異なります。int 型は,コンピュータにもよりますが,た いていは32ビット(0と1が32個並んだデータ)で表される整数のことをいうので,その最大値が決 まっています。その値をC言語ではRAND_MAX と表します。32ビットだったら,この値はおよそ 21億です。一方,数学の整数には最大値はありません。

3.一言で「ランダム」といっても,その「乱れ具合」(=確率分布)にはいろいろなものがあります。

rand() 関数の場合は,「一様分布」にしたがう乱数を発生します。これは発生され得る RAND_MAX + 1 個の整数値が,どれも同じ確率で発生されるという意味です。

4.rand() が発生する値は,厳密には乱数ではありません。なぜなら,rand() はプログラムで出

力値を計算するので,そのプログラムを読めば,次にどんな値が出るかを予測できるからです。

ただし,プログラムを読まずに出力データの系列を観察すると,それは統計学的に乱数が備えて いるべき性質を持っています。その意味で,これを疑似乱数と呼んでいます。

rand() がどのように疑似乱数を発生するのか,そのメカニズムを説明します。スライドの下半分 に書かれているように,rand() はグローバル変数(変数名をr としました)を用いて,前回発生し た疑似乱数値を記憶しています。そして,つぎにrand() が実行されたときには,事前に決められ た適当な整数値A とr の積A*r を新しい疑似乱数値として発生します。ただし,最大値

RAND_MAX を超えるときには,それをRAND_MAX + 1 で割った余りとします。これであたか

も0 以上RAND_MAX 以下の整数がランダムに発生されているかのように見えるのです。

(14)

前のスライドで疑似乱数の発生メカニズムを説明しましたが,そこでは前回発生した疑似乱数 をグローバル変数r に記憶し,それを用いて新しい疑似乱数を発生していました。そうすると,そ もそも一番最初のr の値は何なのかが気になります。その値を疑似乱数の初期値あるいは開始 点あるいは種(seed,シード)といい,私たちユーザー(プログラマー)がsrandという関数を用いて 設定することができます。

srand(seed)は,符号無し整数seed を引数に与えて実行すると,その値を疑似乱数の初期値と

して設定します。初期値なので,たいていの場合,プログラムの開始時点で1度だけこれを実行 します。たとえば,seed=37 にして,srand(37); と書けば良いのです。

しかし,この37という数字はそれを設定した私たちにとっては(見えているので)ランダムとはい えません。私たち自身にとってもその値がわからないようにするためによく使われる方法は,

srand() 関数を実行した時点での「現在時刻」をseed とすることです。現在時刻の値はライブラ

リーにあるtime() という関数によって得られるのですが,これは過去のある時点からの秒数なの で,私たちはよほどのことをしないと値を予測できません。また,同じプログラムでも実行するたび に値が変わるという点でもランダムな感じになります。

このスライドの下半分にその書き方の例を示します。まず,rand とsrandの定義はstdlib (standard library)というライブラリーに格納されているので,ヘッダーファイルstdlib.hをインク ルードします。また,time() 関数はtime というライブラリーに格納されているので,ヘッダーファイ

ルtime.hもインクルードします。

プログラムの実行部分では,通常はまず1回だけ srand((unsigned)time(NULL));

を実行して,現在時刻を使って疑似乱数の初期値を設定します。(この書き方はわかりにくいか もしれませんが,一種のおまじないとして,そのまま書いてください。)srandは1回だけ「実行す る」のであって,1回だけ「書く」のとは違います。ですから,forループの中に1回だけ書いても,

それが繰り返し実行されれば間違いです。

これで準備ができました。あとは,乱数が必要になるたびに繰り返しrand() を実行して,その 戻り値を使えば良いのです。

(15)

以上で今日の内容はおしまいですが,C言語の教科書を読むと,関連した内容としてスタ ティック変数のことが書かれているかもしれません。これは,ローカル変数,グローバル変数に次 ぐ第3の変数の種類です。

スタティック変数についての詳しい説明はこの講義では省略しますが,一言で説明すると,スタ ティック変数のスコープは局所的,ライフタイムは大域的です。つまり,ローカル変数の性質とグ ローバル変数の性質の中間的な性質を持ちます。さらに知りたい人はこのスライドを見て勉強し てください。

しかし,ほとんどのプログラマー(初心者であろうとプロであろうと)は,スタティック変数のことを 知らないで困ることはないでしょうし,世の中(学術や産業)のC言語のプログラムでスタティック 変数が多用されていることはなさそうに思います。

もし皆さんが将来,スコープが局所的でライフタイムが大域的であるような感じの変数を使いた くなったら,C言語ではなく,オブジェクト指向プログラミング言語と呼ばれる種類の現代的なプロ グラミング言語を使われることをお勧めします。C言語は古い言語なので,あまり使われなくなっ た機能がいろいろあるのです。

参照

関連したドキュメント

点から見たときに、 債務者に、 複数債権者の有する債権額を考慮することなく弁済することを可能にしているものとしては、

それでは資料 2 ご覧いただきまして、1 の要旨でございます。前回皆様にお集まりいただ きました、昨年 11

子どもたちは、全5回のプログラムで学習したこと を思い出しながら、 「昔の人は霧ヶ峰に何をしにきてい

基準の電力は,原則として次のいずれかを基準として決定するも

いてもらう権利﹂に関するものである︒また︑多数意見は本件の争点を歪曲した︒というのは︑第一に︑多数意見は

【大塚委員長】 ありがとうございます。.

ƒ 、または Arduinoのリセットボタン”oƒ、2 }~x してか らコマンド @2 しま Q*した Arduino す。 プログラムを Arduino に…き:む Äsについては「

 筆記試験は与えられた課題に対して、時間 内に回答 しなければなりません。時間内に答 え を出すことは働 くことと 同様です。 だから分からな い問題は後回しでもいいので