Strings of Life

PHP/Phalcon/MySQL/JavaScript/RegExp/Ruby/Perl/ActionScript

タグ:C

  • 関数内で変数を宣言すると、コンピュータはスタックと呼ばれるメモリ部分に変数を格納する
  • 関数の外側で変数を宣言すると、コンピュータはメモリのグローバルセクションに変数を格納する

変数のメモリアドレスを知るには、&演算子を使う。

変数のアドレスは、メモリ内の変数の位置を表す。 そのため、アドレスはポインタとも呼ばれる。

メモリアドレスの内容を読み取ったり、設定したりするには、*演算子を使う。

メモリポインタの仕様

#include <stdio.h>

int main
{
    int x = 4;
    printf("xの格納位置は%p\n", &x);
    int *address_of_x = &x; # ポインタ変数
    int value_stored = *address_of_x; #「*」演算子でポインタを参照解決する
    printf("value_storedの値は%p\n", value_stored);
    *address_of_x = 99; # アドレスの指す内容を変更する
    printf("xの値は%p\n", x);
}

ポインタ変数の使い方

1. 変数のアドレスを取得

ポインタ変数:

int x = 4; int *address_of_x = &x

2. アドレスの内容を読み取る

int value_stored = *address_of_x;

3. アドレスの内容を変更する

配列変数

  • 配列変数はポインタとして使える
  • 配列変数は配列の最初の要素を指す
  • 関数に配列引数を宣言すると、ポインタとして扱われる
  • ポインタのサイズは、32ビットOSでは4バイト、64ビットOSでは8バイト

function runc {
  gcc $1 -o ./out && ./out
}
使い方:
$ runc hoge.c
→hoge.cが、outというファイル名でカレントディレクトリにコンパイルされ、それを実行。
→コンパイルエラーがある場合はエラーを吐いて終了。

動作環境:Mac OS X 10.9 / bash 3.2.51

Head First C ―頭とからだで覚えるCの基本
David Griffiths
オライリージャパン
2013-04-03

Cの基本

  • 通常、Cプログラムはコメントで始まる
  • 次に来るのはインクルード部(Cは小さな言語であるため、外部ライブラリがほぼ必須)
  • ソースファイルの最後には関数がある
  • すべてのCコードは関数内で動作する
  • main()関数が最初に実行される
  • main()の戻り値の型はintにすべき
  • main()が0を返せば正常終了、0以外の値を返した場合は異常が発生を意味する
  • プログラムの終了状態を調べるには、echo $?

コンパイル

文字列

  • Cはライブラリの無い状態では文字列をサポートしていない
  • Cの文字列は、文字の配列である
  • Cに文字の終端を認識させるためには、文字列の末尾にヌル文字(\0)を付ける
  • 文字列の末尾にはヌル文字を含む必要があるため、文字列の長さは、最低限必要な文字数よりも1文字分余計に確保する必要がある。
  • 個々の文字には単一引用符「'」を用いる。
  • 文字列の定義には、通常、文字列リテラル(二重引用符「"」で文字列を囲む)を用いる。
  • 文字列リテラルは定数であるため、一度定義した後は、変更できない。

論理演算

  • ANSI Cには、Boolean型は無い。0か、それ以外かで真偽判定を行う(C99でtrue/falseが使えるようになったが、内部的には1/0)。
  • 「&&」がAND条件、「||」がOR条件を示す。
  • 「&」「|」はビット演算を実行する。 1 & 0は0、1 | 0は1。
  • 「&&」「||」はビット演算を実行して評価値を返すために使うので、「&」「|」でも代用できる。違いは、「&」「|」が必ず両辺の条件を評価するのに対し、「&&」「||」は右辺の評価をしないことがある(短絡)。

関数

  • 戻り値がない関数を作成する場合、戻り値の型をvoidにする
/**
* ブラックジャックのカードの値を評価するプログラム
*/
#include <stdio>
#include <stdlib>

int main()
{
    char card_name[3];
    int count = 0;
    do {
        puts("カード名を入力してください");
        scanf("%2s", card_name);
        int val = 0;

        switch (card_name[0]) {
        case 'K':
        case 'Q':
        case 'J':
            val = 10;
            break;
        case 'A':
            val = 11;
            break;
        case 'X':
            continue;
        default:
            val = atoi(card_name);
        }

        if ((val < 1) || (val > 10)) {
            puts("その値はわかりません!");
            continue;
        }

        if ((val > 2) && (val < 7))
            count++;
        else if (val == 10)
            count--;

        printf("現在のカウント:%i\n", count);
        
    } while(card_name[0] != 'X');

    return 0;
}

このページのトップヘ