02: 変数と標準入出力

Similar documents
02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

02: 変数と標準入出力

memo

02: 変数と標準入出力

02: 変数と標準入出力

PowerPoint プレゼンテーション

02: 変数と標準入出力

02: 変数と標準入出力

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

02: 変数と標準入出力

PowerPoint プレゼンテーション

02: 変数と標準入出力

Microsoft PowerPoint - 09.pptx

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Microsoft PowerPoint pptx

PowerPoint プレゼンテーション

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

02: 変数と標準入出力

02: 変数と標準入出力

プログラミング及び演習 第1回 講義概容・実行制御

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft PowerPoint - 11.pptx

Microsoft Word - 3new.doc

memo

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

Microsoft Word - Cプログラミング演習(11)

memo

プログラミング実習I

第1回 プログラミング演習3 センサーアプリケーション

Microsoft PowerPoint - 計算機言語 第7回.ppt

関数の中で宣言された変数の有効範囲はその関数の中だけです さっきの rectangle _s で宣言されている変数 s は他の関数では使用できません ( 別の関数で同じ名前の変数を宣言することはできますが 全く別の変数として扱われます このように ある関数の中で宣言されている変数のことをその関数の

gengo1-11

Microsoft PowerPoint - H22プログラミング第一(E)#12

第2回

Taro-ポインタ変数Ⅰ(公開版).j

情報処理 Ⅱ 2007 年 11 月 26 日 ( 月 )

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Microsoft PowerPoint - C++_第1回.pptx

Microsoft Word - Cプログラミング演習(12)

6 関数 6-1 関数とは少し長いプログラムを作るようになると 同じ処理を何度も行う場面が出てくる そのたびに処 理を書いていたのでは明らかに無駄であるし プログラム全体の見通しも悪くなる そこで登場す るのが 関数 である 関数を使うことを 関数を呼び出す ともいう どのように使うのか 実際に見て

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - kougi7.ppt

CプログラミングI

Prog1_10th

Microsoft PowerPoint ppt

program7app.ppt

Microsoft PowerPoint pptx[読み取り専用]

PowerPoint プレゼンテーション - 物理学情報処理演習

情報処理Ⅰ演習

Microsoft Word - Cプログラミング演習(10)

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

目次

FORTRAN( と C) によるプログラミング 5 ファイル入出力 ここではファイルからデータを読みこんだり ファイルにデータを書き出したりするプログラムを作成してみます はじめに テキスト形式で書かれたデータファイルに書かれているデータを読みこんで配列に代入し 標準出力に書き出すプログラムを作り

kiso2-09.key

cp-7. 配列

講習No.9


Microsoft PowerPoint pptx

プログラミングI第10回

Microsoft Word - no202.docx

PowerPoint プレゼンテーション

PowerPoint Presentation

Microsoft Word - no11.docx

Microsoft PowerPoint pptx

Microsoft PowerPoint - 5Chap15.ppt

プログラミング実習I

Microsoft PowerPoint - prog04.ppt

Microsoft PowerPoint - prog03.ppt

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

Microsoft PowerPoint - CproNt02.ppt [互換モード]

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

基礎プログラミング2015

PowerPoint プレゼンテーション

Prog1_6th

PowerPoint Template

計算機プログラミング

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

Microsoft PowerPoint - 第3回目.ppt [互換モード]

PowerPoint プレゼンテーション

Microsoft PowerPoint - prog07.ppt

Microsoft Word - no15.docx

ARToolKit プログラムの仕組み 1: ヘッダファイルのインクルード 2: Main 関数 3: Main Loop 関数 4: マウス入力処理関数 5: キーボード入力処理関数 6: 終了処理関数 3: Main Loop 関数 1カメラ画像の取得 2カメラ画像の描画 3マーカの検出と認識

講習No.12

gengo1-10

Microsoft Word - 03

PowerPoint プレゼンテーション - 物理学情報処理演習

講習No.1

講習No.10

gengo1-12

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

PowerPoint Presentation

Microsoft PowerPoint - kougi6.ppt

Prog1_12th

Transcription:

C プログラミング入門 基幹 7 ( 水 5) 1 11: 動的メモリ確保 Linux にログインし 以下の講義ページを開いておくこと http://www-it.sci.waseda.ac.jp/teachers/w48369 2/CPR1/ 2017-06-28

まとめ : ポインタを使った処理 2 内容呼び出し元の変数を書き換える文字列を渡す 配列を渡すファイルポインタ複数の値を返す大きな領域を確保する 説明第 9 回第 10 回第 10 回今回今回

ポインタの扱い 3

複数の値を返す 4 return は 1 つの値しか返せない 複数返すには 書きこんでもらいたい変数へのポインタを渡す 返り値を使って計算 例 :int 配列の最大 最小値を計算する int maximum(const int *a, int n); int minimum(const int *a, int n); 整数の配列の先頭ポインタとその個数 void minmax(const int *a, int n, int *m, int *M); 返り値はなし 最小値を書き込むアドレス ( 変数などへのポインタ ) 書き換えるので const がつかない 最大値を書き込むアドレス ( 変数などへのポインタ )

標準ライブラリ関数の例 5 整数部と小数部を求める関数 double modf(double value, double *iptr); 戻り値 :value の小数部 ( 符号付き ) iptr の指すメモリ領域 : 整数部 ( 符号付き ) #include <stdio.h> #include <math.h> double ipart double fpart int main(void) double ipart, fpart; fpart = modf(32.5, &ipart); 小数部 0.5 は戻り値として返る 32 0.5 変数 ipart のアドレスを渡すことで 関数 modf は ipart の中身を書き換えることができる

NULL ポインタ 6

ポインタ変数の初期値の注意 7 通常の変数同様 ポインタ変数も初期化されない しかし どこかは指している 初期化しないポインタ変数でアクセスすると危険 int *p; // 初期化なし *p = 100; 暗黙の初期化はされないので どこを指すアドレスが入っているかは不明 p

NULL ポインタによる安全策 8 以下の場合 null ポインタを入れるとよい 初期化ではアドレスを決定しない 今まで使っていたアドレス無効になった null ポインタを通したアクセスは発見しやすい ポインタ変数の値 ( アドレス ) が null ポインタの場合 斜線 int *p = NULL; を引いて どこも指示していないことを表現することがおおい *p = 100; p null ポインタが指す領域にアクセスすると システムが検知して 例外を発生する

null ポインタ 9 どのアドレスでもないことを示す特別な値 空ポインタともいう null ポインタに対してデリファレンス演算子 * を使うと例外 (null pointer exception) が発生する null ポインタ定数マクロ NULL を使って判定する 数値リテラル 0 は null ポインタに変換される <stddef.h> で定義されているが <stdio.h> などで自動的にインクルードされる

null ポインタ判定 10 以下のような書き方のバリエーションがある p が null であるか p が null でないか if(p == NULL) if(p!= NULL) if(p == 0) if(p!= 0) if(!p) if(p) if は常に式の評価値が 0 でないことを判定するので 上段の式と同じ意味になる

メモリ領域を作成する 11

基本型を返す関数 12... // 行列のトレースを返す関数 double trace3(const double Mat[3][3]) double tr = Mat[0][0]+Mat[1][1]+Mat[2][2]; return tr; } int main(void) double Mat[3][3] = 1, 2, 3 }, 4, 5, 6 }, 7, 8, 9 } }; trace3(mat); // => 15 double 型などの基本型を戻り値とする関数は簡単に作れる このような 配列サイズが固定の場合は 大きさを仮引数に書くことができる ただし 単に先頭アドレスが渡されてくることには変わらない ここで 配列のアドレス計算は Mat[i][j] = *(Mat + i*3 + j) であり 2 番目のサイズのみが使われるので Mat[3][3] という宣言は Mat[][3] と書いてもよく 1 番目の値は単に無視される 値そのものがコピーをされて伝搬していく

... // a から始まる 3 要素の連続値を返す int* seq3(int a) int s[] = a, a+1, a+2 }; return s; } 配列を返す関数? 13 配列のコピーはできないので 関数の中で用意した配列 配列の先頭へのポインタを返す? int main(void) int *seq = seq3(10); seq[0]; // => 10? seq[1]; // => 11? seq[2]; // => 12? 配列の先頭へのポインタを受け取る? この方法ではうまくいかない

関数内の配列のアドレスを返してはいけない 14 関数内で定義された配列変数は 通常の変数と同様に関数の実行が終了する際に消滅する... unsigned char *createnewimage(void) unsigned char img[512*512] = 0 }; return img; } int main(void) unsigned char *pimage;... pimage = createnewimage(); // この後ポインタ pimage を使って // アクセスしてはいけない... 配列の型を戻り値とする関数は作れないその代わり ポインタを返す createnewimage の領域この領域は関数の実行後 img 消滅してしまう pimage このポインタ ( アドレス ) の指す領域は値が返った時点ですでに無い

