I ♥ WordPress

[時間割:C言語]『はじめてのC言語完全入門』その7
2008/10/15 00:36 posted by kunkichi

連休明けですががんばります。ということで先週〜連休中にかけての分はそのうちアップします。今日は『C言語』。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


高度な選択文

  • else if、switch、ifのネスト、三項演算子、この辺はほぼ他言語と同じ。
  • 論理演算子のTIPS(というかひねりが効いたやり方)
    #include <stdio.h>
     
    int main()
    {
      int num1, num2;
      
      num1=0;
      num2=0;
      
      printf("整数? ");
      scanf("%d",&num1);
      
      if( num1 && (num2=100) )
        printf("num1=%d, num2=%d \n",num1,num2);
      else
        printf("num1=%d, num2=%d \n",num1,num2);
      
      return 0;
    }
    ./sample
    整数? 0
    num1=0, num2=0
    $ ./sample
    整数? 1
    num1=1, num2=100
    すなわち、&&を使った論理演算子の場合、最初の評価が偽だった場合は二つ目の評価は行わない。これを利用して、最初の評価が真だった場合のみ、代入を行う。
  • ||の場合は逆になり、最初が真だった場合は二つ目の評価を行わずに、最初が偽だった場合のみ、二つ目の評価で代入を行う。#include <stdio.h>
     
    int main()
    {
      int num1, num2;
      
      num1=0;
      num2=0;
      
      printf("整数? ");
      scanf("%d",&num1);
      
      if( num1 || (num2=100) )
        printf("num1=%d, num2=%d \n",num1,num2);
      else
        printf("num1=%d, num2=%d \n",num1,num2);
      
      return 0;
    }
    $ ./sample
    整数? 0
    num1=0, num2=100
    $ ./sample
    整数? 1
    num1=1, num2=0

反復文

  • 代入演算子、インクリメント、デクリメントは全く同じ。
  • while、do〜while、も同じ。do〜whileってあんまり使ったことないのだけど、入力検査に使うのは納得。
  • forも同じやけど、Cの場合、ループ変数の宣言は別途せなあかんと、、、

この辺、目新しいところは特になかったな。まあ初歩レベルってことで。

[時間割:C言語]『はじめてのC言語完全入門』その6
2008/10/07 20:54 posted by kunkichi

