2008年6月30日月曜日

第11章 文字列とポインタ(その3)

こつこつ。


  • 11-3 文字列を扱うライブラリ関数

    • う、演習1105がBus errorになってしまう。これ、配列でやったときも苦しんだような。
    • せっかくなので、道具箱のGDBを勉強してみることにする。

2008年6月28日土曜日

第11章 文字列とポインタ(その2)

復活! こつこつ。


  • 11-2 ポインタによる文字列の操作

    • そうか*s++は、評価した値を返した後にインクルメントするんだな。
    • ポインタらしく書くことの効用はやはり実行効率か。でもコンパイラの最適化能力があがってきているので、その価値は薄れている、と。



数日休むと頭がぼっとするな。。。

2008年6月23日月曜日

第11章 文字列とポインタ

おなかがいたい。。。こつこつ。


  • 11-1 文字列とポインタ

    • list1101:おお、char *ptr = "123";という初期化も可能なのか。
    • 気になるのは、配列 - 文字列 - ポインタという関連性が、言語としてのC言語において、構文糖衣なのかそれ以上の違いがあるのか、ということ。パタヘネによると、直接アセンブリ言語にコンパイルする場合は違いがある。でもgccはGENERICとかの中間表現に変換するから、そのときにどうなのか、ということも気になる。
    • list1103:まず、配列で初期化した識別子は、その配列が初期化時に確保した領域と結合しており、別の領域を指すように変更はできない。つまり、例えば、str = "DEF";という形での代入はできない。
    • list1104:次に、配列は領域の予約というか、事前確保が可能ということ。char str[6] = "ABC";としておけば、strが指す領域はchar*6確保され、保護される。しかし、int *ptr = "ABC"の場合は、ABC\0が文字列リテラルとしてメモリ上のどこかに生成されているとして、その先頭アドレスを指すということにすぎない。
    • というわけで、配列とポインタは、識別子管理テーブル(勝手につけた名前)の機構に関する違いがあるようだ。管理テーブル的にはポインタでやった場合は、文字列リテラルを格納するメモリ領域とは分離して、ポインタ自体の識別子と領域も別途管理されるということ。
    • しかし、識別子管理テーブルとかいっても仮想マシンがあるわけではないので、けっきょく中間言語だったりというコンパイラの仕様しだいなのか?
    • ところでC言語って、"ABC"という文字列リテラルは共有されるのかなぁ。char *ptr1 = "ABC"; char *ptr2 = "ABC";としたとき、ptr1とptr2は同じアドレスを指しているのか否か?
    • list1105:char *pt[3]ってありなんだ。。。



とりあえず、ここまで。

2008年6月22日日曜日

第10章 ポインタ (その3)

こつこつ。


  • 10-3 ポインタと配列

    • なんと。[]は演算子であり、vc[2]も2[vc]も同じことなんだ。。。
    • じぶんなりにポインタをまとめてみる。

      • int nx;
        によって、メモリ上にint型の値を格納する領域が確保される。その領域に対して値を読み書きするには、nxという変数名が使える。
      • この機構の背後には変数名の管理機構がある。それは次の機能をもっている。

        • nxという識別子が確保している領域がint型であるということ。
        • nxという識別子と確保領域のメモリアドレスとの紐づけ。

      • ひとつのプログラムの中でも識別子は複数存在し、これら管理情報は一種のテーブルを成している。
      • C言語では、このテーブルにアクセスすることができる。
      • まず、nxと紐付けられているアドレスの値を、&nxで得ることができる。これは、まあリテラルである。
      • アドレスをC言語の中で取り扱うにあたって、それ自身もC言語の型機構に適合させてしまう。
      • すなわち、ポインタ型という型を用意する。
      • ポインタ型は例えば、int *ptr;などと宣言する。
      • すると、ptr = &nx; などとできる。
      • これらは上に述べた識別子の機構にあてはめると次のようなことである。

        • ptrという識別子が確保している領域がintのポインタ型であるということ。
        • ptrという識別子と確保領域のメモリアドレスとの紐付け。

      • ポインタ(値)にはいくつかの演算が用意されている。
      • *演算子は、ポインタ(値)が値としてもっているメモリアドレスに格納されている値を指すことができる。
      • すなわち、*ptrはnxの別名と考えてよい。
      • 配列というのは、宣言以外の部分については、ポインタ型を用いたメモリ操作の構文糖衣と考えてもよい。
      • int vc[] = {1 , 1, 0};などとしたとする。
      • vcはこれ以降、配列の先頭要素のアドレスを保持するintのポインタ型の識別子である。
      • すなわち、vc = &vc[0]が成り立つ。
      • これによって、関数の引数に配列を与えたとき、関数の内部でその配列を操作した場合に、もとの配列が破壊的に操作される。
      • 仮引数における、int vc[]というのはint *vcと可換である。
      • ptr = &vc[0] (またはvc)としたとき、vc[i], *(ptr + i), ptr[i] は同じことの別表現である。
      • ポインタ値に対する算術はそのポインタ値が配列の一部を指すとき存在し、自然数を体とするものであり、その単位である1は、メモリアドレスの1ではなく、対象となる配列の要素の個数である。メモリアドレスでいうと型のsizeof分が1に換算される。

    • てな感じなのかなぁ。



