高校数学の窓過去問検索

基本データ型


変数と定数

コンピュータは、何らかの情報を取り扱うとき、それをデータとして格納する場所を自分の内部に確保します。これからは、それを一つの箱に例えることにしましょう。
当然、たくさんの情報を取り扱うことになりますから、それらを格納する箱も大量になり、その一つ一つを識別するために、それぞれの箱に名前をつけなくてはなりません。その名前は、箱の中身がいかなる情報を表現しているか、一目でわかるようにつけるのが普通です。

意味する情報の種類によって、コンピュータが処理を進めていくにつれて、その内容を変化させる箱と、まったく変化させない箱が存在します。プログラムにおいては、

  • 変数・・・時間変化する情報を格納する箱

  • 定数・・・時間変化しない情報を格納する箱


と呼びます。数学における変数との違いに注意してください。一般的に数学では、変数xやyで、何かの未知の量は未知の数を意味し、それらはある値をとりますが、時間的変化は考慮されていません。


ここではメモリのアドレスに付いて書かれてるんですが……、いや、正直、通大数学コースの「コンピュータ」が「初心者向け」前提だったら、この辺の解説は不必要でしょう。
もっと酷い解説は変数、定数の説明です。「時間変化する/しない」って何だろ?これはあるメモリの番地を変数として「2」を代入すれば1秒後には「3」に変わるってか?んなこたあない(by タモリ)。
変化するか、しないか、と言うのは人間の書いたプログラムによる「操作」によって、です。時間で変化するわけじゃあありません。従って、解説としては単純に破綻しています。
まあ、ハッキリ言うと、「変数」も「定数」も「数学的な変数/定数と抽象的には同じもの」と考えてO.K.です。それが一番シンプルな解説ですよね。こんな辺りに「おかしげな」工学的解説なんて試みても無駄です。


プログラムでは、変数xと書かれたとき、xという箱の中身のときと、xと言う名の箱それ自身を意味するときの2つの場合があります。例として、

  • x ← x + 1


と表現される代入文についてみてみます。上の表現で、右辺の"x"はxと呼ばれる箱の中身を、左辺の"x"はxと呼ばれる箱それ自身を表します。したがって、上の命令はxと言う箱の中身と1を足した値を左辺のxという名の箱にいれなさいということになります。結果として、変数xの中の値が1増加することになります。この代入操作が、変数の中身を変化させる処理の基本です。
プログラミング言語の中には、数学の等号"="を代入操作の意味に使用するものがあるので注意が必要です。このテキストでは、上のように矢印"←"を用いて代入を記述することにします。


う〜ん、ツッコミどころがあるんですが、難しいなあ……。
いや、全体的に「アセンブリ言語」とか「機械語レベル」だったらその通りの説明だ、って思う向きもあります。
しかしながら、「高級言語」の文脈で

右辺の"x"はxと呼ばれる箱の中身を、左辺の"x"はxと呼ばれる箱それ自身を表します。

なんて解説はまだるっこしくってしゃーないです。と言うかここまで細分化するなら「高級言語を使う必要性」が無いですし、また、習わせる必要性さえありません。
原則的に、数学的に抽象化すると、この操作は

$$x_{k+1} = x_{k} + 1$$

を表している、に過ぎないのです。箱がどうの、なんてのはハードウェアレベルの話なんで、どうでも良い、って言えばどうでも良い話、です。そしてこのテの「漸化式計算」に於いて、コンピュータでは「添字は無視して構わない」ってだけですよね、抽象的には。
高級言語を利用する目的はこの「抽象性がある」故、です。つまりそれこそ「ハードウェアレベルでの動きを」人間の目から隠して「ブラックボックス化する」ってのが狙いなんです。
もっともこの文脈は情報工学専門でも同じだ、とは思いませんが、少なくとも「数学教員育成コース」では十二分な説明でしょう。

プログラミング言語の中には、数学の等号"="を代入操作の意味に使用するものがあるので注意が必要です。


これはその通り、です。代入操作の表記法はプログラミング言語によって違います。
例えば、Schemeでの上の代入操作は、

(set! x (+ x 1))

と記述しますし、統計解析ソフトRでは

x <- x + 1

と記述します。


プログラムにおける変数、定数は、必ずしも、その中身が"数"とは限らないことに注意してください。すべての情報が数値で表されるとは限りません。
箱、すなわち変数と定数は、その中に入ることの出来る内容別に、すなわちデータの種類(型)によって分類されます。一般に、これは、"変数xは、〜型である"と表現されます。プログラムのなかでは、実際の処理に入る前に、これから使用するすべての変数と定数の名前をあげ、それが変数であるか定数であるかの区別と共にその型を明らかにしなくてはなりません。通常、このことを"変数を宣言する"といいます。このテキストでは、

  • 変数 x, y : 整数型


