Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


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

1 プログラミング入門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. 芝浦工業大学情報工学科 青木 義満

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

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

4 各データ型の変換指定子 ※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

5 データ型の値の範囲を出力 ソースファイル名: 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

6 データ型のサイズ(バイト数)を表示 ソースファイル名: 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

7 関数のプロトタイプ宣言 プログラムの冒頭に,使用する関数の仕様を先に宣言しておく → 関数のプロトタイプ宣言
プログラムの冒頭に,使用する関数の仕様を先に宣言しておく  → 関数のプロトタイプ宣言 #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

8 関数のプロトタイプ宣言 関数のプロトタイプ宣言 (書く習慣をつけておいた方が良い) 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

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

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

11 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

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

13 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

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

15 記憶域の解放 ソースファイル: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

16 確保した領域への値の書き込み ソースファイル名: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

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

18 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

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

20 記憶域の大きさを変更 ソースファイル名: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

21 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

22 二次元配列の動的確保(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

23 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

24 二次元配列の動的確保(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

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

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


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

Similar presentations


Ads by Google