とりあえず、ポインタの前半戦はおしまい。
次は、ポインタと文字列だ!

第10章 ポインタ (その2)

こつこつ。


  • 10-2 ポインタと関数

    • list1006を、gccではコンパイルできなかった。。。

      Compilation started at Sun Jun 22 00:11:06

      gcc -Wall list1006.cpp
      Undefined symbols:
      "___gxx_personality_v0", referenced from:
      ___gxx_personality_v0$non_lazy_ptr in ccNTC8X1.o
      ld: symbol(s) not found
      collect2: ld returned 1 exit status

      Compilation exited abnormally with code 1 at Sun Jun 22 00:11:07

    • おお、参照渡しは密結合を促進し、プログラムの品質を下げる可能性があるのか。なるほど。それがポインタを使う方式なら回避される理由がちょとわからん。同じことじゃないのか?
    • list1009は、私の環境ではほぼ正常に動作した。。。

      二つの実数を入力してください。
      実数X:53.5
      実数Y:21.68
      これらの値を交換しました。
      実数Xは53.500015です。
      実数Yは21.679993です。

    • *hogeに++演算子はつかえんないのか???



演習問題2つやるのにかなり時間がかかった。。。

2008年6月21日土曜日

第10章 ポインタ

コツコツ。


  • 10-1 ポインタ

    • 箱がでてくるとポインタの説明がこんがらがるような。。。
    • オブジェクトに対して、その識別子と型とアドレスを管理しているテーブルがあるだけであって、そのテーブルのアドレス自身が型に対応したポインタ型と呼ばれるオブジェクトであるってだけだと思うのだが。で、そのオブジェクトを操作する手段が提供されいる、と。



写経がすくなかったので、すぐに終わっちゃった。

2008年6月20日金曜日

第9章 文字列の基本(その2)

こつこつ。


  • 9-3 文字列の操作

    • そか、""はアリだけど、''はナシだよね。
    • 配列をベースに考えると、アルゴリズムはforやwhileのループを基本に考えるようになるけど、そうするとそのアルゴリズムが正しいかどうかの判断が結構めんどくさいなぁ。リストなら再帰を使いつつ、宣言的に書けるんだけど。



この節3日かかった。。。
やっとポインタ。

2008年6月17日火曜日

第9章 文字列の基本

さて、こつこつ。


  • 9-1 文字列とは

    • C言語では文字列は文字の配列なのか。。。なんかすごいな。たぶん、C言語における配列というのが、私のイメージよりももっとハードウエアよりなので、こういうことになるんだろうな。
    • おお。文字列である文字列リテラルと、文字列でない文字列リテラルがあるのか。

  • この節、短かかったので、もうひとつ。

  • 9-2 文字列の配列

    • 配列の配列が直列化されているところをみると、メモリが透けてみえる。。。


今日はここまで。

2008年6月16日月曜日

第8章 いろいろなプログラムを作ってみよう(その4)

