バイオプログラミング第1
榊原 康文、佐藤 健吾
ポインタ変数の扱い方
① ポインタ変数の宣言
int *p;
double *q;
② ポインタ変数へのアドレスの代入
int *p;
と宣言した時,p がポインタ変数int x;
と普通に宣言した変数に対して,p = &x;
はxのアドレスのポインタ変数
pへの代入
ポインタ変数の扱い方
③ 間接参照(演算子)
*【ポインタ変数名】
例)
*p;
により,ポインタ変数が指す変数の実体を 「間接的」に扱える
データ構造とポインタ
◼構造体とポインタ
◼関数とポインタ
◼配列とポインタ
◼文字列とポインタ
◼ポインタ配列
◼ポインタのポインタ
◼引数付きmain関数
構造体とポインタ
①構造体のポインタ変数宣言: struct 【構造体タグ名】 *【構造体ポインタ変数名】; 例) struct DATE_DATA { int year; int month; int day; }; struct DATE_DATA today;構造体とポインタ
②構造体ポインタ変数の参照・代入: 【構造体ポインタ変数名】->【メンバ名】 例) pdata=&today; とアドレスを代入した時, today.year ⇔ (*pdata).year ⇔ pdata->year (*【構造体ポインタ変数名】).【メンバ名】 と同じ関数とポインタ
①ポインタと関数引数: 「参照による呼出し (call by reference)」 アドレスを引数として関数へ渡す 「値による呼び出し (call by value)」 変数の値を引数として関数へ渡す 関数の引数はポインタでなければならない#include <stdio.h> int add20(int x);
void addp20(int *p); void main(void) { int k, m, n; m=10; n=10; k=add20(m); addp20(&n); printf(”%d %d %d”, k, m, n); } int add20(int x) { x+=20; return x; }
void addp20(int *p) {
*p+=20;
}
関数とポインタ
②ポインタを返す関数 戻り値がポインタとなる関数の宣言 【関数のデータ型】 *【関数名】 (【引数の並び】) 例) void main(void) { int *p; p=func(10); }int *func(int x) {
int y;
y=x+100;
return &y;
リンクによるリスト(
linked list)
◼
ポインタの応用
◼
動的な記憶領域の確保
リンクによるリスト
◼リストは,配列のような一種のデータ構造
①リストは,項目(要素)を一列に並べるという点 で配列と同じ ②配列では,逐次的な構造が(配列中の位置に よって)自然に指定される ③リストでは,項目を入れる「節点」の中に次の節 点を明示的に指示するリンク(ポインタ)を入れて 表現する配列: char a[5] a[0] a[1] a[2] a[3] a[4] A L I S T リンクによるリスト: A L I S T 節点 リンク
リンクによるリスト
①リストの先頭の節点を指すダミーの節点を設定して, これを「head」 (またはroot)で表すことにする ②リスト中で最後に位置する節点として,ダミーの節点を 設定して,これを「tail」で表すことにする A B C NULL head tailC言語によるリストの実現
◼準備
①記号定数 NULL ポインタに対する特別な値であることを示す記号 としてゼロの代わりに使われる ② sizeof 演算子 (教科書p-22) データ型や変数の大きさ(バイト数)を求める演算子 sizeof(【型名または変数名】) 例) sizeof(int) 4バイトC言語によるリストの実現
③型変換演算子 (キャスト演算子) (教科書p-40) データ型の一時的変換を行う演算子
(【型】) (【変数または式】)
C言語によるリストの実現
④動的に記憶領域を確保するための標準関数 malloc (【記憶領域の大きさ(バイト数 n)】) ⚫nバイトの初期化されていないメモリへのポインタ を返す ⚫mallocから返されるポインタは,適当な型に変換 されなければならない #include <stdlib.h>C言語によるリストの実現
⑤記憶領域を解放する free (【解放する記憶領域を指すポインタ】) ⚫必要の無くなった記憶領域をOSへ返す ⚫メモリの無駄をなくす #include <stdlib.h>C言語によるリストの実現
◼構造体を使った節点の実現
struct node { int key; struct node *next; }; 自己参照構造体: 構造体の中に,自分自身の構造体を参照するメンバを 含めることができる key next nodeC言語によるリストの実現
◼
mallocを使った新しい節点の動的な生成
struct node *x;
x=(struct node *) malloc(sizeof(*x));
◼
初期化
struct node *head, *tail; void listinitialize(void)
{
head = (struct node *) malloc(sizeof(* head)); tail = (struct node *) malloc(sizeof(* tail));
head->next = tail; tail->next = NULL; };
NULL
リスト表現を用いた操作
◼
挿入
◼削除
◼参照
挿入
A B C
NULL
head tail
挿入
A B C
NULL
head tail
◼
挿入
struct node *insertafter(int v, struct node *p) {
struct node *x;
x = (struct node *) malloc(sizeof(* x)); x->key = v;
x->next = p->next; p->next = x;
return x;
x
◼
挿入
struct node *insertafter(int v, struct node *p) {
struct node *x;
x = (struct node *) malloc(sizeof(* x)); x->key = v; x->next = p->next; p->next = x; return x; }; p v q
◼
削除
void deletenext(struct node *p) { struct node *x; x = p->next; p->next = p->next->next; free(x); }; x p v q
◼
削除
void deletenext(struct node *p) { struct node *x; x = p->next; p->next = p->next->next; free(x); }; p v q
◼
削除
void deletenext(struct node *p) { struct node *x; x = p->next; p->next = p->next->next; free(x); }; p q
◼
参照
k番目の要素(節点)の値を参照
⚫ リストでは,headからリンクをたどっていくしかない (kステップかかる)
配列: char a[5]
a[0] a[1] a[2] a[3] a[4]
A L I S T
リンクによるリスト:
◼
参照
x = head; while(x->next->next != NULL) { x = x->next; printf("%d ", x->key); }; A B C NULL head tail struct node *x;◼
節点の並べ変え
ポインタのつけかえのみ
A B C NULL head tail 例) Cをリストの末尾から先頭へ移動◼
節点の並べ変え
ポインタのつけかえのみ
A B C
NULL
◼
節点の並べ変え
ポインタのつけかえのみ
A B C
NULL
◼