文 (Statements)

複合文

[複合文] (Compound Statement) とは [ブロック] {} のことである.

compound.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <stdio.h>

int main(void){
  int i, sum = 0;
  
  for(i = 0; i <= 10; i++){
    printf("i = %d\n", i);
    sum += i;
  }

  printf("sum = %d\n", sum);

  return 0;
}

compound.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./compound
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
sum = 55

式文

[式文] (Expression Statement) とは:

式;

のことである. 式がない式文を [空文] (ナル文, NULL 文, Null Statement) という. [空文] は何も実行しない:

void f(int x); // 宣言
int x = 2; // 宣言
; // 空文
f(x); // 式文
x = 3; 式文

if 文

if.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>

int main(void){
  int x = 0;
  printf("Input an integer: ");
  scanf("%d", &x);
  if(x)
    printf("OK, x = %d\n", x);
  else{
    printf("Input a nonzero integer: ");
    scanf("%d", &x);
    printf("Well, x = %d\n", x);
  }

  return 0;
}

if.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./if
Input an integer: 0
Input a nonzero integer: 10
Well, x = 10

switch 文

switch 文 (switch Statement):

switch(式){
case 整数定数式 1: 文
case 整数定数式 2: 文
/* ... */
default: 文
}

switch.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

int main(void){
  int x = 0;
  
  printf("Input an integer: ");
  scanf("%d", &x);
  
  switch(x){
  case 0:
    printf("Input a nonzero integer: ");
    scanf("%d", &x);
    printf("Well, x = %d\n", x);
    break;
  default:
    printf("OK, x = %d\n", x);
  }

  return 0;
}

switch.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./switch
Input an integer: 0
Input a nonzero integer: 20
Well, x = 20
[cactus:~/code_c/c_tuts]% ./switch
Input an integer: 19
OK, x = 19

getopt.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
/*
  int
  getopt(int argc, char * const argv[], const char *optstring);
*/


int main(int argc, char *argv[]){
  int c;
  char *s;
  int lflag = 0;
  int rflag = 0;

  while( (c = getopt(argc, argv, "lr")) != -1){
    switch( (char)c ){
    case 'l':
      lflag = 1;
      break;
    case 'r':
      rflag = 1;
      break;
    default:
      fprintf(stderr, "usage: command [-lr] [keyword]\n");
      exit(1);
    }
  }
  
  argv += optind; // argv の値を換える
  /*
    extern int optind; (man 3 getopt に参照すること)
    
  */

  if(!argv[0])
    exit(1);

  s = argv[0];

  if(lflag){
    printf("- l mode -\n");;
    for(; *s; s++) // パラメータ文字列を出力する
      printf("%c (%d)\n", *s, *s);
  }

  if(rflag){
    printf("- r mode -\n");
    for(; *s; s++); // ポインタをパラメータ文字列の語尾に移動する
    --s;
    for(; *s; s--) // 文字列を後ろから出力する
      printf("%c (%d)\n", *s, *s);
  }
  
  return 0;
}

getopt.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./getopt -z
./getopt: illegal option -- z
usage: command [-lr] [keyword]
[cactus:~/code_c/c_tuts]% ./getopt -r abc
- r mode -
c (99)
b (98)
a (97)
[cactus:~/code_c/c_tuts]% ./getopt -l abc
- l mode -
a (97)
b (98)
c (99)
[cactus:~/code_c/c_tuts]% ./getopt -rl abc
- l mode -
a (97)
b (98)
c (99)
- r mode -
c (99)
b (98)
a (97)
[cactus:~/code_c/c_tuts]% ./getopt -lr abc
- l mode -
a (97)
b (98)
c (99)
- r mode -
c (99)
b (98)
a (97)
[cactus:~/code_c/c_tuts]% ./getopt -l -r abc
- l mode -
a (97)
b (98)
c (99)
- r mode -
c (99)
b (98)
a (97)

while 文

while.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <stdio.h>

int main(void){
  int sum = 0, x[6] = {0}, *p = x;
  printf("Input integers: ");
  scanf("%d%d%d%d%d", x, x+1, x+2, x+3, x+4);
  while(*p)
    /*
      x[0] が 0 になると加算しなくなる, sum = 0 が出力される
      x[0] が 0 以外の場合は x[0] ~ x[4] までの五つの値を加算して, sum として出力される
    */
    sum += *(p++); // ++ は * より優先になる
  printf("sum = %d\n", sum);

  return 0;
}