自動的に消滅しないメモリ領域を作る 15 動的メモリ確保 (dynamic memory allocation) 変数のような言語機能ではなく 標準ライブラリ関数を使って 直接 OS にメモリ領域を要求する 確保された領域は自由に使える 変数名はつかないので ポインタでアクセスする 自動的には消去されないので 自分で解放する

動的メモリの確保 16 malloc() 関数によって指定したバイト数のメモリ領域を確保する メモリ領域は初期化されない メモリ不足などで確保が失敗した場合 NULL ポインタが返る 確保された領域が置かれているところをヒープ (heap) という malloc() のプロトタイプ #include <stdlib.h> void *malloc(size_t size); 次のスライドで説明

確保されたメモリ領域の値 17 malloc は void * 型を返す 特定の型を表さない 任意のポインタ型に自動変換できる C++ では自動変換されないため static_cast が必要 int *pint; double *pdouble; pint = malloc(16); pint[0] = 100; // double の場合 // pdouble = malloc(16); // pdouble[0] = 3.14; sizeof(int) == 4, sizeof(double) == 8 の場合 ヒープ領域 100??????????? 3.14 int *pint 指し示すアドレスは同じだが 扱われ方が型によって異なる?? main のスタック領域 double *pdouble

サイズの指定 18 例 : int 型の 100 個の領域を確保 int *mem = malloc(sizeof(int) * 100); mem[0] ~ mem[99] としてアクセス

