プログラミングとかブログ

Unity/C#/SRPGStudio/RPGツクールMVの情報とかその他気になったことを調べて書きます。

【C言語】ポインタまとめ

ポインタとは

プログラムはメモリ上で動きます。
変数や関数は全部メモリ上の適当な位置(アドレス)に置かれます。
そのアドレスに対してアレコレ操作するのがポインタです。
もっとざっくり言うと、メモリ上のデータにアクセスする仕組みがポインタです。

文法

宣言

ポインタ変数の宣言でよくある記法は基本的に下記のどっちかですが、後述のアクセス操作を考えると前者のほうがいいです。

	int* pointer1;
	int *pointer2;

実は変数型と変数名の間に「*」を入れればポインタ変数になります。
半角スペースを入れようが入れまいが同じです。
つまりこれもOKです。(見たことないですが)

	int*pointer3;
	int    *    pointer4;
使い方

ポインタ変数にはアドレスが格納されます。
下記では変数aのアドレスをポインタ変数に入れています。
「&変数名」で変数のアドレスになります。

	int a = 1;
	int* pointer = &a;

ポインタが指すアドレスに入っているデータ(つまりaのデータ)にアクセスするには下記のように「*」を変数名の前につけます。

	int b = *pointer;

で、これが宣言時のint *pointer2;と紛らわしいので、宣言時はint* pointerのほうが誤解がないと思います。

配列

ポインタの配列と、配列へのポインタがあります。
紛らわしいです。
前者はポインタがいっぱい、後者はポインタが一個だけです。

ポインタの配列がこう。

	int* p[5];//int型ポインタ変数の配列p

	p[0] = 0x00000001;
	p[1] = 0x00000002;
	p[2] = 0x00000003;
	p[3] = 0x00000004;
	p[4] = 0x00000005;

デバッグするとこんな感じになります。
f:id:shirakamisauto:20180208194642j:plain

配列へのポインタがこう。

	int(*po)[5];//要素数5の配列用のポインタ変数po
	int arr[5] = {1,2,3,4,5};
	po = &arr;

デバッグするとこんな感じになります。
f:id:shirakamisauto:20180208194632j:plain

構造体

通常、構造体のメンバーにアクセスする際は「.」を使います。

	struct MyStruct
	{
		int i;
	};

	struct MyStruct s;
	s.i = 2;

しかし構造体のポインタ変数では代わりに「->」を使います。
違うものなので仕方ないですが、紛らわしいですね。

	struct MyStruct
	{
		int i;
	};

	struct MyStruct stru;
	stru.i = 2;

	struct MyStruct* structp;
	structp = &stru;

	structp->i = 6;

f:id:shirakamisauto:20180209191851j:plain

応用

リスト

多分課題でよく出てくる単純なリスト構造です。
構造体の中に、(主に自身と同じ)構造体のポインタ変数を仕込みます。
下記では構造体n1の次(next変数)に構造体n2を突っ込むことで、n1とn2を続きにしています。

	struct node {
		int data;
		struct node* next;
	};

	struct node n1;
	n1.data = 1;

	struct node n2;
	n2.data = 2;
	n2.next = NULL;

	n1.next = &n2;

デバッグで見るとこんな感じです。
f:id:shirakamisauto:20180208191131j:plain
今はNULLにしていますが、n2.nextに別のを突っ込めば、リストを無限につなげられます。