Download : sample-001.c
/* * 2020/11/20 sample-001.c */ #include <stdio.h> #include "s_memory.h" /* memory モデルを理解するための関数定義 */ /* * */ int main ( void ) { /* * メモリの操作 ( 情報の記録 : set_memory_value_at ) */ set_memory_value_at ( 100, 1 ); /* 100 番地のセルに 1 を記録する */ set_memory_value_at ( 101, 10 ); /* 101 番地のセルに 10 を記録する */ /* * メモリの操作 ( 情報の参照 : get_memory_value_at ) */ printf ( "100 番地のセルに記録されている数値は %d です。\n", get_memory_value_at ( 100 ) ); printf ( "101 番地のセルに記録されている数値は %d です。\n", get_memory_value_at ( 101 ) ); /* * */ return 0; } /* * */
$ ./sample-001.exe 100 番地のセルに記録されている数値は 1 です。 101 番地のセルに記録されている数値は 10 です。 $
Download : sample-002.c
/* * 2020/11/20 sample-002.c */ #include <stdio.h> #include "s_memory.h" /* memory モデルを理解するための関数定義 */ /* * print_memory_value * 指定された address の記憶セルの内容を画面に出力する */ void print_memory_value ( int address ) { printf ( "%d 番地のセルに記録されている数値は %d です。\n", address, get_memory_value_at ( address ) /* 値の取出し */ ); } /* * print_memory_set * メモリへの記憶操作を行い、それを報告する */ void print_memory_set ( int address, int value ) { /* 動作の表示 */ printf ( "%d 番地のセルに %d を記録。\n", address, value ); /* address 番地に value を記録する */ set_memory_value_at ( address, value ); /* 値の設定 */ } /* * print_line * 横棒を表示 */ void print_line ( void ) { printf ( "--------------------------------------\n" ); } /* * */ int main ( void ) { /* * メモリの参照 : 一度記録した情報は何度でも参照できる */ print_memory_set ( 100, 1 ); /* 100 番地のセルに 1 を記録する */ printf ( "一度目 : " ); print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 (一度目) */ printf ( "二度目 : " ); print_memory_value ( 100 ); /* 二度目 */ printf ( "三度目 : " ); print_memory_value ( 100 ); /* 三度目 */ /* * 参照は何度行っても、同じ情報が得られる */ print_line(); /* * 記憶の破壊 : 新しい情報を記録すると以前の記録は失われる */ print_memory_set ( 100, 99 ); /* 100 番地のセルに 99 を記録する */ printf ( "変更後 : " ); print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ /* * 新しい情報を記憶すると以前の記録された情報は失われる */ /* * 記録は最後のものだけ ( 参照の有無と無関係に最後のものだけを記録 ) */ print_memory_set ( 100, 21 ); /* 100 番地のセルに 21 を記録する */ print_memory_set ( 100, 22 ); /* 100 番地のセルに 22 を記録する */ print_memory_set ( 100, 23 ); /* 100 番地のセルに 23 を記録する */ printf ( "現在値 : " ); print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ /* * 記録されている情報は最後に記録された物だけ */ /* * */ return 0; } /* * */
$ ./sample-002.exe 100 番地のセルに 1 を記録。 一度目 : 100 番地のセルに記録されている数値は 1 です。 二度目 : 100 番地のセルに記録されている数値は 1 です。 三度目 : 100 番地のセルに記録されている数値は 1 です。 -------------------------------------- 100 番地のセルに 99 を記録。 変更後 : 100 番地のセルに記録されている数値は 99 です。 100 番地のセルに 21 を記録。 100 番地のセルに 22 を記録。 100 番地のセルに 23 を記録。 現在値 : 100 番地のセルに記録されている数値は 23 です。 $
Download : sample-003.c
/* * 2020/11/20 sample-003.c */ #include <stdio.h> #include "s_memory.h" /* memory モデルを理解するための関数定義 */ /* * print_memory_value * 指定された address の記憶セルの内容を画面に出力する */ void print_memory_value ( int address ) { printf ( "%d 番地のセルに記録されている数値は %d です。\n", address, get_memory_value_at ( address ) /* 値の取出し */ ); } /* * print_memory_set * メモリへの記憶操作を行い、それを報告する */ void print_memory_set ( int address, int value ) { /* 動作の表示 */ printf ( "%d 番地のセルに %d を記録。\n", address, value ); /* address 番地に value を記録する */ set_memory_value_at ( address, value ); /* 値の設定 */ } /* * print_line * 横棒を表示 */ void print_line ( void ) { printf ( "--------------------------------------\n" ); } /* * */ int main ( void ) { /* * メモリセルの独立性 : 番地の異るセルは独立に振る舞う */ print_memory_set ( 100, 1 ); /* 100 番地のセルに 1 を記録する */ print_memory_set ( 101, 2 ); /* 101 番地のセルに 2 を記録する */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ print_memory_value ( 101 ); /* 101 番地のセルの内容を出力 */ /* * 番地が異れば、記録されている情報も異る */ /* * 記憶の独立性 */ print_memory_set ( 100, 99 ); /* 100 番地のセルに 99 を記録する */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ print_memory_value ( 101 ); /* 101 番地のセルの内容を出力 */ print_line(); /* * 100 番地の情報を書き換えても、101 番地の情報は影響しない */ print_memory_set ( 101, 88 ); /* 101 番地のセルに 88 を記録する */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ print_memory_value ( 101 ); /* 101 番地のセルの内容を出力 */ /* * 逆も真なり */ /* * */ return 0; } /* * */
$ ./sample-003.exe 100 番地のセルに 1 を記録。 101 番地のセルに 2 を記録。 100 番地のセルに記録されている数値は 1 です。 101 番地のセルに記録されている数値は 2 です。 100 番地のセルに 99 を記録。 100 番地のセルに記録されている数値は 99 です。 101 番地のセルに記録されている数値は 2 です。 -------------------------------------- 101 番地のセルに 88 を記録。 100 番地のセルに記録されている数値は 99 です。 101 番地のセルに記録されている数値は 88 です。 $
Download : sample-004.c
/* * 2020/11/20 sample-004.c */ #include <stdio.h> #include "s_memory.h" /* memory モデルを理解するための関数定義 */ /* * print_memory_value * 指定された address の記憶セルの内容を画面に出力する */ void print_memory_value ( int address ) { printf ( "%d 番地のセルに記録されている数値は %d です。\n", address, get_memory_value_at ( address ) /* 値の取出し */ ); } /* * print_memory_set * メモリへの記憶操作を行い、それを報告する */ void print_memory_set ( int address, int value ) { /* 動作の表示 */ printf ( "%d 番地のセルに %d を記録。\n", address, value ); /* address 番地に value を記録する */ set_memory_value_at ( address, value ); /* 値の設定 */ } /* * print_line * 横棒を表示 */ void print_line ( void ) { printf ( "--------------------------------------\n" ); } /* * */ int main ( void ) { /* * メモリセルの容量 */ print_memory_set ( 100, 0 ); /* 100 番地のセルに 0 を記録する */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ print_memory_set ( 100, 100 ); /* 100 番地のセルに 100 を記録する */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ print_memory_set ( 100, 255 ); /* 100 番地のセルに 255 を記録する */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ /* * 0 〜 255 ならば、記録できる */ print_line(); /* * メモリセルの容量オーバー */ print_memory_set ( 100, 300 ); /* 100 番地のセルに 300 を記録しようとした */ print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */ /* * 300 は記憶されていない !! * 実は 300 を 256 で割った余り ( 44 ) が記録されている * 256 を越える(オーバーする)情報は捨てられる !! */ /* * */ return 0; } /* * */
$ ./sample-004.exe 100 番地のセルに 0 を記録。 100 番地のセルに記録されている数値は 0 です。 100 番地のセルに 100 を記録。 100 番地のセルに記録されている数値は 100 です。 100 番地のセルに 255 を記録。 100 番地のセルに記録されている数値は 255 です。 -------------------------------------- 100 番地のセルに 300 を記録。 100 番地のセルに記録されている数値は 44 です。 $
Download : sample-005.c
/* * 2020/11/20 sample-005.c */ #include <stdio.h> #include "s_variable.h" /* memory モデルを理解するための関数定義 */ /* * */ int main ( void ) { /* * C 言語の変数のメモリモデルによる理解 */ char cvar; /* char 型の変数 cvar の宣言 */ char dvar; /* char 型の変数 dvar の宣言 */ /* * 変数はアドレスをもっている */ printf ( "変数 cvar のアドレスは 16 進数表現で %x です。\n", get_variable_address( cvar ) ); printf ( "変数 dvar のアドレスは 16 進数表現で %x です。\n", get_variable_address( dvar ) ); /* * 変数名が異れば、番地も異っている */ /* * 変数をアドレスを利用して参照 */ cvar = 'c'; /* 変数 cvar に、値 'c' を代入 */ dvar = 'D'; /* 変数 Dvar に、値 'D' を代入 */ printf ( "変数 cvar に記録されている文字は %c です。\n", get_variable_value_at ( get_variable_address( cvar ) ) ); printf ( "変数 dvar に記録されている文字は %c です。\n", get_variable_value_at ( get_variable_address( dvar ) ) ); /* * 変数の値をアドレスを利用して変更 */ set_variable_value_at ( get_variable_address( cvar ), 'X' ); /* 変数 cvar の所に 'X' を記録 */ printf ( "cvar は %c です。\n", cvar ); set_variable_value_at ( get_variable_address( dvar ), 'y' ); /* 変数 dvar の所に 'y' を記録 */ printf ( "dvar は %c です。\n", dvar ); /* * */ return 0; } /* * */
10
$ ./sample-005.exe < sample-005.in 変数 cvar のアドレスは 16 進数表現で 74ddfabe です。 変数 dvar のアドレスは 16 進数表現で 74ddfabf です。 変数 cvar に記録されている文字は c です。 変数 dvar に記録されている文字は D です。 cvar は X です。 dvar は y です。 $
Download : sample-006.c
/* * 2020/11/20 sample-006.c */ #include <stdio.h> #include "s_variable.h" /* memory モデルを理解するための関数定義 */ /* * */ int main ( void ) { /* * C 言語の文字列のメモリモデルによる理解 */ /* * 文字列はアドレスをもっている */ printf ( "文字列 \"abc\" のアドレスは 16 進数表現で %x です。\n", get_string_address( "abc" ) ); /* * 文字列の要素をアドレスを利用して参照 */ printf ( "文字列 \"abc\" の先頭の文字は %c です。\n", get_variable_value_at ( get_string_address( "abc" ) ) ); /* * 文字列の要素の二つ目以後を取り出す */ printf ( "文字列 \"abc\" の先頭の次の文字は %c です。\n", get_variable_value_at ( get_string_address( "abc" ) + 1 ) ); printf ( "文字列 \"abc\" の先頭の次の次の文字は %c です。\n", get_variable_value_at ( get_string_address( "abc" ) + 2 ) ); /* * */ return 0; } /* * */
$ ./sample-006.exe 文字列 "abc" のアドレスは 16 進数表現で 401470 です。 文字列 "abc" の先頭の文字は a です。 文字列 "abc" の先頭の次の文字は b です。 文字列 "abc" の先頭の次の次の文字は c です。 $
Download : sample-007.c
/* * 2020/11/20 sample-007.c */ #include <stdio.h> #include "s_variable.h" /* memory モデルを理解するための関数定義 */ /* * */ int main ( void ) { /* * C 言語の変数のメモリモデルによる理解 */ char cvar; /* char 型の変数 cvar の宣言 */ char dvar; /* char 型の変数 dvar の宣言 */ char evar; /* char 型の変数 evar の宣言 */ /* * 変数を並べてて宣言すると (偶然..) アドレスが連続していた.. */ printf ( "変数 cvar のアドレスは 16 進数表現で %x です。\n", get_variable_address( cvar ) ); printf ( "変数 dvar のアドレスは 16 進数表現で %x です。\n", get_variable_address( dvar ) ); printf ( "変数 evar のアドレスは 16 進数表現で %x です。\n", get_variable_address( evar ) ); /* * 変数をアドレスを利用して参照 */ cvar = 'c'; /* 変数 cvar に、値 'c' を代入 */ dvar = 'D'; /* 変数 dvar に、値 'D' を代入 */ evar = '\0'; /* 変数 evar に、値 '\0' を代入 */ printf ( "cvar の所から記録されている文字列は (%s) です。\n", get_variable_address( cvar ) ); /* * アドレス経由で、変数の内容を変更 */ set_variable_value_at ( get_variable_address( cvar ) + 1, 'x' ); /* 変数 cvar のアドレスの次のアドレスは dvar のアドレスなので.. */ printf ( "cvar に記録されている文字は %c です。\n", cvar ); /* 結果的に、dvar の内容が書き変わる */ printf ( "dvar に記録されている文字は %c です。\n", dvar ); /* * */ return 0; } /* * */
$ ./sample-007.exe 変数 cvar のアドレスは 16 進数表現で fba3427d です。 変数 dvar のアドレスは 16 進数表現で fba3427e です。 変数 evar のアドレスは 16 進数表現で fba3427f です。 cvar の所から記録されている文字列は (cD) です。 cvar に記録されている文字は c です。 dvar に記録されている文字は x です。 $
Download : sample-008.c
/* * 2020/11/20 sample-008.c */ #include <stdio.h> #include "s_variable.h" /* memory モデルを理解するための関数定義 */ /* * */ int main ( void ) { /* * C 言語の変数のメモリモデルによる理解 */ char carray[3]; /* char 型の一次元配列 carray の宣言 (サイズは 3) */ /* 意味的には char carry[0]; -- cvar char carry[1]; -- dvar char carry[2]; -- evar のように考えて良い (cf. sample-007.c) */ /* * 配列の要素のアドレスは連続している事が保証される */ printf ( "変数 carray[0] のアドレスは 16 進数表現で %x です。\n", get_variable_address( carray[0] ) ); printf ( "変数 carray[1] のアドレスは 16 進数表現で %x です。\n", get_variable_address( carray[1] ) ); printf ( "変数 carray[2] のアドレスは 16 進数表現で %x です。\n", get_variable_address( carray[2] ) ); /* * 変数をアドレスを利用して参照 */ carray[0] = 'c'; /* 変数 carray[0] に、値 'c' を代入 */ carray[1] = 'D'; /* 変数 carray[1] に、値 'D' を代入 */ carray[2] = '\0'; /* 変数 carray[2] に、値 '\0' を代入 */ printf ( "carray[0] の所から記録されている文字列は (%s) です。\n", get_variable_address( carray[0] ) ); /* * アドレス経由で、変数の内容を変更 */ set_variable_value_at ( get_variable_address( carray[0] ) + 1, 'x' ); /* 変数 carray[0] のアドレスの次のアドレスは carray[1] のアドレスなので.. */ printf ( "carray[0] に記録されている文字は %c です。\n", carray[0] ); /* 結果的に、carray[1] の内容が書き変わる */ printf ( "carray[1] に記録されている文字は %c です。\n", carray[1] ); /* * */ return 0; } /* * */
$ ./sample-008.exe 変数 carray[0] のアドレスは 16 進数表現で 4410b3c0 です。 変数 carray[1] のアドレスは 16 進数表現で 4410b3c1 です。 変数 carray[2] のアドレスは 16 進数表現で 4410b3c2 です。 carray[0] の所から記録されている文字列は (cD) です。 carray[0] に記録されている文字は c です。 carray[1] に記録されている文字は x です。 $
Download : sample-009.c
/* * 2020/11/20 sample-009.c */ #include <stdio.h> #include "s_variable.h" /* memory モデルを理解するための関数定義 */ /* * */ int main ( void ) { /* * */ char carray[3]; /* char 型の一次元配列 carray の宣言 (サイズは 3) */ /* * 配列の要素のアドレスは連続している事が保証される */ carray[0] = 'c'; /* 変数 carray[0] に、値 'c' を代入 */ carray[1] = 'D'; /* 変数 carray[1] に、値 'D' を代入 */ carray[2] = '\0'; /* 変数 carray[2] に、値 '\0' を代入 */ printf ( "carray[0] の所から記録されている文字列は (%s) です。\n", get_variable_address( carray[0] ) ); /* * 配列名は、文字列と同じように扱える */ printf ( "carray が表現している文字列は (%s) です。\n", carray ); /* * 文字列の一部を変更する事ができる */ carray[1] = 'U'; /* ニ文字目を 'U' に変更 */ printf ( "carray が表現している文字列は (%s) です。\n", carray ); carray[0] = 'p'; /* 一字目を 'p' に変更 */ printf ( "carray が表現している文字列は (%s) です。\n", carray ); /* * */ return 0; } /* * */
$ ./sample-009.exe carray[0] の所から記録されている文字列は (cD) です。 carray が表現している文字列は (cD) です。 carray が表現している文字列は (cU) です。 carray が表現している文字列は (pU) です。 $
Download : sample-010.c
/* * 2020/11/20 sample-010.c */ #include <stdio.h> /* * */ int main ( void ) { /* * 文字配列の初期化 */ char carray[3] = "AB"; /* carray[0] = 'A'; carray[1] = 'B'; carray[2] = '\0'; */ printf ( "carray[0] は %c です。\n", carray[0] ); printf ( "carray[1] は %c です。\n", carray[1] ); /* * */ return 0; } /* * */
$ ./sample-010.exe carray[0] は A です。 carray[1] は B です。 $
Download : sample-011.c
/* * 2020/11/20 sample-011.c */ #include <stdio.h> /* * */ int main ( void ) { /* * アドレス演算子「&」と間接演算子「*」 */ char carray[3] = "AB"; /* * 添字による参照 */ printf ( "carry[0] = %c\n", carry[0] ); printf ( "carry[1] = %c\n", carry[1] ); /* * 間接演算子による参照 */ printf ( "*carry = %c\n", *carry ); printf ( "*(carry+1) = %c\n", *(carry+1) ); /* * address の比較 */ s_print_string ( "&carry[0] = %x\n", &carry[0] ); s_print_string ( "carry = %x\n", carry ); /* * 「&」と「*」は逆演算子 */ s_print_string ( "carry = %x\n", carry ); s_print_string ( "&*carry = %x\n", &*carry ); s_print_string ( "carry[0] = %c\n", carry[0] ); s_print_string ( "*&carry[0] = %c\n", *&carry[0] ); /* * */ return 0; } /* * */
$ ./sample-011.exe carray[0] は A です。 carray[1] は B です。 $
Download : sample-012.c
/* * 2020/11/20 sample-012.c */ #include <stdio.h> #include "s_memory.h" /* memory モデルを理解するための関数定義 */ /* * ◯×ゲームのボード (一次元版) * * y * 0 1 2 (y,t) * +-----+-----+-----+ +-----+ * 0 |(0,0)|(0,1)|(0,2)| |(0,0)| 0 = 0*3+0 = t*3+y * +-----+-----+-----+ +-----+ * t 1 |(1,0)|(1,1)|(1,2)| |(0,1)| 1 = 0*3+1 = t*3+y * +-----+-----+-----+ +-----+ * 2 |(2,0)|(2,1)|(2,2)| |(0,2)| 2 = 0*3+2 = t*3+y * +-----+-----+-----+ +-----+ * |(1,0)| 3 = 1*3+0 = t*3+y * +-----+ * |(1,1)| 4 = 1*3+1 = t*3+y * +-----+ * |(1,2)| 5 = 1*3+2 = t*3+y * +-----+ * |(2,0)| 6 = 2*3+0 = t*3+y * +-----+ * |(2,1)| 7 = 2*3+1 = t*3+y * +-----+ * |(2,2)| 8 = 2*3+2 = x*3+y * +-----+ * */ #define BOARD_SIZE 3 /* ボードのサイズ */ #define SENTE_MARK 'o' /* 先手は 'o' (マル) */ #define GOTE_MARK 'x' /* 後手は 'x' (バツ) */ int main ( void ) { /* * */ char board[BOARD_SIZE*BOARD_SIZE]; /* サイズは 3 × 3 */ int t; /* 縱 */ int y; /* 横 */ /* * ある局面 * * oxx * xoo * oox */ board[0*BOARD_SIZE+0] = 'o'; /* (0,0) */ board[0*BOARD_SIZE+1] = 'x'; /* (0,1) */ board[0*BOARD_SIZE+2] = 'x'; /* (0,2) */ board[1*BOARD_SIZE+0] = 'x'; /* (1,0) */ board[1*BOARD_SIZE+1] = 'o'; /* (1,1) */ board[1*BOARD_SIZE+2] = 'o'; /* (1,2) */ board[2*BOARD_SIZE+0] = 'o'; /* (2,0) */ board[2*BOARD_SIZE+1] = 'x'; /* (2,1) */ board[2*BOARD_SIZE+2] = 'x'; /* (2,2) */ /* * */ t = 0; while ( t < BOARD_SIZE ) { y = 0; while ( y < BOARD_SIZE ) { printf ( "%c", board[t*BOARD_SIZE+y] ); y = y + 1; } printf ( "\n" ); t = t + 1; } /* * */ return 0; } /* * */
$ ./sample-012.exe oxx xoo oxx $
Download : sample-013.c
/* * 2020/11/20 sample-013.c */ #include <stdio.h> /* * ◯×ゲームのボード (一次元版) * * y * 0 1 2 (y,t) * +-----+-----+-----+ +-----+ * 0 |(0,0)|(0,1)|(0,2)| |(0,0)| 0 = 0*3+0 = t*3+y * +-----+-----+-----+ +-----+ * t 1 |(1,0)|(1,1)|(1,2)| |(0,1)| 1 = 0*3+1 = t*3+y * +-----+-----+-----+ +-----+ * 2 |(2,0)|(2,1)|(2,2)| |(0,2)| 2 = 0*3+2 = t*3+y * +-----+-----+-----+ +-----+ * |(1,0)| 3 = 1*3+0 = t*3+y * +-----+ * |(1,1)| 4 = 1*3+1 = t*3+y * +-----+ * |(1,2)| 5 = 1*3+2 = t*3+y * +-----+ * |(2,0)| 6 = 2*3+0 = t*3+y * +-----+ * |(2,1)| 7 = 2*3+1 = t*3+y * +-----+ * |(2,2)| 8 = 2*3+2 = x*3+y * +-----+ * */ #define BOARD_SIZE 3 /* ボードのサイズ */ #define SENTE_MARK 'o' /* 先手は 'o' (マル) */ #define GOTE_MARK 'x' /* 後手は 'x' (バツ) */ /* * 二次元の座標を一次元に変換する関数 */ int index2d ( int t, int y ) { return t * BOARD_SIZE + y; } int main ( void ) { /* * */ char board[BOARD_SIZE*BOARD_SIZE]; /* サイズは 3 × 3 */ int t; /* 縱 */ int y; /* 横 */ /* * ある局面 * * oxx * xoo * oox */ board[index2d(0,0)] = 'o'; /* (0,0) */ board[index2d(0,1)] = 'x'; /* (0,1) */ board[index2d(0,2)] = 'x'; /* (0,2) */ board[index2d(1,0)] = 'x'; /* (1,0) */ board[index2d(1,1)] = 'o'; /* (1,1) */ board[index2d(1,2)] = 'o'; /* (1,2) */ board[index2d(2,0)] = 'o'; /* (2,0) */ board[index2d(2,1)] = 'x'; /* (2,1) */ board[index2d(2,2)] = 'x'; /* (2,2) */ /* * */ t = 0; while ( t < BOARD_SIZE ) { y = 0; while ( y < BOARD_SIZE ) { printf ( "%c", board[index2d(t,y)] ); y = y + 1; } printf ( "\n" ); t = t + 1; } /* * */ return 0; } /* * */
$ ./sample-013.exe oxx xoo oxx $
Download : sample-014.c
/* * 2020/11/20 sample-014.c */ #include <stdio.h> /* * ◯×ゲームのボード (二次元版) * * y * 0 1 2 * +-----+-----+-----+ * 0 |(0,0)|(0,1)|(0,2)| * +-----+-----+-----+ * t 1 |(1,0)|(1,1)|(1,2)| * +-----+-----+-----+ * 2 |(2,0)|(2,1)|(2,2)| * +-----+-----+-----+ * */ #define BOARD_SIZE 3 /* ボードのサイズ */ #define SENTE_MARK 'o' /* 先手は 'o' (マル) */ #define GOTE_MARK 'x' /* 後手は 'x' (バツ) */ int main ( void ) { /* * */ char board[BOARD_SIZE][BOARD_SIZE]; /* サイズは 3 × 3 */ int t; /* 縱 */ int y; /* 横 */ /* * ある局面 * * oxx * xoo * oox */ board[0][0] = 'o'; /* (0,0) */ board[0][1] = 'x'; /* (0,1) */ board[0][2] = 'x'; /* (0,2) */ board[1][0] = 'x'; /* (1,0) */ board[1][1] = 'o'; /* (1,1) */ board[1][2] = 'o'; /* (1,2) */ board[2][0] = 'o'; /* (2,0) */ board[2][1] = 'x'; /* (2,1) */ board[2][2] = 'x'; /* (2,2) */ /* * */ t = 0; while ( t < BOARD_SIZE ) { y = 0; while ( y < BOARD_SIZE ) { printf ( "%c", board[t][y] ); y = y + 1; } printf ( "\n" ); t = t + 1; } /* * */ return 0; } /* * */
$ ./sample-014.exe oxx xoo oxx $
Download : sample-015.c
/* * 2020/11/20 sample-015.c */ #include <stdio.h> /* * ◯×ゲームのボード (一次元版) * * y * 0 1 2 (y,t) * +-----+-----+-----+ +-----+ * 0 |(0,0)|(0,1)|(0,2)| |(0,0)| 0 = 0*3+0 = t*3+y * +-----+-----+-----+ +-----+ * t 1 |(1,0)|(1,1)|(1,2)| |(0,1)| 1 = 0*3+1 = t*3+y * +-----+-----+-----+ +-----+ * 2 |(2,0)|(2,1)|(2,2)| |(0,2)| 2 = 0*3+2 = t*3+y * +-----+-----+-----+ +-----+ * |(1,0)| 3 = 1*3+0 = t*3+y * +-----+ * |(1,1)| 4 = 1*3+1 = t*3+y * +-----+ * |(1,2)| 5 = 1*3+2 = t*3+y * +-----+ * |(2,0)| 6 = 2*3+0 = t*3+y * +-----+ * |(2,1)| 7 = 2*3+1 = t*3+y * +-----+ * |(2,2)| 8 = 2*3+2 = x*3+y * +-----+ * */ #define BOARD_SIZE 3 /* ボードのサイズ */ #define SENTE_MARK 'o' /* 先手は 'o' (マル) */ #define GOTE_MARK 'x' /* 後手は 'x' (バツ) */ int main ( void ) { /* * */ char board[BOARD_SIZE][BOARD_SIZE]; /* サイズは 3 × 3 */ int t; /* 縱 */ int y; /* 横 */ /* * */ printf ( "sizeof ( board[0][0] ) = %d\n", sizeof ( board[0][0] ) ); printf ( "sizeof ( board[0] ) = %d\n", sizeof ( board[0] ) ); printf ( "\n" ); for ( t = 0; t < BOARD_SIZE; t++ ) { printf ( "board[%d]=%x\n", t, &board[t] ); for ( y = 0; y < BOARD_SIZE; y++ ) { /* アドレスの表示 */ printf ( "\t(%d,%d)=%x\n", t, y, &board[t][y] ); } printf ( "\n" ); } /* * */ return 0; } /* * */
$ ./sample-015.exe sizeof ( board[0][0] ) = 1 sizeof ( board[0] ) = 3 board[0]=173def50 (0,0)=173def50 (0,1)=173def51 (0,2)=173def52 board[1]=173def53 (1,0)=173def53 (1,1)=173def54 (1,2)=173def55 board[2]=173def56 (2,0)=173def56 (2,1)=173def57 (2,2)=173def58 $
Download : sample-017.c
/* * 2020/11/20 sample-017.c */ #include <stdio.h> /* * 再帰を利用した階乗の計算(既出) * * 1 ( n < 1 ) * n! = { * n * { (n-1)! } */ int fact ( int n ) { if ( n < 1 ) { // n が 0 の時 return 1; } else { return fact ( n - 1 ) * n; // 再帰を利用して計算 } } int main ( void ) { /* * */ int n = 5; /* * */ printf ( "fact(%d)=%d\n", n, fact(n) ); /* * */ return 0; } /* * */
$ ./sample-017.exe fact(5)=120 $
Download : sample-018.c
/* * 2020/11/20 sample-018.c */ #include <stdio.h> /* * 仮引数変数 n のアドレスと値はどうなっているか ? */ int fact ( int n ) { int f; printf ( "(fact:前) n = %d, &n = %x\n", n, &n ); if ( n < 1 ) { f = 1; } else { f = fact ( n - 1 ) * n; } printf ( "(fact:後) n = %d, &n = %x\n", n, &n ); return f; } int main ( void ) { /* * */ int n = 5; int f; /* * */ printf ( "(main) n = %d, &n = %x\n", n, &n ); /* * */ f = fact(n); printf ( "fact(%d)=%d\n", n, f ); /* * */ return 0; } /* * */
$ ./sample-018.exe (main) n = 5, &n = 27c8c3c8 (fact:前) n = 5, &n = 27c8c39c (fact:前) n = 4, &n = 27c8c36c (fact:前) n = 3, &n = 27c8c33c (fact:前) n = 2, &n = 27c8c30c (fact:前) n = 1, &n = 27c8c2dc (fact:前) n = 0, &n = 27c8c2ac (fact:後) n = 0, &n = 27c8c2ac (fact:後) n = 1, &n = 27c8c2dc (fact:後) n = 2, &n = 27c8c30c (fact:後) n = 3, &n = 27c8c33c (fact:後) n = 4, &n = 27c8c36c (fact:後) n = 5, &n = 27c8c39c fact(5)=120 $
Download : sample-019.c
/* * 2020/11/20 sample-019.c */ #include <stdio.h> /* * 引数のアドレスは ? ( 引数の順に並んいる ) */ int subfunc ( int a, int b ) { printf ( "a = %d, &a = %x\n", a, &a ); printf ( "b = %d, &b = %x\n", b, &b ); } int main ( void ) { /* * */ subfunc ( 2, 4 ); /* * */ return 0; } /* * */
$ ./sample-019.exe a = 2, &a = b7edab7c b = 4, &b = b7edab78 $
Download : sample-020.c
/* * 2020/11/20 sample-020.c */ #include <stdio.h> /* * 一つの引数変数から(ポインター経由で..)他の引数変数を参照する事ができる */ int subfunc ( int a, int b ) { printf ( "a = %d, &a = %x\n", a, &a ); printf ( "b = %d, &b = %x\n", b, &b ); /* * 変数 b を利用して変数 a の値が参照できる */ printf ( "*(&b-1) = %d, &b-1 = %x\n", *(&b-1), &b-1 ); /* * 変数 b を利用して変数 a の値を変更(代入)できる */ *(&b-1) = 10; printf ( "a = %d\n", a ); } int main ( void ) { /* * */ subfunc ( 2, 4 ); /* * */ return 0; } /* * */
$ ./sample-020.exe a = 2, &a = 4153ca6c b = 4, &b = 4153ca68 *(&b-1) = 0, &b-1 = 4153ca64 a = 2 $
Download : sample-021.c
/* * 2020/11/20 sample-021.c */ #include <stdio.h> /* * 先頭の引数のポインタを利用して、残りの引数を参照する */ int subfunc ( int a, ... ) { printf ( "a = %d, &a = %x\n", a, &a ); printf ( "*(&a+1) = %d, &a + 1 = %x\n", *(&a+1), &a+1 ); printf ( "*(&a+2) = %d, &a + 2 = %x\n", *(&a+2), &a+2 ); } int main ( void ) { /* * */ subfunc ( 1,2,3,4,5 ); /* * */ return 0; } /* * */
$ ./sample-021.exe a = 1, &a = e023163c *(&a+1) = 1724570528, &a + 1 = e0231640 *(&a+2) = 11051, &a + 2 = e0231644 $
Download : sample-022.c
/* * 2020/11/20 sample-022.c */ #include <stdio.h> /* * 引数をアドレス経由で参照する * 最初の引数 n は、他の引数の個数としての情報を担う * 関数(のプログラム作成時)側では、 * (実行時の呼出の時に)幾つの引数が指定されるかを知る術がない * 最初の引数 n の「値」を信じて振る舞うしかない */ int subfunc ( int n, ... ) { int i; for ( i = 0; i < n; i++ ) { printf ( "arg[%d]=%d\n", i, *(&n+1+i) ); } } int main ( void ) { /* * */ printf ( "subfunc ( 5,1,2,3,4,5 );\n" ); subfunc ( 5,1,2,3,4,5 ); // 1 から 5 の追加の引数の個数を適切に指定 printf ( "subfunc ( 3,9,8,7,6 );\n" ); subfunc ( 3,9,8,7,6 ); // 4 つの追加の引数があるのに 3 としているので、最後の値は利用されない /* * */ return 0; } /* * */
$ ./sample-022.exe subfunc ( 5,1,2,3,4,5 ); arg[0]=0 arg[1]=0 arg[2]=0 arg[3]=3 arg[4]=135889920 subfunc ( 3,9,8,7,6 ); arg[0]=0 arg[1]=0 arg[2]=0 $
Download : sample-023.c
/* * 2020/11/20 sample-023.c */ #include <stdio.h> #include "s_print.h" /* * 最初の引数に指定した文字列の中に 「%」があったら、後の引数の値に置き換える */ int print_int_with_format ( char *fmt, int a, ... ) { int i; int j; j = 0; i = 0; while ( fmt[i] != '\0' ) { /* 文字列の終わりがくるまで */ if ( fmt[i] == '%' ) { /* '%' がきたら特別処理 printf ( "%d", *(&a+j) ); /* 追加引数の値を取り出し出力 */ j = j + 1; /* 次の引数の準備 */ } else { /* '%' 以外は.. */ s_print_char ( fmt[i] ); /* その文字をそのまま出力 */ } i = i + 1; /* 次の文字 */ } } int main ( void ) { /* * */ print_int_with_format ( "%\n", 99 ); print_int_with_format ( "i = %, j = %\n", 10, 20 ); print_int_with_format ( "1 st = %, 2nd = %, 3rd = % \n", 10, 20, 90 ); /* * */ return 0; } /* * */
$ ./sample-023.exe i = , j = 1 st = , 2nd = , 3rd = $
Download : sample-024.c
/* * 2020/11/20 sample-024.c */ #include <stdio.h> #include "s_print.h" /* * */ int main ( void ) { /* * */ // printf ( "..." ); /* これまで printf は「文字列出力」専門だった */ /* 実は、もっと、凄い機能がある */ printf ( "%d\n", 99 ); // 文字列の中に「%d」をいれると、これは、その後の引数の // 整数値引数の値に書き変わる /* * 引数の個数は可変長 */ printf ( "i=%d, j=%d, k=%d\n", 10, 20, 90 ); /* * 上と同じ事をする命令列 ( いままでは面倒な事をしていた ) */ s_print_string ( "i=" ); s_print_int ( 10 ); s_print_string ( ", j=" ); s_print_int ( 20 ); s_print_string ( ", k=" ); s_print_int ( 90 ); s_print_newline(); /* * */ return 0; } /* * */
$ ./sample-024.exe 99 i=10, j=20, k=90 i=10, j=20, k=90 $
Download : sample-025.c
/* * 2020/11/20 sample-025.c */ #include <stdio.h> #include "s_print.h" /* * printf を利用してみる */ int main ( void ) { /* * */ printf ( "abc\n" ); /* いままでと同じ */ /* 文字列がそのままでる */ printf ( "i=%d\n", 10 ); /* 文字列の中の 「%d」の部分が、二つ目の引数 10 に変る */ printf ( "i=%d, j=%d\n", 10, 20 ); /* 「%d」が二度でれば二度めは三つ目の引数の値を利用 */ printf ( "a=%f\n", 12.34 ); /* 実数(浮動小数点数) の場合は 「%f」を使う */ printf ( "i=%d, a=%f, c=%c, s=%s\n", 123, 12.34, 'a', "abc" ); /* 混在も可能 %c が文字 %s が文字列(文字型へのポインタ値) */ /* * */ return 0; } /* * */
$ ./sample-025.exe abc i=10 i=10, j=20 a=12.340000 i=123, a=12.340000, c=a, s=abc $
Download : sample-026.c
/* * 2020/11/20 sample-026.c */ #include <stdio.h> #include "s_print.h" /* * printf の更なる機能 : 書式付きの出力 */ int main ( void ) { /* * 同じ数値を異る形式(書式 / format)で出力できる */ printf ( "a=%10.6f\n", -12.34 ); /* 出力する形式を指定できる 10.6 は、全体 10 桁、小数点以下 6 桁の意味 */ printf ( "a=%20.10f\n", -12.34 ); /* 出力する形式を指定できる 20.10 は、全体 20 桁、小数点以下 10 桁の意味 */ /* * */ return 0; } /* * */
$ ./sample-026.exe a=-12.340000 a= -12.3400000000 $
Download : sample-027.c
/* * 2020/11/20 sample-027.c */ #include <stdio.h> #include "s_print.h" /* * scanf, printf (出力関数) の入力版 */ int main ( void ) { /* * */ int i; /* * */ printf ( "i の値を入力してください " ); scanf ( "%d", &i ); /* '%d' --> printf と同じ */ /* i = s_input_int(); */ /* i = 99; の時 scanf ( "%d", i ); は、 scanf ( "%d", 99 ); の意味。 これでは、scanf はどうやっても i の値を得る事ができない。 そこで、「&i」を指定 ( i のポインタ値がわかれば、 i の値が変更できる ) */ /* * */ printf ( "入力された i の値は %d でした\n", i ); /* * */ return 0; } /* * */
10
$ ./sample-027.exe < sample-027.in i の値を入力してください 10 入力された i の値は 10 でした $
/* * 20201127-01-QQQQ.c * ??????????(???????) * ????????z???????????????????? * ????????z???(????????)????????????[??? * ?????????????????????A??????????????????? * ??: * "12", "abc", "x" <=> "12\0abc\0x\0" * ^^^^ * "12" */ #include <stdio.h> #include <string.h> /* strcmp ??p??????.. */ /* * */ #define EOS '\0' #define NO_STRING (-1) /* ?u?????????????v????\?????l */ /* * print_string_seq * ????????o?? */ void print_string_seq ( char sseq[] ) { int i; /* ????A?Q????????? */ for ( i = 0; sseq[i] != EOS; i++ ) { /* ????????????.. */ putchar ( '"' ); while ( sseq[i] != EOS ) { /* ????????o????? */ putchar ( sseq[i] ); /* ??????o?? */ i++; /* ??????? */ } putchar ( '"' ); /* ???????Asseq[i] ??? EOS ?????? */ if ( sseq[i+1] != EOS ) { /* ?????A???????????? */ printf ( ", " ); /* ?????????o?? */ } else { printf ( "\n" ); /* ?s??????s???o?? */ } } } /* * int next_string_seq ( char sseq[], int now ) * ??????????????? */ int next_string_seq ( char sseq[], int now ) { if ( sseq[now] == EOS ) { /* ???????????? */ return now; /* ???????A?i???? */ } while ( sseq[now] != EOS ) { /* ???????????X?L?b?v???? */ /* ??????????? */ now++; /* ?????????? */ } /* ??????Anow ??A??????????????? EOS ???u */ return now + 1; /* +1 ???鎖????A?????????????????? */ } /* * int find_string_seq ( char sseq[], int now, char string[] ) * ??????????T?? */ #define NOT_FOUND (-1) /* ?u???????????????v????\?????l */ int find_string_seq ( char sseq[], int now, char string[] ) { if ( string[0] == EOS ) { /* ?T???????????? */ /* ??`(?????????A???????????)???A?????? */ return NOT_FOUND; /* ???t?????????? */ } while ( sseq[now] != EOS ) { /* ???????????? */ if ( !strcmp ( sseq + now, string ) ) { /* ???????v???? */ return now; /* ?????????? */ } else { /* ??????????? */ now = next_string_seq ( sseq, now ); } } /* ??????????A???t???????????? */ return NOT_FOUND; } /* * main */ int main ( void ) { char sseq[] = "12\0abc\0XY\0abc\0"; /* ???????????? */ int pos; /* ???????? */ printf ( "sseq = \"%s\"\n", sseq ); /* ???????????\???????? */ /* ???????????\??????? */ /* ???????????????o????A??????????\?? */ for ( pos = 0; sseq[pos] != EOS; pos = next_string_seq ( sseq, pos ) ) { printf ( "sseq %d = %s\n", pos, sseq + pos ); } /* ??????????????? "abc" ?????????\?????? */ for ( pos = find_string_seq ( sseq, 0, "abc" ); pos != NOT_FOUND; pos = find_string_seq ( sseq, pos, "abc" ) ) { printf ( "%d\n", pos ); pos = next_string_seq ( sseq, pos ); } return 0; }
#include <stdio.h> #define EOS '\0' int main(void) { char cary[5]; cary[0] = 'a'; cary[1] = 'b'; cary[2] = 'c'; cary[3] = EOS; printf ( "cary = %s\n", cary ); /* 文字列の代わりに文字型配列名 */ printf ( "abc = %s\n", "abc" ); /* 文字列「abc」の出力 */ printf ( "先頭の文字は %c\n", cary[0] ); printf ( "先頭の文字は %c\n", "abc"[0] ); printf ( "先頭の文字は %c\n", *cary ); printf ( "先頭の文字は %c\n", *"abc" ); /* "abc"[1] = 'Z'; */ /* 文字列は変更不能 */ cary[1] = 'Z'; printf ( "cary = %s\n", cary ); /* 文字列の代わりに文字型配列名 */ /* 0 1 2 3 4 前: 'a' 'Z' 'c' EOS ? => "aZc" を表現 後: 'a' 'Z' 'c' '9' EOS => "aZc9" を表現 */ cary[3] = '9'; cary[4] = EOS; printf ( "cary = %s\n", cary ); /* 文字列の代わりに文字型配列名 */ /* 0 1 2 3 4 前: 'a' 'Z' 'c' '9' EOS => "aZc9" を表現 後: 'a' 'Z' EOS '9' EOS => "aZ" を表現 */ cary[2] = EOS; printf ( "cary = %s\n", cary ); /* 文字列の代わりに文字型配列名 */ return 0; }
#include <stdio.h> #define EOS '\0' void func( char cary[] ) { /* char *cary */ cary[0] = 'A'; } int main(void) { char cary[] = "abc"; /* (1) char cary[] = { 'a', 'b', 'c', EOS }; 初期化を行う場合のみ、サイズをさぼる事ができる # サイズの指定があって # かつ、初期化の値の個数が合わない場合 # 初期値の数が少ない場合は、足りない所に何がはいるかわからない # 初期値の数が多い場合は、多い分は捨てられる (2) char cary[4] = { 'a', 'b', 'c', EOS }; (3) char cary[4]; cary[0] = 'a'; cary[1] = 'b'; cary[2] = 'c'; cary[3] = EOS; */ printf ( "cary = %s\n", cary ); func ( cary ); /* 関数呼び出しは、呼び出し元の変数の値を変えない */ printf ( "cary = %s\n", cary ); return 0; }
#include <stdio.h> #define EOS '\0' void func( char cary[] ) { /* char *cary */ cary[0] = 'A'; /* 引数で指定された配列の最初の要素を変更 */ } int main(void) { char cary[] = "abc"; /* (1) char cary[] = { 'a', 'b', 'c', EOS }; 初期化を行う場合のみ、サイズをさぼる事ができる # サイズの指定があって # かつ、初期化の値の個数が合わない場合 # 初期値の数が少ない場合は、足りない所に何がはいるかわからない # 初期値の数が多い場合は、多い分は捨てられる (2) char cary[4] = { 'a', 'b', 'c', EOS }; (3) char cary[4]; cary[0] = 'a'; cary[1] = 'b'; cary[2] = 'c'; cary[3] = EOS; */ printf ( "cary = %s\n", cary ); func ( cary ); /* 関数呼び出しは、呼び出し元の変数の値を変えない */ printf ( "cary = %s\n", cary ); func ( cary + 1 ); /* cary 二つ目 cary + 1 -> cary[1], .. cary -> cary[0], cary[1], .. */ printf ( "cary = %s\n", cary ); return 0; }
#include <stdio.h> #define LINE_SIZE 80 int main(void) { char line[LINE_SIZE]; /* 文字配列を利用して、その文字配列に、 文字列と同じ形のデータを記録する事ができる */ /* 文字列を入力する場合も、文字配列に記録させられる */ printf ( "キーボードから文字列を入力し、[Enter] を押す\n" ); fgets ( line, LINE_SIZE, stdin ); printf ( "入力は、\"%s\" でした。\n", line ); /* fgets を使うと、改行を含めて、入力される */ return 0; }
#include <stdio.h> int main(void) { char c; char d; /* | | +---+ c 0x7ffffc56f776 | | +---+ d 0x7ffffc56f777 | | +---+ | | */ c = 'A'; d = 'Z'; /* | | +---+ c 0x7ffffc56f776 |'A'| +---+ d 0x7ffffc56f777 |'Z'| +---+ | | */ printf ( "c = %c\n", c ); printf ( "d = %c\n", d ); printf ( "&c = %p\n", &c ); /* 変数 c の前に & をつけると address がわかる */ printf ( "&d = %p\n", &d ); /* printf で address を表示する書式は %p */ /* 出力は 16 進数 */ return 0; }
#include <stdio.h> int main(void) { char cary[2]; /* | | +---+ cary[0] 0x7ffff3980576 | | +---+ cary[1] 0x7ffff3980577 | | +---+ | | */ cary[0] = 'A'; cary[1] = 'Z'; /* | | +---+ cary[0] 0x7ffff3980576 |'A'| +---+ cary[1] 0x7ffff3980577 |'Z'| +---+ | | */ printf ( "cary[0] = %c\n", cary[0] ); printf ( "cary[1] = %c\n", cary[1] ); printf ( "&cary[0] = %p\n", &cary[0] ); printf ( "&cary[1] = %p\n", &cary[1] ); printf ( "cary = %p\n", cary ); /* 配列名 */ return 0; }
#include <stdio.h> void func( char ca[] ) { printf ( "F:ca[0] = '%c'\n", ca[0] ); ca[0] = 'Z'; printf ( "F:ca[0] = '%c'\n", ca[0] ); } int main(void) { char ca[1]; /* ca[0] という一つの文字型変数 */ ca[0] = 'A'; printf ( "M:ca[0] = '%c'\n", ca[0] ); func( ca ); /* 見えないが, ca[0] の値が書き変わる */ printf ( "M:ca[0] = '%c'\n", ca[0] ); return 0; }
#include <stdio.h> void func( char ca[] ) { printf ( "F:ca[0] = '%c'\n", ca[0] ); ca[0] = 'Z'; printf ( "F:ca[0] = '%c'\n", ca[0] ); } int main(void) { char cv; /* cv という一つの文字型変数 */ cv = 'A'; printf ( "M:cv = '%c'\n", cv ); func( &cv ); /* 見えないが, cv の値が書き変わる */ printf ( "M:cv = '%c'\n", cv ); return 0; }
#include <stdio.h> int main(void) { char cv; int iv; double dv; char cary[10]; /* cary[0] ?` cary[9] */ /* sizeof cary = sizeof char * 10 */ int iary[10]; printf ( "sizeof char = %ld\n", sizeof(cv) ); printf ( "sizeof int = %ld\n", sizeof(iv) ); printf ( "sizeof double = %ld\n", sizeof(dv) ); printf ( "sizeof char = %ld\n", sizeof(char) ); printf ( "sizeof int = %ld\n", sizeof(int) ); printf ( "sizeof double = %ld\n", sizeof(double) ); printf ( "sizeof cary = %ld\n", sizeof(cary) ); printf ( "sizeof iary = %ld\n", sizeof(iary) ); return 0; }
#include <stdio.h> int main(void) { int iary[10]; printf ( "iary = %p\n", iary ); printf ( "&iary[0] = %p\n", &iary[0] ); printf ( "&iary[1] = %p\n", &iary[1] ); printf ( "iary + 1 = %p\n", iary + 1 ); /* (A) +1 だから、番地が 1 増える (B) iary + 1 = &iary[1] -> iary[1] の番地だから iary ( iary[0] の番地 )より sizeof int ( = 4 ) だけ大きい 実は、 */ /* | | +---+ iary[0] | | sizeof int = 4 +---+ | | +---+ | | +---+ | | +---+ iary[1] | | iary[0] の番地の 4 byte 先 +---+ | | */ return 0; } /* ary[0] = *ary; ary[1] = *(ary+1); ary[n] = *(ary+n); */
#include <stdio.h> int main(void) { double dary[10]; printf ( "dary = %p\n", dary ); printf ( "&dary[0] = %p\n", &dary[0] ); printf ( "&dary[1] = %p\n", &dary[1] ); printf ( "dary + 1 = %p\n", dary + 1 ); return 0; }
#include <stdio.h> int main(void) { int vi = 5; double vd = 5.0; printf ( "%d/2 = %d\n", vi, vi/2 ); printf ( "%f/2.0 = %f\n", vd, vd/2.0 ); vi = vd; /* vd の値の型は浮動小数点数 vi の型は、整数型 */ /* => 型変換がおきている */ /* 値の型は、変数の型に「型変換」される */ printf ( "vi = %d\n", vi ); return 0; }
#include <stdio.h> int main(void) { int iv = 5.0; /* 浮動小数点数を代入 */ /* => 整数に型変換 */ printf ( "%d/2 = %d\n", iv, iv / 2 ); printf ( "%f/2 = %f\n", 5.0, 5.0 / 2 ); /* 浮動小数点数と整数型の混在 */ /* 浮動小数点数型に一度、型変換し、それを計算する */ return 0; }
?O?????e : ?f?[?^?\?? (4) ?u?` ?u??????v??u?????^?z??v ?????^?z?? ( ?????^??z?? ) # ?z???v?f???????^????? # char cary[4]; # cary[0], cary[1], cary[2], cary[3] # 'a' 'b' 'c' '\0' ?????? ?u"(?_?u???N?H?[?e?[?V????)?v??????????????? "abc" = { 'a', 'b', 'c', '\0' } # '\0' ?? NUL ???? ( ????\??????????????????????????????? ) # EOS ( End Of String : ???????I??? ) ?????g???? ?????z???A??????????????f?[?^(?????R?[?h?????)?? ???(???)?????A?????????A??????????U???? ?u??????v??A?????I???A??????^?z???A?????????? ?\??????????AEOS ??????????????????????????????? <<????: ?????z??????????>> ?????^?z???v?f(???)???A???????\ ???????v?f??????????? ( ?????????g???X?????? ) # ??????(???e????)??A???????т??????????? # => ?u??X?s?\?v??????????????? !! ??X??\???????(????????)???K?v????A !! ?????z???p?????? ?????z?????????A??????????Z????\ ?u?z??v???????e???????????????n???? +1 ?????A???????????菜????? * ????????A????????????o???? *(??????+n) = ??????[n] *(?z??+n) = ?z??[n] ???????????????w?????z??(??????) !!! ??????????z????w???鎖????A !!! ????????A?z???v?f??l???X????? fgets ??u??????v????? == ?????????f?? 1 byte ????L?^?????Z??????????????????? ???Z?? : ?????????U?????????? ?????\??A?L?^???????????鎖(???)??????? ?L?^??????????(?f?[?^)?????????????A???x?????o???? ?Z?????A??n?????????? ?Z????????????A??n????????????? C ?????????A ??????????f???????????? ????A?????^?z???A????Z?????????????????? C ??????????A??n?????????? ?????O??u&?v????????A ??n??鎖??????? !!! ?u&?v???O?? scanf ???????? !!! => ???????A?u??????????v?????u?????????v????? !!! => ????????????? !!! ????A?u??????n?????o???v????????Z?q ??n????l(?f?[?^)????A ?????????o?R??n??????????? ?t??A?z??????A?????z????A??n????A & ???????K?v????? fgets ??????A?z????????w?? !!! ?Z??????e???X??????A??n???????? !!! => C ???????A??яo???????????n???????n????????A !!! ????????l???A??яo????????????X??\ !!! 1) scanf ??????A?????l???X????? !!! => ??n??n????????? !!! => ?????O??u&?v???K?v????R !!! ?z???n??????????? !!! ?u?z??v??A?u?z???????v?f?v???n(??l???????) !!! ??????????u?z??v???w???鎖???? !!! ?z???v?f??l????X????? ?????^??????A????Z????????????? ?????^??T?C?Y?? 1 (byte) ????? ????^(??????..)??A??????Z?????????????\??????????A ?T?C?Y??A????Z?????? ????? & ??t???鎖????A??n(?P??鐔?l?????)??鎖??????? => printf ?? %p ??\????\ +1 ???????A?????n??????????????^??T?C?Y????????????? ?u&?????????????l?v??A?u(?P???)?????l?v??????A ?^??????????????m????? => ?|?C???^?[?l = ??n + ?^???? ?^???? ?T?C?Y(???????????????Z?????K?v??) ???Z??????????A???U?????????? ? ?u*?v??t???鎖????A????^??????????U?????????? ?^??????? double ?^??l?? int ?^???????? ?l??^??? ( double -> int ) double ?^?? int ?^???????????v?Z?????A ????Aint ?^??l?? double ?^?????A ???? double ?^??????v?Z???s???B # ?^????i
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20201127-01.c
/* * 20201127-01-QQQQ.c * 文字列の並び(文字列列) * 一つの文字配列に複数の文字列を保存する * 大きな文字配列に(空文字列でない)複数の文字列を納める * 文字列列の最後には空文字列をいれ、それは文字列列の一部としない * 例: * "abc", "x", "12" <=> "abc\0x\012\0" * */ #include <stdio.h> #include <string.h> /* strcmp を利用するので.. */ /* * */ #define EOS '\0' #define NO_STRING (-1) /* 「文字列がもうない」事を表す数値 */ /* * print_string_seq * 文字列列の出力 */ void print_string_seq ( char sseq[] ) { int i; /* 現在、参照している場所 */ for ( i = 0; sseq[i] != EOS; i++ ) { /* まだ文字列がある.. */ putchar ( '"' ); while ( sseq[i] != EOS ) { /* 文字列を出力する */ putchar ( sseq[i] ); /* 文字の出力 */ i++; /* 次の文字 */ } putchar ( '"' ); if ( sseq[i+1] != EOS ) { /* 未だ、次の文字列がある */ printf ( ", " ); /* 区切り文字を出力 */ } else { printf ( "\n" ); /* 行末の改行を出力 */ } } } /* * int next_string_seq ( char sseq[], int now ) * 次の文字列の場所を返す */ int next_string_seq ( char sseq[], int now ) { if ( sseq[now] == EOS ) { /* 先頭が空文字列だった */ return now; /* それ以上は、進まない */ } while ( sseq[now] != EOS ) { /* 先頭の文字列をスキップする */ /* 次の場所を見る */ /* ** この部分を完成させなさい */ } /* ここで、now は、先頭の文字列の最後尾の EOS の位置 */ return now + 1; /* +1 する事により、次の文字列の先頭の場所となる */ } /* * int find_string_seq ( char sseq[], int now, char string[] ) * 文字列の場所を探す */ #define NOT_FOUND (-1) /* 「発見できなかった」事を表す数値 */ int find_string_seq ( char sseq[], int now, char string[] ) { if ( string[0] == EOS ) { /* 探す文字列が空文字列 */ /* 定義(文字列列には、空文字列を含めない)より、含まれない */ return NOT_FOUND; /* 見付からなかった */ } while ( sseq[now] != EOS ) { /* 空文字列でない限り */ if ( !strcmp ( sseq + now, string ) ) { /* 文字列が一致した */ return now; /* 現在の場所を返す */ } else { /* 次の場所を見る */ /* ** この部分を完成させなさい */ } } /* 最後までみたが、見付からないかった */ return NOT_FOUND; } /* * main */ int main ( void ) { char sseq[] = "12\0abc\0XY\0abc\0"; /* 文字列列を準備 */ int pos; /* 文字列の場所 */ printf ( "sseq = \"%s\"\n", sseq ); /* 先頭の文字列しか表示されない */ print_string_seq ( sseq ); /* 複数の文字列が表示される */ /* 文字列を一つずつ取り出して、場所の文字列の表示 */ for ( pos = 0; sseq[pos] != EOS; pos = next_string_seq ( sseq, pos ) ) { printf ( "sseq %d = %s\n", pos, sseq + pos ); } /* 文字文字列中に含まれる "abc" の場所を順に表示する */ for ( pos = 0; pos != NOT_FOUND; pos = find_string_seq ( sseq, pos, "abc" ) ) { printf ( "%d\n", pos ); pos = next_string_seq ( sseq, pos ); } return 0; }
$ ./20201127-01-QQQQ.exe sseq = "12" "12", "abc", "XY", "abc" sseq 0 = 12 sseq 3 = abc sseq 7 = XY sseq 10 = abc 0 3 10 $