と言う記述を用いて、変数として使われる箱の名前(変数名)とその型を明示し、また

  • 定数 Pi = 3.14159265 : 実数型


と言う記述で、定数として使われる箱の名前(定数名)とその型、さらに変化することのないその箱の中身を処理に先だって明記します。
型が明らかな定数の場合は、その型の明示を省略することもあります。


この辺から怪しくなってくるんだよな(苦笑)。
まず、前にも書きましたが

プログラムのなかでは、実際の処理に入る前に、これから使用するすべての変数と定数の名前をあげ、それが変数であるか定数であるかの区別と共にその型を明らかにしなくてはなりません。通常、このことを"変数を宣言する"といいます。

と言うような「あらゆるプログラミング言語で変数宣言は必ず行わなければならない」的な記述は害悪、です。「そんな必要のない言語」も多いのです。ウソ書いちゃいけない。
一般的に、プログラミング言語には次の二種類が存在します。

  • 静的型付け言語(Static Typing Language):変数宣言を行わなければならないプログラミング言語

  • 動的型付け言語(Dynamic Typing Language):変数宣言を行う必要がないプログラミング言語


それぞれ、メリット、デメリットがあるんですが、一般的に記述が簡単なのは「動的型付け言語」の方です。
通大のレポート/テストで指定されている言語のうち、Fortran、Pascal、C言語はすべて「静的型付け言語」ですね。
(下手すればBASICもこっちに分類されるかもしれません。構造が動的型付け言語のメカニズムに一致してないでしょうから。)
一方、Schemeなんかは「動的型付け言語」に分類されます。事実、亀田自身は「変数宣言」なんてした事ありません(笑)。んなもんメンド臭くてやってられるか、っての(笑)。
ポイントは「プログラミング言語の面倒なしきたり」にいきなり触れさせるべきではない、って事です。この通大の「コンピュータ」のテキストの主目的はあくまで「数値計算」と言う「数学をどうやってプログラミングロジックに変換するのか?」です。これはこれで難しいのに、「静的型付け言語」の「様式」なんてひきずって解説したらワヤクチャなんですよ。
まあ、初版1991年、と言う時代考えてみればしょーがない部分もありますが、いずれにせよ、現時点まで「1991年のまま」ってのは害悪ですね。
ここではあくまで「動的型付け言語」にこだわって展開していきます。
そして、


このテキストでは、

  • 変数 x, y : 整数型


と言う記述を用いて、変数として使われる箱の名前(変数名)とその型を明示し、また

  • 定数 Pi = 3.14159265 : 実数型


と言う記述で、定数として使われる箱の名前(定数名)とその型、さらに変化することのないその箱の中身を処理に先だって明記します。

とか書いてますが、そもそも疑似コードに「変数宣言」なんて書くべきじゃない、です。疑似コードに「変数宣言」なんてものは必要ありません。
もう一回書いておきますが、疑似コードの必要性、ってのは特定のプログラミング言語に縛られない「ロジックの簡易記述」にその目的がある、んです。「工学的な流儀」であるとか、「静的型付け言語の流儀」ってのは、別に「計算ロジックそのもの」とは何の関係も無いのです。こう言う混乱を起こすような事を書くなっての。
また、通大用語で言う「疑似プログラム」の「変数宣言」ってのは丸っきり「Pascalのモノ」なんですよ。

(* Pascalに於ける変数宣言の例 *)
var x, y : integer;
(* Pascalに於ける定数宣言の例 *)
const pi = 3.141592;

基本的に英語表記を日本語表記に変えただけ、に過ぎません(爆)。
こんなんだったら、キチンとPascal使って「最初からPascalを通して数値計算を学ばせる」べき、なんです。この辺で通大ローカルである「疑似プログラム」なんてのは何の意味も持たない、ってのが大方分かってくると思います。

そして、ここまで書いてくれば大体想像付くとは思いますが、続く「データ型の説明」も事実上、「Pascalのデータ型」を説明してる、って事なんです(何じゃそりゃ)。


コンピュータが実際に取り扱える情報の多くは、次のいずれかの型で表現できるものか、または、それらを組み合わせて表現できるものです。すなわち、基本データ型として、

  • 整数型

  • 実数型

  • 文字型

  • 文字列型

  • 論理型

  • 番地型


の6つが存在します。それぞれの型について、具体的にどのような内容が表現されるか見てみます。

