「超ひも理論をパパに習ってみた 天才物理学者・浪速阪教授の70分講義」
「ポインタ完全制覇」1-3 ポインタについて
1-3-1 そもそも、悪名高いポインタとは何か
- 「ポインタは、他の変数のアドレスを内容とする変数」(by K&R)
- ポインタといえば変数であるかのように説明されているが、実際には必ずしもそうではない(そうではないとはどういうことなんだろう)
- ポインタ型
- ポインタ型という型が単独で存在するわけではなく、他の型から派生することにより作り出される(他の型、int型とか、は単独で存在可能)
- 被参照型Tから派生されるポインタ型はTへのポインタと呼ぶ
- intへのポインタ型、doubleへのポインタ型とか
- ポインタ型は型なので、ポインタ型の変数もポインタ型の値もある
- ポインタ型という型が単独で存在するわけではなく、他の型から派生することにより作り出される(他の型、int型とか、は単独で存在可能)
intという型は整数を表す intは型なので、int型を格納するための変数もある int型の値もある ポインタ型も同じく、 ポインタ型はメモリアドレスを表す ポインタは型なので、ポインタを格納するための変数もある ポインタ型の値もある
1-3-2 ポインタに触れてみよう
#include <stdio.h> int main(void) { int hoge = 5; int piyo = 10; int *hoge_p; printf("&hoge..%p\n", (void*)&hoge); printf("&piyo..%p\n", (void*)&piyo); printf("&hoge_p..%p\n", (void*)&hoge_p); return 0; }
「C言語ポインタ完全制覇」題1章(1-2)
- メモリとアドレスの概念がわかっただけでは、ポインタをマスターすることは出来ない、それは「ドハマリの道」の第一歩でしかない
1-2-1 メモリとアドレス
- 今どきの計算機は8ビットを1つの単位(バイト)として扱っている
-
「C言語ポインタ完全制覇」題0章
0-1 本書の狙い
- 何故Cのポインタはこれほどまで難しいと言われてしまうのか、メモリとアドレスの概念(ポインタはアドレスだ的な観点)を知っただけではソレを使いこなすことは出来ない
- Cの奇妙な宣言の構文(宣言まわりの混乱した文法)
- 配列とポインタの妙な交換性
- ポインタはデータ構造を構築するために必須
- データ構造
- 連結リスト
- 木構造
- データ構造
0-2 対象読者と構成
- Cを使っているが(何不自由なく)、実は理解が曖昧「なんか皆がこう書いているから、同じように書いている」では悲しい
- 構成
- 第1章:まずは基礎から ー 予備知識と復習
- 第2章:実験してみよう ー Cはメモリをどう使うのか?
- 題3章:Cの文法を解き明かす ー 結局のところ、どういうことなのか?
- 第4章:定石集 ー 配列とポインタのよくある使い方
- 第5章:データ構造 ー ポインタの真の使い方
- 第6章:その他 ー 落ち葉拾い
「C言語ポインタ完全制覇」
- 著者のサポートページ http://www.kmaebashi.com/seiha2/index.html
- C言語の「配列」と「ポインタ」に関する本(この本の存在理由は、Cの文法がクソ、よくいえば宣言まわりのそれが奇ッ怪なため、それの問題点がゴロゴロ、それがいい加減)
- Cのプログラミングではポインタを避けて通ることは不可能
- Cの配列とポインタの間の妙な交換性
第0章 本書の狙いと対象読者―イントロダクション 0-1 本書の狙い 0-2 対象読者と構成 第1章 まずは基礎から―予備知識と復習 1-1 Cはどんな言語なのか 1-1-1 Cの生い立ち 【補足】アセンブリ言語? アセンブラ? 【補足】Bってどんな言語? 1-1-2 文法上の不備・不統一 1-1-3 Cのバイブル―K&R 1-1-4 ANSI C以前のC 1-1-5 ANSI C(C89/90) 1-1-6 C95 1-1-7 C99 1-1-8 C11 1-1-9 Cの理念 1-1-10 C言語の本体とは 1-1-11 Cは,スカラしか扱えない言語だった 1-2 メモリとアドレス 1-2-1 メモリとアドレス 1-2-2 メモリと変数 【補足】size_t型 1-2-3 メモリとプログラムの実行 1-3 ポインタについて 1-3-1 そもそも,悪名高いポインタとは何か 1-3-2 ポインタに触れてみよう 1-3-3 アドレス演算子,間接演算子,添字演算子 【補足】本書に載っているアドレスの値について―16進表記 【補足】宣言にまつわる混乱―どうすれば自然に読めるか? 【補足】hogeって何だ? 1-3-4 ポインタとアドレスの微妙な関係 【補足】実行時には,型の情報も変数名も,ない 1-3-5 ポインタ演算 1-3-6 ヌルポインタとは何か? 【補足】NULLと0と''と 1-3-7 実践―関数から複数の値を返してもらう 1-4 配列について 1-4-1 配列を使う 【補足】Cの配列はゼロから始まる 1-4-2 配列とポインタの微妙な関係 1-4-3 添字演算子[]は,配列とは無関係だ! 【補足】シンタックスシュガー 1-4-4 ポインタ演算という妙な機能はなぜあるのか? 1-4-5 ポインタ演算なんか使うのはやめてしまおう 【補足】引数を変更してよいのか? 1-4-6 関数の引数として配列を渡す(つもり) 【補足】配列を値渡しするなら 1-4-7 関数の仮引数の宣言の書き方 【補足】なぜCは,配列の範囲チェックをしてくれないのか? 1-4-8 C99の可変長配列―VLA 第2章 実験してみよう―Cはメモリをどう使うのか 2-1 仮想アドレス 【補足】scanf()について 【補足】未定義,未既定,処理系定義 2-2 Cのメモリの使い方 2-2-1 Cにおける変数の種類 【補足】記憶域クラス指定子 2-2-2 アドレスを表示させてみよう 2-3 関数と文字列リテラル 2-3-1 書き込み禁止領域 2-3-2 関数へのポインタ 2-4 静的変数 2-4-1 静的変数とは 2-4-2 分割コンパイルとリンク 2-5 自動変数(スタック) 2-5-1 領域の「使い回し」 2-5-2 関数呼び出しで何が起きるか? 【補足】呼び出し規約―Calling Convention 2-5-3 自動変数をどのように参照するのか 【補足】自動変数の領域は,関数を抜けたら解放される! 2-5-4 典型的なセキュリティホール―バッファオーバーフロー脆弱性 【補足】OSによるバッファオーバーフロー脆弱性対策 2-5-5 可変長引数 【補足】assert() 【補足】デバッグライト用の関数を作ってみよう 2-5-6 再帰呼び出し 2-5-7 C99の可変長配列(VLA)におけるスタック 2-6 malloc( )による動的な領域確保(ヒープ) 2-6-1 malloc( )の基礎 【補足】malloc( )の戻り値をキャストするべきか 2-6-2 malloc( )は「システムコール」か? 2-6-3 malloc( )で何が起きるのか? 2-6-4 free( )したあと,その領域はどうなるのか? 【補足】Valgrind 2-6-5 フラグメンテーション 2-6-6 malloc( )以外の動的メモリ確保関数 【補足】サイズが0でmalloc( ) 【補足】malloc( )の戻り値チェック 【補足】プログラムの終了時にもfree( )しなければいけないか? 2-7 アラインメント 【補足】構造体のメンバ名も,実行時には,ない 2-8 バイトオーダー 2-9 言語仕様と実装について―ごめんなさい,ここまでの内容はかなりウソです 第3章 Cの文法を解き明かす―結局のところ,どういうことなのか? 3-1 Cの宣言を解読する 3-1-1 英語で読め 3-1-2 Cの宣言を解読する 【補足】最近の言語だと,型は後置のものが多い 3-1-3 型名 【補足】せめて,間接演算子*が後置になっていれば…… 3-2 Cの型モデル 3-2-1 基本型と派生型 3-2-2 ポインタ型派生 3-2-3 配列型派生 3-2-4 「配列へのポインタ」とは何か? 3-2-5 C言語には,多次元配列は存在しない! 3-2-6 関数型派生 3-2-7 型のサイズを計算する 3-2-8 基本型 3-2-9 構造体と共用体 3-2-10 不完全型 3-3 式 3-3-1 式とデータ型 【補足】「式」に対するsizeof 3-3-2 左辺値とは何か―変数の2つの顔 【補足】左辺値という言葉の由来は? 3-3-3 配列→ポインタの読み替え 3-3-4 配列とポインタに関係する演算子 3-3-5 多次元配列 【補足】演算子の優先順位 3-4 続・Cの宣言を解読する 3-4-1 const修飾子 3-4-2 constをどう使うか?どこまで使えるか? 【補足】constは#defineの代わりになるか? 3-4-3 typedef 3-5 その他 3-5-1 関数の仮引数の宣言(ANSI C版) 【補足】関数の仮引数の宣言に関するK&Rでの説明 3-5-2 関数の仮引数の宣言(C99版) 3-5-3 空の[ ]について 【補足】定義と宣言 3-5-4 文字列リテラル 【補足】文字列リテラルは,charの「配列」だ 3-5-5 関数へのポインタにおける混乱 3-5-6 キャスト 3-5-7 練習―複雑な宣言を読んでみよう 3-6 頭に叩き込んでおくべきこと―配列とポインタは別物だ!! 3-6-1 なぜ混乱してしまうのか 3-6-2 式の中では 3-6-3 宣言では 第4章 定石集―配列とポインタのよくある使い方 4-1 基本的な使い方 4-1-1 戻り値以外の方法で値を返してもらう 4-1-2 配列を関数の引数として渡す 4-1-3 動的配列―malloc( )による可変長の配列 【補足】他言語の配列 4-2 組み合わせて使う 4-2-1 動的配列の配列 【補足】ワイド文字 4-2-2 動的配列の動的配列 4-2-3 コマンド行引数 4-2-4 引数経由でポインタを返してもらう 【補足】「ダブルポインタ」って何? 4-2-5 多次元配列を関数の引数として渡す 4-2-6 多次元配列を関数の引数として渡す(VLA版) 4-2-7 縦横可変の2次元配列をmalloc( )で確保する(C99) 【補足】Cの多次元配列は「行優先」だ 【補足】ANSI Cで縦横可変の2次元配列を実現する 【補足】JavaやC#の多次元配列 4-2-8 配列の動的配列 4-2-9 変に凝る前に,構造体の使用を考えよう 4-2-10 可変長構造体(ANSI C版) 【補足】可変長構造体確保時のサイズ指定について 4-2-11 フレキシブル配列メンバ(C99) 【補足】ポインタは,配列の最後の要素の次の要素まで向けられる 第5章 データ構造―ポインタの真の使い方 5-1 ケーススタディ1:単語の使用頻度を数える 5-1-1 例題の仕様について 【補足】各種言語における「ポインタ」の呼び方 【補足】参照渡し 5-1-2 設計 【補足】ヘッダファイルの書き方について 5-1-3 配列版 5-1-4 連結リスト版 【補足】ヘッダファイルのパブリックとプライベート 【補足】同時に複数のデータを扱えるようにするには 【補足】イテレータ 5-1-5 検索機能の追加 【補足】倍々ゲーム 5-1-6 その他のデータ構造 5-2 ケーススタディ2:ドローツールのデータ構造 5-2-1 例題の仕様について 5-2-2 各種の図形を表現する 【補足】座標系の話 5-2-3 Shape型 5-2-4 検討―他の方法は考えられないか 【補足】なんでも入る連結リスト 5-2-5 図形のグループ化 5-2-6 関数へのポインタの配列で処理を振り分ける 5-2-7 継承とポリモルフィズムへの道 【補足】本当に,draw( )をShapeに入れていいのか? 5-2-8 ポインタの怖さ 5-2-9 で,結局ポインタってのは何なのか? 第6章 その他―落ち穂拾い 6-1 新しい関数群 6-1-1 範囲チェックが追加された関数(C11) 【補足】restrictキーワード 6-1-2 静的な領域を使わないようにした関数(C11) 6-2 落とし穴 6-2-1 整数拡張 6-2-2 「古い」Cでfloat型の引数を使ったら 6-2-3 printf( )とscanf( ) 6-2-4 プロトタイプ宣言の光と影 6-3 イディオム 6-3-1 構造体宣言 6-3-2 自己参照構造体 6-3-3 構造体の相互参照 6-3-4 構造体のネスティング 6-3-5 共用体 6-3-6 無名構造体/共用体(C11) 6-3-7 配列の初期化 6-3-8 charへのポインタの配列の初期化 6-3-9 構造体の初期化 6-3-10 共用体の初期化 6-3-11 要素指示子付きの初期化(C99) 6-3-12 複合リテラル(C99)