プログラミング入門2 第12回 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科 青木 義満

Slides:



Advertisements
Similar presentations
プログラミング入門2 芝浦工業大学情報工学科青木 義満 第11回構造体. プログラミング入門2 2 構造体 5 人分のサッカー選手データ 全てのデータを関数に渡して,処理する場合 char name[5][256]; int assist[5]; int score[5]; void func( char.
Advertisements

アルゴリズムと データ構造 第 3 回 基本的なデータ構造(2) : 配列 1. 前回の復習 アルゴリズムの計算量 最悪(最大)計算量 計算量の漸近的評価 (オーダ)  多項式時間アルゴリズム( polynomial time algorithm )  指数時間アルゴリズム( exponential.
配列の宣言 配列要素の初期値 配列の上限 メモリ領域 多次元配列 配列の応用
プログラミング入門2 第1回 イントロダクション 芝浦工業大学情報工学科 青木 義満
ポインタ プログラミング入門2 第10回 芝浦工業大学情報工学科 青木 義満
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
プログラミング入門2 第10回 動的な領域確保 情報工学科 篠埜 功.
プログラミング入門2 第7回 情報工学科 篠埜 功.
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング入門2 ポインタについて補足 構造体 第11回 芝浦工業大学情報工学科 青木 義満、篠埜 功
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
基礎プログラミングおよび演習 第9回
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
第2回ネットワークプログラミング 中村 修.
プログラミング入門2 第6回 関数(2) 芝浦工業大学情報工学科 青木 義満
第8回 プログラミングⅡ 第8回
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
演習問題の答え #include #include #define NUM 5 typedef struct { // 構造体の定義 float shincho; // 身長 float taiju; // 体重 } shintai; void hyouji(shintai.
プログラミング入門2 第3回 繰り返し文 芝浦工業大学情報工学科 青木 義満
構造体 プログラミング入門2 芝浦工業大学情報工学科 青木 義満
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
プログラミング入門2 第5回 関数(1) 芝浦工業大学情報工学科 青木 義満
プログラミング入門2 ファイルの入出力 ポインタ 芝浦工業大学情報工学科 青木 義満
Computer Graphics 第3回 座標変換 芝浦工業大学情報工学科 青木 義満
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング 4 記憶の割り付け.
プログラミング入門2 第12回 構造体の配列 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科
プログラミング演習I 2003年5月7日(第4回) 木村巌.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
プログラミング入門2 第11回 情報工学科 篠埜 功.
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
第13章 文字の取り扱い方 13.1 文字と文字型関数 13.2 文字列 13.3 文字型配列への文字列の代入
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
プログラミング入門2 第12回 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科 青木 義満
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
2013年度 プログラミングⅡ ~ 計算してみよう ~.
2015年度 プログラミングⅡ ~ 計算してみよう ~.
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
第13章 文字の取り扱い方 13.1 文字と文字型変数 13.2 文字列 13.3 文字型配列への文字列の代入
情報処理Ⅱ 第2回 2006年10月13日(金).
11: 動的メモリ確保 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
ネットワーク・プログラミング Cプログラミングの基礎.
11: 動的メモリ確保 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
標準入出力、変数、演算子、エスケープシーケンス
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
第3回簡単なデータの入出力.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也.
プログラミング演習II 2003年12月10日(第7回) 木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
printf・scanf・変数・四則演算
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

プログラミング入門2 第12回 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科 青木 義満 I’ll get started with Introduction and Conventional works around our study, then mention our motivation and goal. Next, I’ll explain our 3D Face Modeling Method and its medical application. Finally, I’ll conclude this presentation with some future works. 芝浦工業大学情報工学科 青木 義満

データ型 データ型 整数型,文字型,浮動小数点数,倍精度型 C言語で扱うことのできるデータ型 データ型 意味 整数型 整数を表現する 文字型 文字を表現する 浮動小数点数 実数を表現する 倍精度型 精度の高い浮動小数点数を表現する C言語で扱うことのできるデータ型 プログラミング入門2

各データが扱える数値範囲 変数を用意する際,目的にあった(扱うデータの値の取りうる範囲,必要とされる精度)データ型を以下から選択して使用 ビット長 扱える数値の範囲  short 16 -32768 ~ +32767  int 32 -2147483648 ~ 2147483648  long  unsigned short 0 ~ 65535  unsigned int 0 ~ 4294967295  unsigned long  char 8 (-128 ~ 127)  unsigned char (0 ~ 255)  float 3.4 x 10-38 ~ 3.4 x 10+38  double 64 1.7 x 10-308 ~1.7 x 10+308 unsigned (符号なし)  → 0と正の数のみ扱える ※実際のデータサイズは,処理系によって異なる(特にint) プログラミング入門2

各データ型の変換指定子 ※scanfの場合,float は%f, double は %lf で読み込み 標準入出力のための変換指定子 指定子 意味 %d(%ld) 整数の10進数として出力 (longの場合,%ld) %u (%lu) 整数の符号なし10進数として出力 (unsigned longの場合,%lu) %f 浮動小数点表示(float, double共通) %c 1文字を出力 %s 文字列を出力 %p ポインタの値(アドレス)を出力 ※scanfの場合,float は%f, double は %lf で読み込み プログラミング入門2

データ型の値の範囲を出力 ソースファイル名: data.c 各データ型の値の取りうる範囲を出力 #include <stdio.h> #include <limits.h> int main(void) { printf("char : %d to %d\n", CHAR_MIN, CHAR_MAX); printf("unsigned char : %d to %d\n", 0, UCHAR_MAX); printf("short : %d to %d\n", SHRT_MIN, SHRT_MAX); printf("int : %d to %d\n", INT_MIN, INT_MAX); printf("long : %ld to %ld\n", LONG_MIN, LONG_MAX); printf("unsigned short : %u to %u\n", 0, USHRT_MAX); printf("unsigned int : %u to %u\n", 0, UINT_MAX); printf("unsigned long int: %lu to %lu\n", 0, ULONG_MAX); return(0); } 各データ型の値の範囲が定義(#define)されている プログラミング入門2

データ型のサイズ(バイト数)を表示 ソースファイル名: datasize.c 各データ型の大きさ(サイズ)を表示 #include <stdio.h> int main(void) { printf("sizeof(char) = %u\n", sizeof(char) ); printf("sizeof(short) = %u\n", sizeof(short) ); printf("sizeof(int) = %u\n", sizeof(int) ); printf("sizeof(long) = %u\n", sizeof(long) ); printf("sizeof(float) = %u\n", sizeof(float) ); printf("sizeof(double) = %u\n", sizeof(double) ); return(0); } sizeof( データ型 ) → データ型の大きさ(byte数) ※p.180に詳しい解説 プログラミング入門2

関数のプロトタイプ宣言 プログラムの冒頭に,使用する関数の仕様を先に宣言しておく → 関数のプロトタイプ宣言 プログラムの冒頭に,使用する関数の仕様を先に宣言しておく  → 関数のプロトタイプ宣言 #include <stdio.h> int main(void) { int x, y, z; x = 5; y = 10; z = func( x, y ); printf( "x+y = %d\n", z); return(0); } int func(int x, int y) return (x+y) ; 定義されていない(not defined)とエラー! 関数をmain関数の後に定義すると… プログラミング入門2

関数のプロトタイプ宣言 関数のプロトタイプ宣言 (書く習慣をつけておいた方が良い) int func(int x, int y); #include <stdio.h> int func(int x, int y); int main(void) { int x, y, z; x = 5; y = 10; z = func( x, y ); printf( "x+y = %d\n", z); return(0); } int func(int x, int y) return (x+y) ; 変数の型のみプログラムの冒頭に記述 (どんな引数を何個受け取り,どんな値を返すのか) 関数のプロトタイプ宣言 (書く習慣をつけておいた方が良い) プログラミング入門2

動的記憶域確保の必要性 動的な記憶域確保の必要性! これまでのプログラム 問題に応じて、適切なサイズの配列(記憶域)を確保する方法は? 配列の要素数は固定 あらかじめ大きめの配列を確保しておく #defineマクロで、要素数を定数として宣言し、その値を変更することで対応 → 静的な配列(記憶域)の確保 問題に応じて、適切なサイズの配列(記憶域)を確保する方法は? メモリの節約 プログラムの柔軟性向上 動的な記憶域確保の必要性! プログラミング入門2

calloc関数 : 記憶域の確保 必要になったら記憶域を動的(ダイナミック)に確保し、不要になったら解放する機能を提供 ヘッダ #include <stdlib.h> 形式 void *calloc(size_t n, size_t size ); 解説 大きさがsizeであるn個のオブジェクト(記憶域)の領域を確保する。 返却値 領域確保に成功した場合は、その領域の先頭へのポインタを返し、失敗した場合は、空ポインタ(NULL)を返す。 プログラミング入門2

Callc関数による記憶域の確保(1) ソースファイル名:calloc1.c 整数1個分の記憶域を動的に確保 #include <stdio.h> #include <stdlib.h> int main(void) { int *p; p = (int *)calloc( 1, sizeof(int) ); /*整数を1個分動的に確保*/ if( p == NULL ) puts(“記憶域の確保に失敗しました"); else { *p = 15; printf("*p = %d\n", *p ); } return(0); stdlib.hのインクルードを忘れずに! プログラミング入門2

Calloc関数の動作イメージ p = (int *)calloc( 1, sizeof(int) ); Intのデータ1個を動的に確保 500番地 *p sizeof( int ) p p Intのデータ1個を動的に確保 プログラミング入門2

void へのポインタ (void *)calloc(size_t n, size_t size ); p = (int *)calloc( 1, sizeof(int) ); Calloc関数の返却値 → void * 型 (voidへのポインタ型) 動的確保の対象: int, char, double, 構造体 など、様々なオブジェクト ・ 特定の型へのポインタを返す使用 → × ・ 融通の利く万能なポインタ void *  → ○ プログラムでは、確保する変数の型に合わせて、(void *)型のポインタを 任意のポインタ型にキャスト ※上の例では、int * 型 プログラミング入門2

free関数 : 記憶域の解放 動的に確保した記憶域は、不要になった時点で必ず解放 #include <stdlib.h> ヘッダ  #include <stdlib.h> 形式 void free( void *p ); 解説 Pが指す領域を開放する。但しpがNULLであれば何も行わない。 プログラミング入門2

記憶域の解放 ソースファイル:calloc2.c 記憶域の解放 free(p); 記憶域解放 記憶域確保 プログラミング入門2 #include <stdio.h> #include <stdlib.h> int main(void) { int *p; p = (int *)calloc( 1, sizeof(int) ); /*整数を1個分動的に確保*/ if( p == NULL ) puts(“記憶域の確保に失敗しました"); else { *p = 15; printf("*p = %d\n", *p );    free(p); /* 確保していた領域を解放 */ } return(0); free(p); p = (int *)calloc( 1, sizeof(int) ); 記憶域確保 プログラミング入門2

確保した領域への値の書き込み ソースファイル名:calloc3.c 記憶域を1個動的に確保し、キーボードから値を読込み #include <stdio.h> #include <stdlib.h> int main(void) { int *p; p = (int *)calloc( 1, sizeof(int) ); /*整数を1個分動的に確保*/ if( p == NULL ) puts(“記憶域の確保に失敗しました"); else {    printf(“整数を入力して下さい:”); scanf(“%d”, p); printf("*p = %d\n", *p ); } return(0); プログラミング入門2

1次元配列の動的確保 配列宣言の例 実行時に、扱うデータのサイズによって最適な配列を用意することが可能 int x[10];  実行時に、扱うデータのサイズによって最適な配列を用意することが可能 配列の要素数は定数式でなければならない → 要素数を変数とすることは不可能 → 開発時に要素数を決定する必要 ※もしくは、#defineで宣言した定数 配列の動的確保 → 実行時に要素数を決定! プログラミング入門2

1次元配列の確保 ソースファイル名:calloc4.c int型の配列を動的に確保 p[0] p[1] p[2] p[3] p[4] p #include <stdio.h> #include <stdlib.h> int main(void) { int no; /* 配列の要素数 */ int i; int *p; printf(“確保する配列の要素数:”); scanf(“%d”, &no); p = (int *)calloc( no, sizeof(int) ); /*整数を1個分動的に確保*/ if( p == NULL ) puts(“記憶域の確保に失敗しました"); else { for(i=0; i < no; i++) p[i] = i; for(i=0; i< no; i++) printf(“p[%d] = %d¥n”, i, p[i] ); free(p); } return(0); p[0] p[1] p[2] sizeof(int) * 5 p[3] p[4] p あたかも int p[5]; と宣言された配列が存在する かのように処理できる! プログラミング入門2

realloc : 確保した領域の大きさの変更 ヘッダ  #include <stdlib.h> 形式 void *realloc( void *ptr, size_t size ); *ptr : 大きさを変更したい領域へのポインタ size: 新しい大きさ 解説 ptrが指す記憶域の大きさをsizeバイトに変更する。変更前後の小さい方までのオブジェクトの内容は変わらない。 プログラミング入門2

記憶域の大きさを変更 ソースファイル名:calloc5.c 確保した記憶域の大きさを途中で変更 printf("Before----\n"); for(i=0;i<no;i++) printf("p[%d] = %d\n", i, p[i]); printf("Input new array size : "); scanf("%d", &no2); temp = (int *)realloc(p, no2 * sizeof(int) ); if(temp==NULL) puts("Cannot allocate memory.\n"); else{ p = temp; for(i=no; i < no2; i++) p[i] = i; printf("After----\n"); for(i=0;i<no2;i++) } free(p); return(0); #include <stdio.h> #include <stdlib.h> int main(void) { int no, no2; int i; int *p; int *temp; printf("Input size: "); scanf("%d", &no); p = (int *)calloc(no, sizeof(int)); if(p==NULL) puts("Cannot allocate memory.\n"); else { for(i=0;i<no;i++) p[i] = i; 領域サイズの変更 1回目の領域確保 領域の解放 プログラミング入門2

reallocの動作イメージ ←0 ←1 ←2 ←3 ←4 ←5 ←6 ←7 p[0] p[0] p[1] p[2] p[1] p[2] 要素数はno 新たに確保 した領域 p[6] p[7] ※realloc関数で確保済みの領域の大きさを変更する際には、 realloc関数の返却値が、空ポインタでないことを確認! 要素数はn2 プログラミング入門2

二次元配列の動的確保(1) ソースファイル名:calloc6.c height行3列の2次元配列を確保(行数固定) #include <stdio.h> #include <stdlib.h> int main(void) { int height; int (*p)[3]; int i, j; printf("Gyou :"); scanf("%d", &height); p = (int (*)[3])calloc(height * 3, sizeof(int)); if(p==NULL) puts("Cannot allocate memory.\n"); else{ for(i=0;i<height;i++) for(j=0;j<3;j++) p[i][j]=0; printf("p[%d][%d] = %d\n", i, j, p[i][j]); free(p); } return(0); 要素型がintで要素数が3の配列へのポインタ プログラミング入門2

2次元配列の動的確保 イメージ p[0] p[1] p[2] p[3] p[0][0] p[0][1] p[0][2] p[1][0] 2次元配列の動的確保 イメージ p[0][0] p[0][1] p[0] p[0][2] p[1][0] p[1][1] p[1] p[1][2] 4(height) * 3 * sizeof(int) p[2][0] p[2][1] p[2] p[2][2] p[3][0] p[3] p[3][1] p[3][2] ※n次元配列を動的に確保する際は、最高位のn次元の 要素数のみが可変。それ以外の次元の要素数は定数でなければならない プログラミング入門2

二次元配列の動的確保(2) 上級者向け ソースファイル名:calloc7.c ダブルポインタを用いた2次元配列の動的確保(行数列数共に可変) 二次元配列の動的確保(2) 上級者向け ソースファイル名:calloc7.c ダブルポインタを用いた2次元配列の動的確保(行数列数共に可変) #include <stdio.h> #include <stdlib.h> int main(void) { int height, width; int i,j; int **p; printf("Gyou: "); scanf("%d", &height); printf("Retsu: "); scanf("%d", &width); p= (int **)calloc(height, sizeof(int *)); if(p==NULL) printf("Cannot allocate memory.\n"); else{ for(i=0;i<height;i++) p[i]=NULL; for(i=0;i<height;i++){ p[i]=(int *)calloc(width, sizeof(int)); if(p[i]==NULL){ puts("Cannot allocate memory.\n"); goto Free; } for(i=0;i<height;i++) for(j=0;j<width;j++) p[i][j]=0; printf("p[%d][%d]=%d\n", i, j, p[i][j]); Free: free(p[i]); free(p); } return(0); プログラミング入門2

演習課題 構造体配列の動的確保(kadai12-1.c) 以下のpoint構造体について、 プログラム中で扱える点の数を可変にしたい。 実行時にキーボードから点の数を入力し、それにより動的に構造体の配列を確保するプログラムを作成せよ。 確保後、全ての座標値を0.0で初期化し、その結果を表示せよ。 最後に確保した領域を解放するのを忘れずに! typedef struct { double x; double y; } point; プログラミング入門2

演習課題 2次元配列の動的確保(kadai12-2.c) N x 3の行列を動的に確保し、2つの行列の和を表示するプログラムを作成せよ。 課題提出方法 ・ソースファイル2つをメール添付にて ・期限: 1/15(火)13:00まで ・題目: pro2-12 学籍番号 苗字 プログラミング入門2