Objective-C 変数の型,ポインタ型,id型 【初級編 第10回】
ここまで変数をいろいろ扱ってきました。
普通にC言語で使用できるint型やdouble型、Objective-Cで拡張されて出てきたid型、
定義したクラスを型(前回)として使用しているものなどがありました。
その中でid型のときはオブジェクトを格納するときに「*」を使用していませんでしたが、クラスを型として使用した場合には
変数名の前に「*」をつけなければなりませんでした。その7や前回のコードで以下のようにしていた部分です。
id mine = [[Person alloc] init];
Person *mine = [[Person alloc] initWithWeight:65.0 height:1.72];
ポインタ型となるため「*」をつけるといいましたが、このポインタ型を含めて変数の型についてすこし説明しようと思います。
まず変数(variable)というのはプログラム内で使用する値などを格納しておくものです。
「変」という文字が使われていることからも,その中に格納する値は変更することができます。
プログラム上で変数を宣言するとメモリ上に必要な領域が確保されます。
複数の変数を作成する場合、それぞれの領域を区別する必要がありますね。
そのためにつけられる名前が変数名となります。
変数作成の際にCやObjective-Cなどの言語ではどのくらいのサイズでどういったデータ(整数、小数など)を
扱うためのメモリ領域を確保するのかを指定しなければなりません。
変数は「double weight」などのように変数の型を指定して「型 変数名」という宣言をする必要があります。
Objective-Cで使用できるデータ型には以下のようなものがあります。
型 | 内容 | サイズ |
---|---|---|
char | 1文字を表す | 8ビット |
short | 整数を表す | 16ビット |
int | 整数を表す | 32ビット |
long | 整数を表す | 32ビット |
float | 小数を表す | 32ビット |
double | 小数を表す | 64ビット |
BOOL | YES(1)かNO(0) | 8ビット |
long型とshort型は他の型と合わせて使用することがあります。
このとき変数へアクセスするということは実際に確保したメモリ領域に入っているデータにアクセスすることになります。
変数の中身は実データってことです。
しかしポインタというのはこれとは違っています。
ポインタの場合は変数に格納されているのは実データではなく、実データの格納されているメモリ領域の
アドレス(場所を示す値といえばいいでしょうか)であるということです。
実際に違いを確認してみましょう。ちょっと今までのコードとは離れますが下記のシンプルなコードで確認してみます。
全然Objective-Cの要素がないコードですが。
1 2 3 4 5 6 7 8 9 10 11 12 | #import <stdio.h> #import <objc/Object.h> int main(void){ int a=200; int b=100; int *c; c=&b; printf( "%Xn" ,a); printf( "%Xn" ,c); return 0; } |
以下が実行結果です。
32ビット整数を格納する変数aに200、変数bに100を代入します。その下にポインタである変数cを用意しています。
変数名の頭に「*」がついていますね。
そしてこのポインタであるcに変数bを代入していますが内容は100という値ではなく100が格納されているアドレスです。
C言語ではデータ型の変数のアドレスを表すときに頭に「&」をつけるのですが、Cを拡張しているObjective-Cでも
同様に使用できます。
最後に変数a、変数cをそれぞれ16進数表記にして表示させています。printfで表示させるときに%Xを使うと
後ろの変数の内容が16進数表示となります。
結果を見ると変数aは200を16進数にした「C8」という値になっていますが、変数cの表示結果はBFD62558という値になっています。
この値が100という値の格納されている領域のアドレスとなります。
メモリ上ではこんな感じですね。
私の環境ではポインタ変数のサイズは4バイトでした。以下のコードを付け加えると調べられます。
printf(“%d”,sizeof(int *));
前回のコードの「Person *」や「id」に変えても同様の結果となりました。
もし変数cの指しているアドレスに格納されている値を取り出したい場合は、以下のようにする必要があります。
変数の頭に「*」をつけます。宣言のときの「*」と一緒にしないよう気を付けてください。
printf(“%Xn”,*c);
このようにポインタ型とは実際のメモリ上に確保された領域の値を直接格納しているのではなく、その確保した部分の場所を示す
ものとなっています。
クラスをインスタンスする際にも確保した領域のアドレスが「init」などから返されているということになります。
そのためポインタ型で受け取る必要があります。
id型は「*」をつけていませんが、これはid型の場合、オブジェクトデータへのポインタ型として
最初から定義されているため必要がないようです。
今回のまとめとしては
- 変数とはデータの格納のためにメモリ上に確保された領域であり、その領域を区別するために変数名をつける
- Objective-Cではデータ型とポインタ型の変数があり、型を指定する必要がある
- ポインタ型は「*」をつけて変数宣言をする
- ポインタ型の変数内に格納されているのはメモリ上に確保した領域のアドレスである
- インスタンス化したオブジェクトはポインタ型で受け取る必要があるがid型はもともとポインタ型になっている
といったところでしょうか。
TechProjin 開発系基礎講座 連載リンク
基礎からPHPWEBアプリ解発を学ぶなら・・
PHP基礎 連載
AIなどで注目急上昇!これから学ぶならPython!!
独学で学ぶ-pythonプログラミング 連載
汎用性◎ 定番プログラミング言語JAVA
Java基礎講座 連載