講座準備 講座資料は次の URL から DL 可能 https://goo.gl/jnrfth 1
ポインタ講座 2017/01/06,09 fumi 2
はじめに ポインタはC 言語において理解が難しいとされる そのポインタを理解することを目的とする 講座は1 日で行うので 詳しいことは調べること 3
はじめに みなさん復習はしましたか? 4
& 演算子 & 演算子を使うと 変数のアドレスが得られる 例 :int fumi = 23; printf( %d n, &fumi); // 変数 fumiのアドレスが表示される 5
演習 1- アドレスを表示しよう 自分で変数を作り その中に値を代入 printf でアドレスとその内容を表示 イメージをつかもう 6
演習 1- アドレスを表示しよう ソースコード 実行結果 7
そもそもポインタとは? 8
ポインタとは アドレスを格納できる特殊な変数のこ と 9
メリット 上手く使うと実行速度が向上する メモリ効率が向上する コードの柔軟性が向上する 詳しいことは調べてみよう 10
デメリット 可読性が低くなる 誤った使い方をすると危険である 慣れてないと混乱しやすい 1 つ 1 つ整理すること 11
理解は難しい? 苦手意識を持ったら終わり 他のことと混ざらないように 何が異なるのか? よく考える事 実際は難しくない 12
ポインタのイメージ 変数などのアドレスを保存できる型の こと イメージ int f = 23; Int* u; u = &f; 番地内容 ( 変数名 ) 5022 5023 23 f,*u 5024 5025 5023 u 23 u は f を指している! ポインタみたい! 5026 アドレス 5023 5025 f 5023 u イメージ 13
使い方 (1) 型 * 変数名 または 型 * 変数名 でポ インタ変数として宣言できる 変数名 の状態でアドレスモード * 変数名 の状態で参照モード 後ほど説明するよ! 例 int* fumi; // ポインタ変数の宣言 14
使い方 (2) 必ず NULL で初期化をすること 例 : int *fumi =NULL; C++11 以降は nullptr が追加されている 例 : int *fumi = nullptr; Visual Studioではこちらを推奨します 詳しいことは調べてみよう 15
* について (1) C 言語では * マークは様々な場所で使われる わかりにくくなる原因の 1 つ 3 つ順番に説明するので混乱しないように 1 つ目は? かけ算の * 例 :fumi = 2*3; 乗算演算子という 16
* について (2) 残りの2つが混乱しやすい 2つ目は? ポインタ変数の宣言の時に使われる * 例 : int* fumi; // fumi というポインタ変数を宣言 17
* について (3) 3 つ目は? ポインタ変数の参照の時に使われる * 間接参照演算子という 例 :int fumi = 0; int *sofume = &fumi; // sofumeはfumiを指すポインタ *sofume = 23; // sofume(fumi) に 23 を代入 18
演習 2- ポインタを使う int 型の変数とポインタ変数を定義し ポインタ変数の中に変数のアドレスを入れてみよう ポインタ変数を元にデータを変化させてよう 19
演習 2- ポインタを使う ソースコード 実行結果 20
重要なこと (1) ポインタを使うときは 必ずNULLで初期化すること 初期化なしポインタはどこかを指している 自動的に初期化される場合も ( 環境依存 ) Visual Studioだと? 21
重要なこと (2) 関係のないアドレスの内容を上書きしないように気をつけること 無意識に誤ったアドレスを入れてしまうことがあり得る Visual Studioは検知してくれる ポインタ変数にも型判別がある 22
全てのアドレス プログラムは全てメモリ上にある なら 変数も配列も関数も構造体も全 てメモリ上にある ということはポインタが使えるのでは? 23
配列 (1) 実は配列の変数には 宣言時に確保さ れた領域の先頭のアドレスが入っている 例 :int array[5]; 5 個分の領域が確保される イメージ 番地 内容 ( 変数名 ) 5022 5023 array 5024 5025 5026 5027 5028 24
配列 (2) 領域を5つ確保と言うが 実際は型によって確保される領域の数は変わる 例 :char 1byte, int 4byte, etc サイズは環境依存 講座はこの例に従う 25
配列 (3) 配列のN 番目のデータの場所は変数のアドレス+ 型の大きさ N 例 : array + 4byte 3 // int 型のarray[3] // 合計で12 個の領域が確保される 26
[] 演算子 先頭アドレスから距離を指定 距離は 型の大きさ [] の中の数字 例 : int array[3]; // 4byte * 3 の領域を確保 配列参照演算子という ポインタ演算の簡易表記 27
ポインタは何に使う? ポインタはどこで使うべき? 何のために必要? 例えば 28
配列のメモリ確保 配列は [] 内の数値の分だけメモリを確保してくれた [] の中身は定数でなければならない ( 環境依存 ) 変数を使いたい時や実行まで定まらない時は? 29
メモリの動的確保 malloc という関数を用いると必要な分だけメモリ ( 配列 ) を確保できる malloc 関数 void *malloc(size_t size); // size バイト分のメモリを確保し先頭のアドレスを返す stdlib.h をインクルードする必要がある 確保に失敗すると NULL が返ってくる 30
変数の大きさ 普段の配列 ( 静的確保 ) では [] 演算子がバイト数を計算してくれていた intは4byte? どうやって大きさを判断する? 31
型ごとの大きさを調べる sizeof 演算子 sizeof( 型, 変数等 ) でサイズを調べられる 例 : sizeof (int) // int 型のバイト数が得られる 32
演習 3- 色んな型のサイズ Sizeof 演算子を使って様々な型のサイズ を調べてみよう! char, int, float, double, etc 33
演習 3- 色んな型のサイズ ソースコード 実行結果 34
メモリの動的確保をしてみる sizeの求め方はわかった void *malloc(size_t size); void ポインタ型? 合った型にキャストする必要がある 例 : int *data = (int *) malloc (sizeof(int) * n); 35
メモリの解放 malloc 関数で確保したメモリは free 関数で解放する 解放しないと ずっとメモリに残ったままになる 実行終了時には消えるが 解放することによって無駄なメモリを使わない free( ポインタ変数 ); 例 : free(ptr); 36
演習 4- 配列の動的確保 1~10の好きな数字を入力し その分だけ配列を作る その後順番に数値を入力し 最後に全ての値を表示する 37
時間がある人向け 二次配列を動的確保してみよう ポインタのポインタ 構造体を動的確保してみよう メンバ変数にアクセスするには.( ドット ) 演算子ではなく->( アロー ) 演算子を用いる 38
演習 4- 配列の動的確保 ソースコード 39
関数の返り値 今まで使ってきた関数は 返り値を1つのみしか指定できなかった ポインタを使うといくつも返せる? 今までの関数 int add(int a, int b){ return a+b; } 40
複数の戻り値 ポインタを使うことによって実現できる アドレスを渡せば変数の有効範囲が変わらない void func (int* a, int* b); // ポインタ渡し // intポインタ型が仮引数 // 実引数はアドレス 41
演習 5- 複数の戻り値を扱う int 型の変数を2つ渡すと その内容を入れ替えてくれる関数を作ろう a = 3, b = 5 a = 5, b = 3 さっきの関数を参考にしてみよう 42
演習 5- 複数の戻り値を扱う ソースコード 実行結果 43
配列を引数にする 配列を引数に持った関数を作るには? 変数には配列の先頭のアドレスが入っ ている 44
演習 6- 引数が配列の関数 演習 4を元に 配列の中身の平均値を求め出力する関数を作ろう 書式 void printave(, int size); の部分は自分で考えよう 45
時間がある人向け 二次配列を引数に持つ関数を作ってみよう 構造体を引数に持つ関数を作ってみよう 46
演習 6- 引数が配列の関数 ソースコード 実行結果 47
まとめ C 言語の特徴であるポインタの概念を理解すると様々なことができるようになる マスターすると 速度向上やメモリ節約などにつながる 48
C++ の世界へ この講座ではCを主に扱った より拡張した言語にC++ というものがある C++ は非常に便利 今回の内容を簡単に なおかつスマートに書けるようになる 49
他の言語の世界へ C 言語にはポインタという概念があり 柔軟に扱うことができる これらをあまり扱わずに済む言語もある C#,etc.. それぞれの言語の特徴や利点を調べてみよう 君に合った言語を見つけよう 50
さいごに これだけが全てではない 他にもたくさん ( 時間の都合等 ) const 修飾子を用いると良い C++ だと参照渡しという方法がある Etc.. C# も C++ もオブジェクト指向である ( 参考サイトをぜひ!) 51
やってほしいこと 今まで自分が出た講座をよく復習すること 講座で扱ってないことに挑戦すること 時間ある人向けの問題とか 他にどんなことができるか調べること ヘッダーファイルを使うとどれだけ便利になる? 52
参考サイト ( ポインタ関係 ) http://white-bear.info/archives/583 https://www.sgnet.co.jp/c/6-3.html http://9cguide.appspot.com/15-05.html http://qiita.com/go_astrayer/items/6 afb1592a8a5763fede1 53
参考サイト (C++ 関係 ) http://www.asahi-net.or.jp/~yf8kkbys/newcpp0.html http://www7b.biglobe.ne.jp/~robe/ cpphtml/ 54
参考サイト ( その他 ) https://qiita.com/ http://qiita.com/hirokidaichi/items/5 91ad96ab12938878fe1 http://tdak.hateblo.jp/entry/2014040 6/1396773476 55