火曜日は『C言語』です。ちょいご無沙汰でした(^^; がんばります。

入力プログラムの応用

  • 定数はdefineを使う。#define TEISU 400
  • 行の最後までが有効になる。
  • スペースを含んでもOK。
  • 行をまたぐ場合は最後に¥を使う。
  • サンプル:#include <stdio.h>
    #define STR "word and space"
    #define PARAGRAPH "This is test for paragraph.\
    new line"
     
    int main()
    {
     
        printf("%s\n" , STR);
        printf("%s\n" , PARAGRAPH);
        return 0;
    }
    実行結果:$ ./en
    word and space
    This is test for paragraph. new line
  • 定数を置き換えるのはプリプロセッサの地点。gcc -E でプリプロセスだけ行うとよくわかる。$ gcc -E sample.c
    ・・・
    int main()
    {
     
        printf("%s\n" , "word and space");
        printf("%s\n" , "This is test for paragraph. new line");
        return 0;
    }

ifを使った選択文

  • 他言語とほとんど一緒。
  • 代入「式」を条件に使うif( a = 4 )a=4;
    if(a)
    と同じ。

やっと本の半分弱まで来ました。日々の努力が大事です。

[時間割:C言語]『はじめてのC言語完全入門』その5
2008/09/17 23:01 posted by kunkichi

火曜日の『C言語』を忘れてたので今日はがんばります!

12章「書式付き入力(その1)」から。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


  • scanfで定型フォーマットのデータを標準入力scanf("変換仕様",&変数名)
  • 複数のデータの場合は以下のような感じで空白で区切るとわかりやすい。scanf("%c %d %f",&変数名1,&変数名2,&変数名3)とりあえず、区切りの空白は無視されるものとする。
  • 標準入力に含まれる空白の扱いに注意
    • 空白をフィールドの区切りとする
    • 先頭部分の空白は削除される
    • ただし、文字の場合のみ空白も改行も含まれる形で入力をとる。
  • 変換仕様中の空白は無視されるとしたけど、実際は空白を含めると、入力データの空白を除去したのと同じになる。よって
    • 空白を入力したい場合は文字書式(%c)等の前に空白を入れない。
    • 空白を除去したい場合は文字書式(%c)等の前に空白を入れる。
  • scanfは決まったフォーマットでデータを受けとる前提になっているので、入力エラーに対応できない。ではどうするか?
  • scanfはintを返す。返す値は入力に成功したフィールドの数。これを使えば、エラーチェックができる。int ret;
    ret = scanf( "%d", &arg1 );
    retが1ならOK。0ならNG。でも数値は文字列ともとれるから、単に数値かどうかのチェックしかできない気がする。やっぱり正規表現がいいなぁ、それはまたあとで出てくるのかな?
  • ただし複数フィールドの場合に最初のフィールドでエラーになったらscanfはそこで終わってしまうので、その場合はscanfを複数に分ける。scanf("%d",&argv1);
    scanf("%c",&argv2);
    1行目でエラーになっても2行目のscanfは実行される。
  • EOF(キーボードならCtrl+D)の場合はscanfは-1を返す。
  • 入力フィールドをスキップするには、変換仕様のフォーマットに*を含める。scanf("%d %*d %d", &arg1, &arg3 )この例だと元データの2番目のフィールドはスキップされる。
  • EOF(キーボードならCtrl+D)の場合はscanfは-1を返す。
  • scanfの書式文字列に、変換仕様や空白以外を含めると、その文字列を含めた一連のフォーマット文字列の入力とすることができる。日付とかで便利かも。scanf("%s/%s/%s", &y, &m, &d);
  • scanfの書式文字列に”¥n”を含めると入力が終わらなくなるので注意!

ふぅ〜、とりあえずこれで入出力を両方できるようになりました。でもこれじゃちょっと入力チェックが弱すぎだな〜。もう少し進めば正規表現とかも出てくるのかな?がんばります。

『サーバ』は引き続き↓読んでます。アウトプットがなかなか難しいですが、そのうち。

コンピュータの構成と設計~ハードウエアとソフトウエアのインタフェース 第3版 (上)
デイビッド・A. パターソン ジョン・L. ヘネシー
日経BP社
売り上げランキング: 37621

[時間割:C言語]『はじめてのC言語完全入門』その4
2008/09/10 01:30 posted by kunkichi

火曜日は『C言語』です。張り切っていってみよう!

今日は11章「変数と定数」から。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


  • Cでは変数の宣言が必要。
    ex) int a とか int a = 1。後者は初期化も一括。
  • sizeof で変数やデータ型のメモリ上のサイズを調べることができる。
  • 定数の場合はconstで宣言する。ちなみに定数は大文字で定義することが一般的
    ex) const int A = 1
  • 列挙型。複数の定数をまとめて宣言。これちょっと今までなかったタイプの型だな。
    enum { a, b, c }
  • 列挙された定数=列挙定数は自動的に0,1,2…と値が割り当てられる
  • 値を指定することもできる。
    ex) enum { a, b=4, c }
    この場合、a、b、cはそれぞれ0、4、5となる。つまり、指定した場合でもその次の値は+1。
  • 列挙に名前を付けることができる。ex) enum DAY { MONDAY, TUESDAY, WEDNESDAY, … }
    これをさらに変数宣言で使用できる。
    ex) enum DAY w;
    でこれに列挙された定数を代入できる。
    ex) w = MONDAY; ・・・上の例だと結局のところ0になる。
  • タグの指定と変数宣言は一括で書ける
    ex) enum DAY { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY } var;
  • 型自体を作る感じと言った方がわかりやすいかも。

列挙型ってちょっと使いどころがピンとこなかったのだけど、いろいろ調べてみたところ、以下のサイトでなんとなく雰囲気はつかめた感じ。

ポイントをまとめると、

  • enum を用いると、 複数の数字に一意な「名前」を 付ける事が出来る。つまり、「名前」で判断すればよいということ。
  • フラグをたてるような場合に、フラグ名と値の関連を考えずにフラグ名だけで考えれるので便利。defineとかだとそれを意識しないといけない
  • switch文とか特に便利。
  • 配列とそろえると連想配列的な使い方も可能。
  • 値は整数のみ
  • 基本的な手順は以下。
    1. 列挙型の定義・・・タグを使ってenum型を定義する
    2. 変数宣言・・・定義された列挙タグを使って変数として定義
    3. 変数を使う・・・変数に列挙定数を代入したり。

簡単なスクリプトを試しに作ってみた。
#include <stdio.h>
 
enum weekday { MONDAY,
               TUESDAY,
               WEDNESDAY,
               THURSDAY,
               FRIDAY,
               SATURDAY,
               SUNDAY } w;
 
main()
{
  w = WEDNESDAY;
 
  switch(w){
  case MONDAY:
       printf("月曜日です。\n");
       break;
  case TUESDAY:
       printf("火曜日です。\n");
       break;
  case WEDNESDAY:
       printf("水曜日です。\n");
       break;
  case THURSDAY:
       printf("木曜日です。\n");
       break;
  case FRIDAY:
       printf("金曜日です。\n");
       break;
  case SATURDAY:
       printf("土曜日です。\n");
       break;
  case SUNDAY:
       printf("日曜日です。\n");
       break;
  }
  
  return 0;
}

内部的には整数だけど確かにこれだと値は意識しなくていいね。

[時間割:C言語]『はじめてのC言語完全入門』その3
2008/09/02 22:48 posted by kunkichi

火曜日は『C言語』です。8〜10章を終えました。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


書式付き文字列

  • printfみたいなフォーマット出力の話。この辺は他言語でもほぼ同じなのでスルー。