こつこつ。


  • 8-4 入出力と文字

    • 文字ロジックにおける文字コードのとりあつかいのところは、Cがいかにも低レベルな言語だなぁと感じるところでした。善し悪しは別として。
    • 低レベルなんで、環境に密着したプログラミングができるわけですが、可搬性をもとめようとするとそれをマクロとかで隠蔽しなきゃいけなくて、そうすると結構複雑になるような? そしたらもともと言語で抽象化していた方がいいんでないかい?と思ってしまう。



次は文字列。ポインタまで後一歩!

2008年6月15日日曜日

第8章 いろいろなプログラムを作ってみよう(その3)

こつこつ。


  • 8-3 再帰

    • 特になし。



再帰もあっさり。
今日はここまで。

第8章 いろいろなプログラムを作ってみよう(その2)

今週後半は業務繁忙にてまったく手をつけられなかった。。。
今日からまたこつこつ。


  • 8-2 列挙体

    • 列挙体って何だかすごいものだな。。。シンボルを使いたいのだが、実態は数字というのが表にでているって感じなのかな。
    • エナムって読んでた。。。イニューム推奨なのね。
    • 列挙タグと変数名は別のシンボルテーブル、と。


    • enum season { Spring, Summer, Autumn, Winter, Invalid };
      enum sex { Male, Female, Invalid };

      とすると、Invalid重複!とコンパイラに怒られた。Warningじゃなくerror。これは厳しい、というか使いにくい。


今日はここまで。
久しぶりだと、忘れてるし、頭も動かない。
でもこつこつ。

2008年6月9日月曜日

第8章 いろいろなプログラムを作ってみよう

この章はてんこもりだな! 入門書なんでこのあたりはまとめてさらっとやるのかな?
引き続き、こつこつ。


  • 8-1 関数形式マクロ

    • 関数形式マクロの説明に、型の煩雑さんの回避というのはどうなのかなぁ。演算子が型を選ばない範囲でしかつかえないわけだし。こういうものを重宝に思うなら、そもそも識別子が型をもたない機構を導入すべきと思ってしまう。。。
    • これも副作用と呼ぶんだ。
    • 演習8-2:そうか、関数形式マクロはある意味置換だから、Cの文法は全て使えるんだ。
    • 関数形式マクロは、展開されると式になるようにする。そのためにコンマ演算子が有効。



さあ次は列挙体だ!

第7章 基本型(その2)

こつこつ。


  • 7-3 浮動小数点型

    • うん。特になし。

  • 7-4 演算

    • うぉ。型変換ルール、複雑。


この章、振り返ってみると、やたら整数に力がはいっていたような。まあ、計算機だからそんなもんか。
とりあえず、ここまで。

第7章 基本型

昨日は植田ジャパンのお祝いにかこつけて飲んだので、調子悪し。。。


  • 7-1 基本型と数

    • えっと、さすがに基数は知っていたので、もう一節。

  • 7-2 整数型と文字型

    • 自分の環境のlimits.h該当部分。

      #define SCHAR_MAX 127 /* min value for a signed char */
      #define SCHAR_MIN (-128) /* max value for a signed char */

      #define UCHAR_MAX 255 /* max value for an unsigned char */
      #define CHAR_MAX 127 /* max value for a char */
      #define CHAR_MIN (-128) /* min value for a char */

      #define USHRT_MAX 65535 /* max value for an unsigned short */
      #define SHRT_MAX 32767 /* max value for a short */
      #define SHRT_MIN (-32768) /* min value for a short */

      #define UINT_MAX 0xffffffff /* max value for an unsigned int */
      #define INT_MAX 2147483647 /* max value for an int */
      #define INT_MIN (-2147483647-1) /* min value for an int */

      #ifdef __LP64__
      #define ULONG_MAX 0xffffffffffffffffUL /* max unsigned long */
      #define LONG_MAX 0x7fffffffffffffffL /* max signed long */
      #define LONG_MIN (-0x7fffffffffffffffL-1) /* min signed long */
      #else /* !__LP64__ */
      #define ULONG_MAX 0xffffffffUL /* max unsigned long */
      #define LONG_MAX 2147483647L /* max signed long */
      #define LONG_MIN (-2147483647L-1) /* min signed long */
      #endif /* __LP64__ */

      #define ULLONG_MAX 0xffffffffffffffffULL /* max unsigned long long */
      #define LLONG_MAX 0x7fffffffffffffffLL /* max signed long long */
      #define LLONG_MIN (-0x7fffffffffffffffLL-1) /* min signed long long */

    • longはwordなのかな。
    • 整数定数が型をもつ、ということは、Cでは識別子と値の双方が型情報を保持している、ということかな?
    • 補数
    • 厳しくいうと、例えば1を0001としたときに、000まで1の補数として反転するのは、補数の考え方から外れているような。
    • 0001の1の補数は、数学的には0000じゃないか。そして、2の補数は0001。
    • 計算機の内部で負数の表現に利用しているのは、補数の「計算手順」であって、0001の1の補数を1110と呼ぶのは奇妙。
    • まあ、やりたいことはわかるんですが。



