[C言語]雑多な学習メモ

Objective-Cの前にC言語をすこしやっときたいなと思って軽く勉強した。

参考にしたモノ

猫でもわかるC言語プログラミング でObjective-Cの前にC言語をすこしやっときたいなと思って軽く勉強した。 苦しんで覚えるC言語も参考にした(こちらのサイトに書いてある学習用開発環境を使用)

プログラムについて

ソースファイル(ソース)をコンパイラで機械語にコンパイルするとオブジェクトファイルができ、 これをリンカでライブラリと結合させると実行可能なプログラムができる。 コンパイラによってコンパイル結果が違うことがあるので注意。

メモ:リトルエンディアン、ビッグエンディアン、イクセス表現、バイアス、正規化normalization

HelloWorld

#include <stdio.h>

int main(void)
{
  printf("Hello" "World!\n");
  return 0;
}

結果

Hello World

とりあえず走らせた。#include で stdio.h を読み込んでいる(参考:http://9cguide.appspot.com/03-01.html#S2)。 printfはstdout(標準出力)に文字を入力する関数らしいけれどこの引数の書き方はphpやJavaなどでは無理な書き方。main関数 は処理の起点、 なんで int 0 を返してるのか分かんないけど、まぁいいや…

エスケープシーケンス

エスケープシーケンスは拡張表記とも言う

#include <stdio.h>

int main(void)
{
  printf("\x61\x62\a\n");
  printf("\x61\b\x62\n");
  printf("\x61\x62\b\n");
  printf("あ\b\n");
  return 0;
}

結果

ab (ベル音が鳴る)
b
ab
あ

データ型

  • short 16ビット整数型
  • int 32ビット整数型
  • long 32ビット整数型
  • float 32ビット浮動小数点型
  • double 64ビット浮動小数点型
  • long double 64ビット浮動小数点型
  • char 8ビット文字型

コンパイラによってbit数が違うらしい。

型変換とか型キャストとか

#include <stdio.h>

int main(void)
{
  float f1, f2, f3;
  f1 = 1.5f;
  f2 = (int) f1;
  f3 = 1;
  printf("%f | %f | %f\n", f1, f2, f3);

  int n = 0x10;
  printf("%d | %d", n, n / 3);

  return 0;
}

結果

1.500000 | 1.000000 | 1.000000
16 | 5

古いコンパイラだと変数の宣言を最初に行わないとコンパイルエラーになるそうな。。

sizeof 演算子

バイト数を調べられる。返り値の型は size_t型

#include <stdio.h>

int main(void)
{
  size_t x[8];
  x[0] = sizeof "TEST";
  x[1] = sizeof "";
  x[2] = sizeof 'a';
  x[3] = sizeof 1234567890;
  x[4] = sizeof 12345678901234567890;
  // x[4] = sizeof 12345678901345678901234567890; オーバーフロー
  x[5] = sizeof 'a';
  x[6] = sizeof 0.0;
  x[7] = sizeof x;
  int i;
  for(i = 0; i < 9; i++){
    printf("[%d] %d\n", i, x[i]);
  }

  return 0;
}

結果

[0] 5
[1] 1
[2] 4
[3] 4
[4] 8
[5] 4
[6] 8
[7] 32
[8] 1638280

関係演算子

!= とか == とかはあるけど === とか !== は存在しない。

またboolean型は無く 0 or 1 に評価される。

#include <stdio.h>

int main(void)
{
  printf("%d\n", 0 == 0 );
  printf("%d\n", 0 != 1 );
  printf("%d\n", 0 <= 0 );
  printf("%d\n", 0 > 1 );

  return 0;
}

結果

1
1
1
0

制御文

このあたりはどのプログラムでもほとんど同じ。

制御式(controlling expression)では 0 以外は true とみなされ真文(true statement)を実行する

#include <stdio.h>

int main(void)
{
  int i;

  for (
    i = 0;  /* 初期設定式:ここで変数の宣言はできない。省略可能 */
    i < 10; /* 継続条件式:省略可能 */
    i++     /* 再設定式:省略可能 */
  ) {
    printf("%d", i);
  }

  return 0;
}

結果

0123456789
#include <stdio.h>

int main(void)
{
  while (1) {
    while (1) {
      printf("TEST");
      goto LABEL;
    }
  }
  LABEL :

  return 0;
}

結果

TEST

C言語で多重ループを一気に抜けるためには goto ラベル名; を使う

関数

返り値の型 変数名(仮引数){中身} という書き方で定義する

#include <stdio.h>

int main(void)
{
  static int n;
  n++;
  printf("%d", n);
  n < 9 ? main() : 0 ;
  return 0;
}

結果

123456789

main も関数の一つなので再帰的に呼び出しできる。 static変数は明示的に初期化しない場合は 0 に初期化される。 初期化は1度しか行われないため、2回目以降は無視される。

#include <stdio.h>

int n = 12345679; /* グローバル変数 */

foobar(int, int); /* 関数のプロトタイプ宣言 */

int main(void)
{
  foobar(n, 81);
  return 0;
}

int foobar(int int1, int int2)
{
  printf("%d", int1 * int2);
}

結果

999999999

コンパイラが関数を最初に読み込んでくれない場合は、関数のプロトタイプ宣言を行わないとエラーになる。 関数外で宣言した変数はグローバルスコープで、これも下のほうに書いたりするとコンパイルエラーになったりする。 グローバル変数は初期値を代入しない場合は 0 に初期化される。

用語のメモ

  • assignment(代入)
  • 書式指定フィールド
  • 浮動小数点接尾語(floating suffix)
  • 整数接尾語(integer suffix)
  • 式(expression)
  • 演算項目(operand)
  • 一次式(primary exprssion)
  • 式文(expression statement)
  • 評価(evaluation)
  • 演算子の優先順位(precedence)
  • 格上げ(promote)
  • 結合規則(associativity)
  • 仮引数(parameter)
  • 実引数(argument)
Share
関連記事