ポインタ

出典: へっぽこ実験ウィキ『八百科事典(アンサイクロペディア)』
ナビゲーションに移動 検索に移動

ポインタとは、C言語中の人である。中の人について語れることはヲタクの必須条件であるため、C言語使いを名乗る上での登竜門となっている。

Wikipedia
ユーモア欠落症患者のために、ウィキペディア専門家気取りたちが「ポインタ」の項目を執筆しています。

基本概念[編集]

C言語における変数や関数は、ソースコード上は別々の名前(シンボル)がついているが、実際には中の人がたった1人で演じ分けているだけである。演じ分けるポイントは「年齢」と「性別」だけであり、この「ポイント」を示すものがポインタである。

年齢は数値であるため、名前と違って変数に格納したり演算したりできることが大きな利点となる。

ポインタ渡し[編集]

わかりやすくするため、架空の例で説明する。なお、シスプリとは何の関係もない。

  • 可憐(15才、)
  • 咲耶(14才、妹)
  • 鞠絵(13才、妹)
  • 千影(12才、妹)
  • 春歌(11才、妹)
  • 鈴凛(10才、妹)
  • 四葉(9才、妹)
  • 白雪(8才、妹)
  • 衛(7才、妹)
  • 花穂(6才、妹)
  • 亞里亞(5才、妹)
  • 雛子(4才、妹)

下記のサンプルプログラムで可憐と書いたとき、実際には中の人は「15才の妹」を演じるのである。

#include <stdio.h>

int karen = 1;
int sakuya = 1;
 
void func1(int marie)
{
    marie++;
}

void func2(int *chikage)
{
    (*chikage)++;
}

int main(int ac, char **av)
{
    func1(karen);
    func2(&sakuya);
    printf("karen(%d) sakuya(%d)\n", karen, sakuya);
    return 0;
}

これを実行すると、以下のように表示される。

karen(1) sakuya(2)

func1が呼ばれるとき、karenに代入してあった数字「1、整数」が、marieに渡される。marieをインクリメントしても、karenは元のままである。このように、変数の内容を関数に渡すことを「値渡し」と呼ぶことがある。

func1実行前
変数名 karen sakuya marie
中の人 15才、妹 14才、妹 13才、妹
内容 1、整数 1、整数 1、整数
func1実行後
変数名 karen sakuya marie
中の人 15才、妹 14才、妹 13才、妹
内容 1、整数 1、整数 2、整数

一方func2が呼ばれるときは、sakuyaの中の人のポインタである「14才、妹」が、chikageに渡される。このため、func2では「14才、妹」の内容をインクリメントすることができ、sakuyaが更新されたのである。

func2実行前
変数名 karen sakuya chikage
中の人 15才、妹 14才、妹 12才、妹
内容 1、整数 1、整数 14才、妹
func2実行後
変数名 karen sakuya chikage
中の人 15才、妹 14才、妹 12才、妹
内容 1、整数 2、整数 14才、妹

さらに以下のようにしてみる。

void func2a(int **haruka)
{
    (**haruka)++;
}
 
/* 差し換え */
void func2(int *chikage)
{
    func2a(&chikage);
}

同じ結果が得られるが、これはまずfunc2が呼ばれるときにsakuyaの中の人のポインタである「14才、妹」がchikageに渡される。次にfunc2aが呼ばれるときにchikageの中の人のポインタである「12才、妹」がharukaに渡される。func2aでは「12才、妹」の内容である「14才、妹」をインクリメントした結果、sakuyaが更新されたのである。

func2実行前
変数名 karen sakuya chikage
中の人 15才、妹 14才、妹 12才、妹
内容 1、整数 1、整数 14才、妹
func2a実行前
変数名 karen sakuya chikage haruka
中の人 15才、妹 14才、妹 12才、妹 11才、妹
内容 1、整数 1、整数 14才、妹 12才、妹
func2a実行後
変数名 karen sakuya chikage haruka
中の人 15才、妹 14才、妹 12才、妹 11才、妹
内容 1、整数 2、整数 14才、妹 12才、妹
func2実行後
変数名 karen sakuya chikage
中の人 15才、妹 14才、妹 12才、妹
内容 1、整数 2、整数 14才、妹

今度は、以下のようにしてみる。

void func2b(int *rinrin)
{
    (*rinrin)++;
}
 
/* 差し換え */
void func2(int *chikage)
{
    func2b(chikage);
}

</source> 同じ結果が得られるが、これはまずfunc2が呼ばれるときにsakuyaの中の人のポインタである「14才、妹」がchikageに渡される。次にfunc2bが呼ばれるときに、chikageの内容である「14才、妹」がrinrinに渡される。func2bでは「14才、妹」をインクリメントして、sakuyaが更新される。