演習に結構時間がかかった。ここまで。

2008年6月7日土曜日

第6章 関数 (その3)

昨晩飲まなかったので、やっぱり調子がいい。


  • 6-3 有効範囲と記憶域期間

    • list0618。Cはレキシカルスコープ。



さあ、次は型だ!

2008年6月6日金曜日

第6章 関数 (その2)

こつこつ!


  • 6-2 関数の設計

    • list0610。なんで省略可能なexternをここで説明するのかなぁ?
    • list0611。配列は自動的に参照渡しなのか。。。



終わった。。。この節、長かったです。

2008年6月5日木曜日

第6章 関数

こつこつ。


  • 6-1 関数とは

    • むう。抽象化やコードの再利用の話をせずに、関数をやるのだな。
    • ()は演算子なんだ。
    • コンパクトなコードを書くことが、そんなに重要事項なのかなぁ。
    • 「値渡し」って、値でやりとりされるというよりも、オブジェクトがコピーされて渡されるということでいいのかな。値がオブジェクトであって、オブジェクトがそのまま渡されるとしたら話が違ってくるし。値渡し(pass by value)という言葉がいかんような。



昨日、久しぶりに酒を飲んだら、頭が、、、 酒は旨いが、いかん。

2008年6月4日水曜日

第5章 配列 (その3)

こつこつ。


  • 5-3 素数を求める

    • コンマ演算子はprognかな。



次はついに関数だ!

2008年6月3日火曜日

第5章 配列 (その2)

こつこつ。


  • 5-2 多次元配列

    • 多次元配列の初期化子の構文は、無用に柔軟じゃないか???



この節、2ページなので、手早く終了。

第5章 配列

こつこつ。


  • 5-1 配列

    • []は添字「演算子」なんだ。
    • for文とかの繰り返し構造って、ある意味、抽象化なような。
    • object-like macroではなくて、グローバル変数みたいなものはないのかな。
    • 変数名などの識別子の一部などはマクロで置換されない。なるほど、安全だが、制限的。プリプロセッサはある程度Cの構文は知っている、ということはありそうだ。
    • expressionを式と訳したのは、数学においても、コンピュータ科学においても、最大の損失ではないか。
    • list0512は、なんちゅうか、とても汚い。構造体への伏線かな。
    • list0513は、関数の伏線かな。



予期せず、この節、写経がおおかった。。。

2008年6月2日月曜日

第4章 プログラムの流れの繰り返し (その5)

こつこつ。


  • 4-5 プログラムの要素と書式

    • 識別子は、なんで先頭が非数字じゃないといかんのだろう? パーサにやさしいためかな?
    • ああ、この構文図ってBNFを図示したものなんだ。
    • なんと。隣接する文字列リテラルは自動連結される。



写経がないので、すぐ終わった。
もうひとつやる。

2008年6月1日日曜日

第4章 プログラムの流れの繰り返し (その4)

こつこつ。


  • 4-4 多重ループ

    • 変数のいろいろな使い方の例にもなっている。



今日はここまで。