Objective-C Primer 番外編 徹底C復習 6.構造体

構造体はデータ型の一種類という位置付けになりますが、今までのデータ型とは1つ大きな違いがあります。それはユーザー(プログラマ)が型の宣言をしなければいけないという事です。
 今まで使ってきたint, char, ポインター、そしてviva Cocoa ホームページで紹介している float, double, BOOLなどはデータ型の宣言を、言語の仕様としてすでに済ませてあります。ですからいきなり、
int    intVal;
と変数の宣言ができました。
この時点で、もし「int」というデータ型の宣言がなされていなければコンパイラはエラーを返します。しかし構造体は「ユーザーが作る新しいデータ型」なのでユーザーが宣言をしなければコンパイラにとってはまったく未知の型となり、エラーとなってしまいます。

フレームワークなどで使われる最初から宣言されている構造体もあります


 では「seito」という新しい構造体のデータ型を宣言して実際にそれを使ってみます。
サンプルコードは seito.zip からダウンロードできます。



seito.c


d0122908_14481757.gif

コード説明

ソースコードのカラーリングは初期設定から変更しています。カラーリングがプログラムに影響することはありません。たんに見やすさのためだけです。


1行目:このプログラムの中で使われている puts()、printf()、fgets()などの定義がなされているファイル stdio.h ファイルを読み込んでいます。このようなファイルのことをヘッダファイルと呼びます。なお以上に述べた3つの関数はすべてC言語の関数です。
3行目:「#define A B」で、コンパイルする時にAの文字列をBと解釈してコンパイルしろ、と指示していることになります。大変良く使われる方法でこのプログラムの中でもここを書き換えるだけで5か所の数値を1度に書き換えられます。このAの文字列のことを記号定数と呼びます。記号定数はこのように通常すべて大文字で書かれます。
5行目〜9行目:構造体の宣言を行っています。宣言は「struct(キーワード) + 構造体名(任意の名前)」ではじまり「{」と「 }」の間にカンマ「;」で区切った通常の変数宣言を行っていきます。最後の「}」の後にもカンマ「;」を付けることを忘れないようにしましょう。
11〜12行目:自作関数のプロトタイプです。「プロトタイプ」については viva Cocoa ホームページの Objective-C Primer 第4回の「Column」(ページの一番最後の段落です) をご覧になってください。
12行目では引数として「構造体seito型のポインター変数 b」を渡しています
15行目:構造体 seito型の sei という変数を宣言しています。
16行目:記号定数「MOJISUU」を使って char 型を100個並べた配列 ss を宣言しています。
18行目:puts()関数は引数「( )の中」で指定した文字列をコンソール(ターミナル)に表示して自動で改行します。この例の場合は改行だけして欲しいので空の文字列("")を引数として指定しています。
19行目:printf()関数については、このvivaCocoaブログの「Objective-C Primer 番外編 徹底C復習 2.変数」の「コード説明」を見てください。
20行目:fgets()関数は第1引数(この場合はsei.namae)で指定した変数に、第2引数(この場合はMOJISUUすなわち100)で指定した文字数を上限として、第3引数(この場合はstdin)で指定したファイルから文字を読み込みます。この例の場合はファイルではなくてstdinから文字列を読み込む指定になっています。stdinとは「標準インプット」のことで特に何も指定のないかぎりはキーボードからの入力のことを指します。それぞれの引数はこのようにカンマ「,」で区切ります
35行目:ポインター型以外の変数を引数「( )の中」でポインター型として指定したい場合はその変数名の前に「&」を付けます
44行目
メンバ変数(構造体の中の変数のことをこのように呼びます)にアクセスするために「a.namae」とドット演算子「.」を使っています。その構造体変数がポインターでなければこのドット演算子を使います。一方、57行目のようにその構造体変数がポインターであれば内部のメンバ変数にアクセスするには「b->namae」のようにアロー演算子「->」を使います。

50行目:引数として受け取った「構造体seito型の変数 a」のメモリー上のサイズを計っています。sizeof演算子についての説明は viva Cocoa ホームページの「C言語予約語一覧」をご覧になって下さい。




実行画面は以下のようになります。

d0122908_9504876.gif

cd Desktop/vivacocoa   デスクトップのvivacocoaフォルダに移動しています
cc seito.c          ソースファイルをコンパイルしています。
./a.out           出来上がった実行ファイルを実行しています

いろいろな入力を試してみてください。
 「名前」欄は、日本語、英語、スペース、数字、なんでも読み込んで表示すると思います。最高文字数を100と記号定数「MOJISUU」で指定していましたね。この100文字を超えた場合はどうなるのかも試してみましょう。なおこの100文字とは半角文字で100文字です。

 「点数」欄は、小数点数は切り捨て。スペースの空いた数字もスペース以降切り捨て。「50点」などと数字以外の文字が混じった場合も数字以外は切り捨て、と上手くいっているみたいです。しかし「点数」としての0から100以外の数字が入力された場合には再入力が促されるようにしたいですね。最初の文字を数字以外にすると「0」と認識されてしまうこともなおしたいですね。

 「評価」欄は「A」「B」「C」「D」だけにしたいと思います。ここはユーザーに入力してもらうのではなく点数から自動で算出できるようにしたいですね。
*註釈1

 これらのことは「オブジェクト」の章でやってみましょう。
次回からいよいよObjective-Cの文法に入っていきます。 viva Cocoa ホームページから、この Objective-C Primer を読まれてきたかたは、そろそろ Objective-C へ移行する体力がついてきたと思います。まだ制御文は if文しか説明していません。配列の詳しい説明もしていません。他にも一杯知っておかなければならないC言語の決まりはあります。しかし次回で「オブジェクト」を作ってみましょう。大丈夫でしょう。この章を理解できるなら一気にオブジェクトもやってしまいましょう。

注意.1
「制御文はif文しか説明していません。」
と書いていますが、次の「クラス」の説明を開始してからやはり制御文の説明をしておく必要性を感じたので、第4回と第5回に差し入れる形ですべての制御文の説明をしました。
注意.2
このブログの「Objective-C Primer 番外編」は、ホームページの「Objective-C Primer」の続編の形で書かれています。viva Cocoa ホームページの Objective-C Primer を読まれていないかたは、できたら読まれることをおすすめします。


 最後に、「引数として受け取ったデータ量」は、seitoHyoujiA、seitoHyoujiB のそれぞれの関数が呼び出された時に引数として受け取った変数のデータ量です。
 seitoHyoujiAは構造体のまるまるコピーを受け取っています。容量が108バイトあることが分かります。
 seito HyoujiBは引数として構造体のポインターを受け取っています。容量はわずか4バイトで済んでいます。
 ソースファイルの3行目を#define MOJISUU 1000 などと最後の数字を変えてみましょう。この場合に関数 seitoHyoujiA が受け取った変数のサイズがいくらになるか、「seito.c」ファイルをコンパイルしなおして実行画面で確認してみましょう。seitoHyoujiA関数はサイズが変わりますが、seitoHyoujiB関数ではサイズは変わりませんね。

註釈1
評価欄に日本文字を入力すると文字が化けて表示されます。これはこの変数hyoukaが先頭の1バイトしか受け取らないからです。日本文字は1文字2バイトの容量があります。1バイトだけでは正しい文字になりません。

[PR]
by vivacocoa | 2007-05-04 22:46


<< Objective-C Pri... Objective-C Pri... >>