算術演算

  • いわゆる四則演算。printfと絡めて。ここも目新しくはない。
  • 『等差数列の和』とかって学校で習ったっけ?ちゅうか数学の知識なさ過ぎを痛感。「3n歳からの数学嫌い克服」フラグ発動。

いろいろなデータ型

  • ビットとかバイトとか。1バイト=256種類、2バイト=65536種類、4バイトの整数=たくさん、とか。1バイト整数だと0〜256と-128〜127、いわゆる符号あり/なしとか、ここもまあ普通。
  • データ型(文字型、文字列型、整数型、浮動小数点型)とリテラル。
  • 文字型を整数として出力するとASCIIコードが出力される。
  • 16進で出力。こういうのは意識してやったことないなー。
    ex) printf( “%#02x”, ‘A’); → “0×41″が出力される。
    • %x・・・16進で出力
    • #・・・16進であることを示す”0x”が先頭に追加される。
    • 02・・・最低2桁で出力、1桁の場合は先頭に0を追加。っていうか、0をつけるような文字列って制御文字しかなくって、いろいろ試してみたのだけど、printfの第2引数にどうやって指定するかがわかりませんですた。
    • ASCIIコード表開いてみたり(笑)

それほど目新しいところってあんまりなかったのだけど、数学の知識が明らかに足りないことがわかったのは収穫でした。16進とかもちょっと苦手意識あるし。でも、コンピュータが話す言葉にほんの少しでも近づいた感がしてちょっと嬉しい。目指せバイナリアン。

[時間割:C言語]『はじめてのC言語完全入門』その2
2008/09/01 00:25 posted by kunkichi

今日は復習ということで、火曜日にアップできていない『C言語』の復習とまとめをアップ。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


5〜7章まで進みました。

  • 単に外部ファイルを読み込むだけでなく、標準関数のエラーなども出力してくれるのでデバッグがしやすくなる。
  • 関数には、型と引数の定義が必要。
  • 引数を指定しない場合は、(void)。()内に何も指定しない場合は引数のチェックをスキップするという意味でちょっと異なる。
  • ただし、mailに限っては、通常3つの引数を取るので、引数を使わない場合は()を指定する。
  • 関数が返すデータ型を指定するのが型。値を返さない場合はvoidを指定する。
  • 型を省略するとintになる。
  • mainはintを返す。これがリターンコードになる。
  • エスケープシーケンスは二つ。
    • 文字列エスケープシーケンス
      • エスケープ文字列は\。文字列の中で解釈される。タブとか改行とか
    • 端末エスケープシーケンス
      • ANSIエスケープシーケンス。対応している端末ならOK。
      • エスケープ文字列はESC。よって、指定する場合はこれを16進で指定するので、”\x1b”となる。
      • 文字を修飾する場合は、”\x1b[パラメータm”。複数のパラメータを指定する場合は;で区切って”\x1b[パラメータ;パラメータ:パラメータm”とする。
      • 例えばputsで黄色で出力するなら
        puts(”\x1b[33m黄色です。”);
      • 一旦変更するとずっとそのままになってしまうので戻す場合は、
        puts(”\x1b[0m”);
      • 輝度とかも指定できる。1で高輝度。デフォは低輝度。

やっぱりCの場合、関数の定義の仕方というか、型とか引数の指定とか、その辺がきっちりしてる印象。

[時間割:C言語]『はじめてのC言語完全入門』
2008/08/19 23:40 posted by kunkichi

火曜日は「C言語」です。

C言語は大学の最初の頃に習ったんだけど、それ以来ほんと触ることなくて、PerlとかPHPとかのインタプリタ言語を触るようになってからはますます疎遠になってました。なので気分的には1からやり直す感じで。カーネルのソースコード読めるようにがんばります!

ということで、引っ張りだしてきたのは以前に買ってたCの入門書。塚越さんの本は読みやすくて好きなんだよね、Perlの本も良かったし。

はじめてのC言語 完全入門 (標準プログラマーズライブラリ)
塚越 一雄
技術評論社
売り上げランキング: 420963


1〜4章

  • コンパイル時のステージ。全部gccで一発でやってくれるけど一応。
    1. ソース書く(*.c)
    2. プリプロセス(gcc -E *.c > *.i)
      コンパイルの前処理。外部ファイルの読み込みとかマクロの置換とか。
    3. コンパイル(gcc -S *.c か *.i → *.s)
      アセンブラコードへの変換。
    4. アセンブル(gcc -c *.c か *.i か *.s → *.o)
      オブジェクトファイル(バイナリ)へ変換
    5. リンク(gcc *.o)オブジェクトファイルとライブラリをリンク
  • Cは外部宣言(宣言と関数定義)の集合。
  • 関数定義が一つ必要、かつ関数名はmainである必要がある。
  • nmコマンド初めて知った。オブジェクトやライブラリに含まれている関数とかを表示する。
  • リンク後の実行ファイルには作成した関数以外にもスタートアップモジュールが追加される。これがmainを呼び出す。

実はCの文法とかというよりも、こういう点が一番勉強したかったところ。バイナリアンになりたい。

このページの先頭へ