C#
unsafe
CLR(共通言語ランタイム:Common Language Runtime)によって管理されないコードのことをunsafeと呼ぶ。
その一つがポインター。ポインターは参照型のポインターを取ることはできない。
int *ip; //型* 変数名;
int num = 10;
ip = # //numがint以外の型だったとしても警告は出さない。
&
は変数が指す参照(変数の箱の位置)を返す。*
は箱の中身(値)を返す。
ポインターは構造体にも使える。構造体のメンバーにアクセスする方法として、アロー演算子が用意されている。
struct MyStruct {
public int x;
public int y;
public int sum() { return x + y; }
}
MyStruct o = new MyStruct();
MyStruct* p;
p = &o;
p->x = 10;
p->y = 20;
Console.WriteLine("Sum is {0}", p->sum());
ポインター変数に算術演算を行うことが可能。ポインターアドレスをインクリメントすると、ポインターが指すメモリ領域の隣のポインター型のアドレスを指すようになります。
- int(0)<- Pointer | double(1) | int(2)
- インクリメント
- int(0) | double(1) | int(2) <- Pointer
デクリメントを行うと逆の現象が起こる。
ポインター変数同士の引き算も可能。この場合、2つのポインター変数のアドレスに囲まれた部分のメモリ領域のデータ個数を返す。ポインター変数同士の足し算はできない。
unsafeキーワード
ポインターを使用するコードはunsafeキーワードを使用する必要がある。unsafeキーワードは文単位でもメソッド単位でも使用できる。
//Mainメソッドの中ではポインターが使用できる。
unsafe static void Main() {
}
unsafeを含むコードが存在する場合コンパイル時にunsafeオプションを用いる必要がある。
## fixed
fixedの使用方法は2つ存在する。
1. ポインターが参照しているオブジェクトがGCの作用によって、移動することをさける。
```C#
ficxed(int* p = &o.num) {
//oは移動されない。
}
- 構造体に固定サイズの一次元配列を作成する場合
通常構造体のメンバを定義した場合、配列の参照が埋め込まれるが、fixedを利用することで配列全体を構造体に含めることができる。
構造体のサイズが重要な意味を持つ状況化などで有用。たとえば、C#で作成したデータ構造にC#以外の言語でアクセスする場合など。
fixed
もunsafe
コード中で使用することができる。
fixed int BufferedArray[10]
オブジェクト思考できていますか?
「プリミティブ型を全てラップする。」というのはオブジェクト思考っぽいけど、若干やりすぎなような気もしてしまう。「Getter/Setterを使用しない」を意識して開発をしたことがなかったので、一度意識してみようと思う。