まあ、良いんですが……「番地型」って何だろ?ひょっとしてポインタの事言ってんのかしら(笑)?
どうも通大のテキストって「通大ローカル」の用語混ぜてるんで紛らわしいですよね。普通、学者連中は「用語の混乱」避ける為に用語に付いてはある程度コンセンサス取る筈なんですがねえ。
いずれにせよ、このテキストのレベルでは「ポインタ」なんて使わんだろ、っての(笑)。「全部列挙すれば良い」ってもんじゃあ無いのですよ。どうもこの辺も「ミニマリスト的なアプローチ」からは乖離している気があります(それ言っちゃうと実は文字型/文字列型なんかも解説の必要が本当にあるのか、疑わしいのですが)。


整数型

通常、-32768から+32767までの整数値からなるものです。これは16ビットで表現できる整数です。コンピュータシステムによっては、32ビットで表現できる整数をあつかうことができるように、倍長整数型(-2147483648から2147483647までの整数)を設けることがあります。


実数型

これは、2章で説明のあった浮動小数点表示で表現される値をとるものです。多くのシステムでは、32ビット幅の単精度実数型(有効桁数は7から8)と、64ビット幅の倍精度実数型(有効桁数は15から16)の二つがあり、必要とする精度によって使い分けます。


文字列と文字列型

通常使用する文字と、その並び(文字列)からなるものです。ひと昔前までは、コンピュータが扱える文字は、アルファベットと数字、それにいくつかの記号だけでした。しかし、現在では漢字も扱えるようになり、コンピュータは、日本人にとって、より身近なものになっています。


論理型

命題論理における"真"か"偽"の値をとるものと定義されます。なんらかの論理式の値を論理型変数に代入して、それを演算の順序制御に用いることがあります。


番地型

変数をコンピュータ内部の箱に例え、名前をつけました。このとき、名前をもつ箱には二つの値が付随することに注意してください。ひとつは、その箱の中身そのもの、もうひとつは、その箱のコンピュータのなかでの位置を示す番地です。変数の名前は、人間が識別するためのものですが、コンピュータ自身は、内部処理において、番地を用いて識別をおこなっています。
今までの型はコンピュータの外部にある情報をデータとして、その内部に取り込むためのものです。番地型はコンピュータの内部情報(番地)を取り扱うためのものです。



そうね、番地型、ってポインタの事を言ってるみたい。どの道、ポインタなんてこのレベルでは使いません。
さて、整数型、とか型かたカタKATAとか書かれていますが、「コンピュータシステムによって」違うのは当然ですが、もっと言っちゃうと言語によっても違いますし、同じ言語でも「実装」、つまりメーカーとかベンダが提供している「製品」によっても変わってきます。
従って、ここに書かれている事はあくまで「(90年代初頭の)Pascalを基本とした」データ型の「概要」を説明してるに過ぎません。これを全部このままマトモに受け取らないように。






Schemeによる例。
通大の「コンピュータ」のテキストに記述されている倍長整数型の上限値、2147483647を4倍したらどうなるか、の実験。
見て分かる通り、「問題無く」解が返されている。
一般に、動的型付け言語では、数学的な数値計算に於いての扱える上限値は単純にハードウェアに左右される。当然、内部では「もの凄い複雑な処理」が行われているだろうが、高級言語では基本的に「その手の問題をユーザーに見えないように設計する」のが肝でもある。
C言語やPascalは、別の言い方をすると、「極めてハードウェアレベルに近い」処理をしている、と言う事である。
そしてそれは「1970年代の」遺産、と言う意味でもある。



数学における数と、プログラムにおける数の違いに注意してください。数学において単に数といえば、通常は実数を意味します。ところが、コンピュータプログラミングにおいては、数といえば有理数です。それも、実際にコンピュータが扱うことができる数は、有理数全体ではなく、上のように、たとえ倍長整数型、倍精度実数型を使ったとしても、そのほんの一部であることに注意しなくてはいけません。したがって、コンピュータを用いて、数値計算を行うときには、そのほとんどの場合、近似計算となり誤差を常に意識しなくてはなりません。


これはその通りです。肝に銘じる事。


構造化型

上で説明したデータ型は、単一データのもので単純型といわれるものです。情報によっては、単一データを複数個組み合わせた構造化型と呼ばれるデータ型を用いる場合があります。
例として、個人のプロフィールを考えてみます。プロフィールとして必要な項目は、

  • 氏名

  • 年齢

  • 性別

  • 配偶者の有無

  • 住所

  • 電話番号

  • 職業


等が考えられます。それぞれは、上から順に文字列型、整数型、文字型、論理型、文字列型、文字列型、文字列型のデータですが、プロフィールはこれらをまとめて一つにした情報としてとらえるべきものです。これが構造化型のデータといわれるものです。プログラミング言語によっては、これを支援する機能を持っているものと、持っていないものがあります。一つ言語をマスターしようとするときは、構造化型を支援している言語をおすすめします(例えばPascal)。


下線部:亀田


