Transcript Document

C言語
情報理工学部 システム工学科 3年
H107035 亀窪祐太
H107042 纐纈琢真
H107087
西村智
目的
 バグの無いプログラムを書く
 入力時のエラーを無くそう
 汎用的なプログラムを書く
 型にとらわれないプログラムを書こう
 効率の良いプログラムを書く
 動的配列を使おう
目次
1.
入力時の問題点
3.
動的配列
 scanfを使わない入力
 利点
 問題点の改善策
 動的メモリ管理関数
 入力関数
 プログラム例
 バッファ削除
 フォーマット関数
 改善プログラムの解説
2.
型にとらわれないプログラム
 関数ポインタ
 void*とキャスト
 qsortを使った実例
4.
課題
型にとらわれないプログラム

ソート処理の場合
 比較関数を作る
 ソート関数に比較関数を渡す
C言語の場合
関数ポインタを使う
 voidポインタとキャストを使う

関数ポインタ
関数のアドレスを保持するポインタ
 以下のように宣言する
戻り値の型 (*ポインタ名) (引数のリスト);
 以下のように使う
int func(int x){
int (*p)(int x);
return x * 2;
p = func;
}

ans = (*p)(10); // または ans = p(10);
voidポインタとキャスト

voidポインタ (汎用ポインタとも呼ばれる)
あらゆるポインタ型に変換できる
 どのような型も受け取れる関数が作れる
 使用する際に使いたい型にキャストする

例
void *v;
int i;
v = &i;
// 受け取る場合
int *p = (int *)v; // 使用する場合
voidポインタの使用例

qsort : クイックソートを行う関数
void qsort(void* base, size_t n, size_t size, int(*fnc)(const void*, const void*))
// base
ソートする配列のアドレス
// n
配列の要素数
// size
配列の要素の大きさ
// fnc
比較関数のアドレス
比較関数
並べ替えるための基準を指定する関数
 2つの引数を持ち、int型を返り値とする
 返り値は

第1引数を先頭側にする場合、負の値
第2引数を先頭側にする場合、正の値
両者が同じなら0
Cによる動的配列
動的に連続領域を確保する
リスト構造を使用する
構造体とポインタを使用して実現
配列を動的に確保する
malloc, calloc, realloc, free関数を使用して実現
動的確保の利点
必要な場所で必要な量だけ確保する事が可能
好きな時に、解放する事が出来る
使用範囲が自由に決められる
効率の良いリソース(メモリ)の管理が可能になる
動的メモリ管理関数
動的メモリ領域の確保
void* malloc(size_t size)
void* calloc(size_t n, size_t size)
動的メモリ領域の再定義
void* realloc(void *ptr, size_t size)
動的メモリ領域の解放
void free(void *ptr)
必要なヘッダーファイル
<stdlib.h>
※ size_t とは
引数として与えるsizeの型
void* malloc(size_t size)
メモリを確保する関数
引数には確保したいメモリサイズ(バイト)を渡す
任意の領域を確保するために、
voidポインタ型が使われている
確保領域に合わせてキャストする必要あり
返り値
成功 :確保領域の先頭アドレス
失敗 :NULL
void* calloc(size_t n, size_t size)
mallocと同じく、メモリを確保する関数
キャストする必要あり
引数には配列の要素数と要素の
メモリサイズ(バイト)を渡す
返り値
成功 :確保領域の先頭アドレス
失敗 :NULL
確保した領域は
全てのビットを0で初期化されている
void* realloc(void *ptr,size_t size)
動的配列のサイズを再定義する
キャストする必要あり
前に確保した要素は最大で
sizeバイト分だけコピーされる
引数には再定義したい配列のアドレス、
再定義後のメモリサイズ(バイト)を指定する
返り値
成功 :確保領域の先頭アドレス
失敗 :NULL
reallocの注意点
引数がおかしくても文法エラーにならない
第一引数をNULLに
realloc(NULL, size_t size)→malloc(size_t size)
第二引数を0に
realloc(void *ptr, 0)→free(void *ptr)
void* free(void *ptr)
確保された領域を解放する関数
引数には動的に確保した領域のアドレスを渡す
動的に確保した領域以外のアドレスや既に解放した
アドレスを渡してはいけない
NULLを受け取った場合何もしない
解放し忘れていてもエラーにはならないので注意
解放し忘れる → メモリリークが起こる
malloc ・ calloc : プログラム例
freeで解放
忘れずに
realloc : プログラム例
課題
課題1
名前とGPAを持つ構造体を使った配列を最初に任
意の人数を入力させ、その人数分保管し、qsortを
使って並び変えよ
 mallocまたはcallocを使うこと
reallocを使わないこと
 ソート前とソート後のデータを表示すること
 並び変えの基準
 GPAの降順
 GPAが同じ場合は名前の昇順(辞書順)
課題2
課題1のプログラムを任意の数扱えるように
せよ
ユーザに任意の人数分のデータを入力させよ
名前入力時にendと入力すると
入力が終わるようにする