while.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./while
Input integers: 0 1 2 3 4 5 6 7
sum = 0
[cactus:~/code_c/c_tuts]% ./while
Input integers: 1 2 3 4 5 6 7 8
sum = 15
[cactus:~/code_c/c_tuts]% ./while
Input integers: 1 2 3 4 5 6 7 8 9 10
sum = 15

do 文

[cactus:~/code_c/c_tuts]% ./do Input integers: 1 2 3 4 5 6 7 sum = 15 [cactus:~/code_c/c_tuts]% ./do Input integers: 0 1 2 3 4 5 sum = 10 [cactus:~/code_c/c_tuts]% ./do Input integers: 1 2 0 0 2 3 sum = 3 [cactus:~/code_c/c_tuts]% gcc -Wall -o do do.c [cactus:~/code_c/c_tuts]% ./do Input integers: 1 2 0 0 2 3 sum = 3

for 文

for 文 (for Statement):

for(式1; 式2; 式3) 文

for 文は, 式 1 を最初に評価し, 式 2 が真であれば 文 を実行後 式 3 を評価する. 式 1 が返しの初期条件, 式 2 が繰り返す条件, そして 式 3 が条件変更と解釈できる.

while 文で書き直すと:

式 1;
while(式 2){
  文
  式 3
}

となる.

for.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <stdio.h>

int main(void){
  int sum = 0, x[6] = {0}, *p = NULL;
  printf("Input integers: ");
  scanf("%d%d%d%d%d", x, x+1, x+2, x+3, x+4);
  for(p = x; *p; p++)
    sum += *p;
  printf("sum = %d\n", sum);

  return 0;
}

for.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./for
Input integers: 0 1 2 3 4 5
sum = 0
[cactus:~/code_c/c_tuts]% ./for
Input integers: 1 2 3 4 5 6 7 8
sum = 15

for2.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <string.h>
/*
  char *
  strtok(char *restrict str, const char *restrict sep);
*/

int main(void){
  char str[] = "ABCD\tabc\t123\t<=>\t";
  char key[] = "\t";
  char *s[10];
  char **z;

  z = s;
  *z = strtok(str, key);
  ++z;
  for(; (*z = strtok(NULL, key)); z++){}

  for(z = s; *z; z++)
    printf("%s\n", *z);

  return 0;
}

for2.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./for2
ABCD
abc
123
<=>

isPrime.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main(void){
  int n;
  int p[50] = {2};
  int *v;

  for(n = 3; n <= 100; n++){
    for(v = p; *v && (n % *v); v++){}
    if(!*v)
      *v = n;
  }

  for(v = p; *v; v++)
    printf("%d ", *v);

  putchar('\n');
  printf("number of prime numbers = %td\n", v - p);

  return 0;
}

isPrime.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./isPrime
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
number of prime numbers = 25

goto 文

goto.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <stdio.h>

int main(void){
  unsigned char x = 0;
 call:
  printf("OK, input a character: ");
  scanf("%c", &x);

  if(x < 65 || x > 90) // 大文字 (A~Z) 以外の場合は call: にジャンプする
    goto call;
  printf("x = %c (%d)\n", x, x);

  return 0;
}

goto.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./goto
OK, input a character: A
x = A (65)
[cactus:~/code_c/c_tuts]% ./goto
OK, input a character: a
OK, input a character: OK, input a character: Z
x = Z (90)

continue 文 と break 文

continue 文は, while 文, do 文, for 文の [繰り返し] において, 繰り返し対象の文の末尾にジャンプさせる. goto 文を使った右側と同じである.

すなわち, 繰り返し処理において, continue 以下を飛ばすこととなる.

break 文は, while 文, do 文, for 文の [繰り返し文] と switch 文において, 処理を止める. すなわち, 繰り返し処理から抜ける.

continue_break.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>

int main(void){
  int x[10] = {8, 5, 14, 10, 9, 12, 16, 7, 2, 22};
  int flag2 = 0, flag3 = 0;

  int *p = NULL;

  for(p = x; *p; p++){
    flag2 = *p % 2;
    if(flag2)
      continue; // 以下の処理を飛ばすことができる!!
    printf("x[%td] = %d\n", p-x, *p);

    flag3 = *p % 3;
    if(!flag3)
      break;

    /*
      2 と 3 の倍数であったときに, 繰り返し処理から抜ける
    */
  }

  ++p; // インデックスは 0 からなので, 1 を足さなくてはいけない
  printf("Process terminates at the %tdth element.\n", p-x);

  return 0;
}

continue_break.c の実行結果は:

[cactus:~/code_c/c_tuts]% ./continue_break
x[0] = 8
x[2] = 14
x[3] = 10
x[5] = 12
Process terminates at the 6th element.