だから十進BASICって「構造体」持ってねえだろ、っての(笑)。
しかも十進BASICで記述したプログラムを読ませる問題をレポートにしたりテストにしたり……そんなチグハグな話って無いでしょうが(笑)。テキストにこう書いてるんだったら、ソースからビルドしたPascalコンパイラをCD-ROMにして受講生に配布するなり何なり、ちっとはやれ、っての(笑)。
さて、またまた「玉川用語」なのか……。通常、「構造化型」なんて呼びません。普通は単に「構造体」って言います。そっちがポピュラーですね。
手元のPascalの入門書調べてみたんですが、Pascalではどうやら「構造型」とか呼ぶようです。これはPascalローカルの呼び方、ですね。
一般的には「構造体」ですよ、「構造体」。お間違いのないように。
いずれにせよ、このテキストの数値計算のレベルではやっぱり「構造体」なんて出番はありませんけどね。


配列

構造化型のなかで最も簡単でよく使われるものが配列です。これは同じ型のデータがいくつか順番に並んだ情報を表現するために使われます。
例えば、数学における3次元数ベクトル(3, -1.5, 0.3)は、実数型のデータが3つ順番に並んだ配列と表現されます。いま、その配列にvと名前をつければ、

v[1]・・・配列vの1番目の要素
v[2]・・・配列vの2番目の要素
v[3]・・・配列vの3番めの要素

として、構成要素を一つづつ取り出すことができます。また、行列は2次元配列(縦横に同一のデータ型を持つものが並んでいる)を用いて表現されます。あるm×n行列が、Aという名の実数型の2次元配列で表されるとき、

A[i, j]・・・行列の(i, j)成分

とします。ここで、多くの場合、iとjは整数型の変数を用います。
配列は、使用する前に

  • 変数 v : 1次元実数型配列 [1..3]

  • 変数 v : 2次元実数型配列 [1..m;1..n]


と宣言されます。ここで"[1..3]"によって、配列vの各要素が"1から3"までの整数で上のように参照できることを意味します。また、配列Aは、"1..m"と"1..n"、すなわち、1からmまでの整数と1からnまでの整数を2つ使用して上のように各要素を参照できる2次元配列であることを示しています。ただし、mとnは前もって宣言されている整数型の正の値を持つ定数です。

実際の処理の対象となる情報は非常に複雑です。手順、段取りを考えるとき、その複雑なものをコンピュータが扱える範囲で、データとして処理しやすいようにいかに表現するかはたいへん重要な問題となります。しかし、このテキストではこれ以上データ構造に関する問題には立ち入らないことにします

<演習問題>

  1. x = x + 1 と x <- x + 1 の違いを述べなさい。

  2. 個人の成績を構造化型のデータとして必要な項目とそのデータ型を述べなさい。

  3. クラスの成績はどのような構造化型データとして表せられますか。




下線部:亀田


さて。

構造化型のなかで最も簡単でよく使われるものが配列です

そうか(笑)?
まあ、確かにPascalでは配列は構造型使って実装されているようです。
しかし、一般的にそうか、と言われればそんな保証は無いでしょう。配列は配列だ、って考えた方が無難でしょうね。この辺、ちょっとウソがあります。

配列の宣言にせよ、「宣言する必要のない」言語もあるんで、この辺の話もマトモに受け取らない方が良い、です。

ちなみに、上の例では配列の要素を1から数えはじめていますが、これはPascalが配列の要素を1から数えはじめるから、です。
しかしながら、普通は配列の要素に限らず、何でも「0から数えはじめる」プログラミング言語の方が多い、のです。何故かと言うと、C言語が「0から数え始めていて」、C言語の影響を受けた言語の方が多いから、ですね。
実際、プログラム界隈では次のジョークがあります。

普通の人間は1から数を数えはじめるが、プログラマは0から数えはじめる。

恐らくPascal型を採用している言語は、知ってる限りで言うとBASICしか無いような気がします。


このテキストではこれ以上データ構造に関する問題には立ち入らないことにします


もう既に多すぎ、です(苦笑)。
取り合えず、このテキストに於いては、整数型、実数型、論理型、そして配列の4種類だけ押さえておけばまあ良いでしょう。かつ、ここでの解題では動的言語を用いるので、事実上そんなにデータ型について考えなくても良いです。レポート/テスト向けに最後に通大の指定言語(Fortran、BASIC、Pascal、C言語)で練習してみれば良いでしょう。

<演習問題回答例>

  1. 省略。ないしは、特定のローカル言語や、ないしは通大テキストローカルだけに通じる答えを書いても一般性を欠くので意味無し。

  2. 省略。ないしは、数値計算で使うようなデータ型でないのでやっても意味無し。また、構造体自体も言語によって記述形式が違うので一般的な答えは書けない。通大の「怪しい」疑似コードで書く気もないです。

  3. 同上。

0 コメント: