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と入力すると
入力が終わるようにする