func2実行前
変数名 karen sakuya chikage
中の人 15才、妹 14才、妹 12才、妹
内容 1、整数 1、整数 14才、妹
func2b実行前
変数名 karen sakuya chikage rinrin
中の人 15才、妹 14才、妹 12才、妹 10才、妹
内容 1、整数 1、整数 14才、妹 14才、妹
func2b実行後
変数名 karen sakuya chikage rinrin
中の人 15才、妹 14才、妹 12才、妹 10才、妹
内容 1、整数 2、整数 14才、妹 14才、妹
func2実行後
変数名 karen sakuya chikage
中の人 15才、妹 14才、妹 12才、妹
内容 1、整数 2、整数 14才、妹


やあ、兄くん。元気そうだね。 ....実はアンサイクロペディアに「ポインタ渡し」の節を書いているんだが ....兄くんも一緒にどうかな。 ....兄くんと二人だけの世界でなら、永遠に褪せない秀逸な記事ができると思うんだ。
.... そうか、それは残念だ。私はいつまでも兄くんのことを待っているよ。 (Portal:スタブ)

構造体へのポインタ[編集]

これも架空の例であり、アイマスとは何の関係もない。

  • 三浦あずさ(20才、女性アイドル)
  • 如月千早(19才、女性アイドル)
  • 秋月律子(18才、女性アイドル)
  • 天海春香(17才、女性アイドル)
  • 菊地真(16才、女性アイドル)
  • 萩原雪歩(15才、女性アイドル)
  • 水瀬伊織(14才、女性アイドル)
  • 高槻やよい(13才、女性アイドル)
  • 双海亜美・真美(12才、女性アイドル)
#include	<stdio.h>

struct	idol_struct {
	char	*name;
	struct	idol_struct	*next;
};

extern	struct	idol_struct	azusa, chihaya, ritsuko, haruka, makoto, yukiho, iori, yayoi, ami;
struct	idol_struct	azusa = {"Azusa Miura", &chihaya};
struct	idol_struct	chihaya = {"Chihaya Kisaragi", &makoto};
struct	idol_struct	ritsuko = {"Ritsuko Akizuki", &haruka};
struct	idol_struct	haruka = {"Haruka Amami", &yukiho};
struct	idol_struct	makoto = {"Makoto Kikuchi", NULL};
struct	idol_struct	yukiho = {"Yukiho Hagiwara", NULL};
struct	idol_struct	iori = {"Iori Minase", &yayoi};
struct	idol_struct	yayoi = {"Yayoi Takatsuki", &ami};
struct	idol_struct	ami = {"Ami&Mami Futami", NULL};
struct	idol_struct	*mp[3] = {&ritsuko, &azusa, &iori};

int	main(int ac, char **av)
{
	struct	idol_struct	*p;
	int	i;
	
	for (i=0; i<3; i++) {
		printf("master piece %02d", i + 1);
		p = mp[i];
		while (p != NULL) {
			printf(" - %s", p->name);
			p = p->next;
		}
		printf("\n");
	}
	return 0;
} 

これを実行すると、以下のようになる。

master piece 01 - Ritsuko Akizuki - Haruka Amami - Yukiho Hagiwara
master piece 02 - Azusa Miura - Chihaya Kisaragi - Makoto Kikuchi
master piece 03 - Iori Minase - Yayoi Takatsuki - Ami&Mami Futami

このプログラムでは構造体中に、次の構造体の中の人のポインタを入れている。例えばazusa.nextは「19才、女性アイドル」であり、chihayaを指している。これを利用して、別々に定義された構造体を次々に処理していくようになっている。

変数名 azusa chihaya ritsuko haruka makoto yukiho iori yayoi ami
中の人 20才、
女性アイドル
19才、
女性アイドル
18才、
女性アイドル
17才、
女性アイドル
16才、
女性アイドル
15才、
女性アイドル
14才、
女性アイドル
13才、
女性アイドル
12才、
女性アイドル
内容(name) Azusa Miura Chihaya Kisaragi Ritsuko Akizuki Haruka Amami Makoto Kikuchi Yukiho Hagiwara Iori Minase Yayoi Takatsuki Ami&Mami Futami
内容(next) 19才、
女性アイドル
16才、
女性アイドル
17才、
女性アイドル
15才、
女性アイドル
(NULL) (NULL) 13才、
女性アイドル
12才、
女性アイドル
(NULL)

また、ポインタから構造体の中を指すために->を使用している。p->nextは、(*p).nextと同じである。

NULLは、指す先がない無人ポインタである。値としては0であるため、if (p != NULL)はif ((p))と等価である。

関連項目[編集]


NOW LOADING .... Loading bar blue.gif
ポインタの執筆者をロード中です。しばらくお待ちください。
待ちきれない場合は自分で執筆してください。 (Portal:スタブ)