サイズの指定 19 例 : 画素値を unsigned char 型として w h のサイズのメモリ領域を確保 unsigned char *image = malloc(sizeof(unsigned char) * w * h); 座標 x, y に対して image[x+y*w] としてアクセス 0 x < w, 0 y < h w image[0+0*w] sizeof(unsigned char) は必ず 1 なので 書かなくてもよい h image[x+y*w]

動的メモリの確保 ( その他 ) 20 calloc(): malloc() と同じだが さらにゼロで初期化を行う size num バイトの領域を確保する メモリの全てのビットが 0 となるからと言って double などの型の値として 0 となるとは限らない realloc(): 確保された領域のサイズを変更 calloc(), realloc() のプロトタイプ #include <stdlib.h> void *calloc(size_t num, size_t size); void *realloc(void *ptr, size_t new_size);

動的メモリの解放 21 確保したメモリへのポインタを指定して その領域を解放する 解放した領域は使用してはならない NULL を入れておくと安全 既に解放済みのポインタに対して実行してはいけない (2 重解放エラー ) NULL ポインタを与えた場合は何もしない free() のプロトタイプ #include <stdlib.h> void free(void* ptr); どんな型のポインタも void * に自動的に変換される

例題 :PGM 画像 22 画像のためのメモリを自動的に確保する関数... // 画素値 0 で初期化された画像を動的に作成する unsigned char *createimage(int width, int height) int i; unsigned char *img = malloc(width * height); if(img == NULL) sizeof(unsigned char) == 1 な ので 掛けるのを省略 return NULL; } メモリ不足の場合は NULL を返す for(i = 0; i < width*height; ++i) img[i] = 0; return img; } すべてゼロで初期化する

例題 :PGM 画像 23 使い終わったら自分で free() する... int main(void) unsigned char *Image = NULL;... Image = createimage(640, 480);... free(image), Image = NULL; メモリ領域を解放する ポインタは無効になるので NULL ポインタを代入しておくとよい

用語 : メモリリーク (memory leak) 24 malloc() で動的確保した領域を free() で解放し忘れて メモリが圧迫されること 単純なプログラムではこの手のバグは見つけやすいが 秋期 C プログラミング で扱う複雑なデータ構造では発生しやすく 見つけづらいバグとなる

変数とポインタと動的メモリ確保の整理 25 メモリに領域を確保して値を読み書きする方法には 4 つある 分類生存期間スコープメモリ領域初期化 自動変数 ( ローカル変数 ) 大域変数 ( グローバル変数 ) 静的変数 (static 変数 ) 動的メモリ 定義位置からブロック終端まで プログラムの実行開始から終了まで プログラムの実行開始から終了まで 確保から解放まで 定義位置からブロック終端まで 定義位置からプログラム終了まで 定義位置からブロック終端まで 変数名で参照しない スタック 静的領域 静的領域 ヒープ 初期化が指定されている場合のみ ブロックに入るたびに初期化される プログラム開始時に 1 度だけ 初期化が指定されない場合 0 で初期化される 同上 malloc() はされない calloc() は 0 を書きこむ

配列変数と動的メモリ確保の比較 26 機能配列動的メモリ確保 サイズ 多次元 コピー 解放 自動変数の場合は あまり大きなサイズは確保できない 可能 ただし 関数などに次元やサイズを伝えられない 不可能 標準ライブラリ関数を利用 自動変数の場合 ブロックを抜けると自動的に消滅する ほとんど制限がない 単なるポインタなので不可能 不可能 標準ライブラリ関数を利用 free() によって自分で解放する アクセス 変数名が先頭へのポインタになる malloc() によって得られるアドレ スをポインタ変数に入れて扱う