Download : sample-001.c ( SJIS 版 )
/* * 2014/11/07 sample-001.c */ /* * 関数への引数渡し(単純型変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * func * 整数(int)型単純変数の仮引数 */ void func ( int var ) { printf ( "Func[1] : var = %d\n", var ); /* 引数の値を出力 */ var = - var; /* 引数の値の符号を変更 */ printf ( "Func[2] : var = %d\n", var ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない */ } /* * main * */ int main( int argc, char *argv[] ) { int v = 123; /* 整数(int)型単純変数の引数 */ printf ( "Main[1] : v = %d\n", v ); /* v を出力 */ func ( v ); /* func を呼び出す時に v の値を渡す */ printf ( "Main[2] : v = %d\n", v ); /* v を出力 */ /* 変数 v の値は変更されない */ /* 渡されているのは「値」のみ */ func ( 456 ); /* 引数には定数も OK */ /* そもそも変更の対象となる変数がない */ /* 誤解(変数そのものを渡す)の可能性はない */ return 0; }
C:\usr\c>sample-001 Main[1] : v = 123 Func[1] : var = 123 Func[2] : var = -123 Main[2] : v = 123 Func[1] : var = 456 Func[2] : var = -456 C:\usr\c>
Download : sample-002.c ( SJIS 版 )
/* * 2014/11/07 sample-002.c */ /* * 関数への引数渡し(構造体型変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #include <stdio.h> /* * 構造体型の定義 */ typedef struct { /* 新しい構造体型の宣言 */ int x; int y; } Point2D; /* 二次元の点型 */ /* * func * 構造体型変数の仮引数 */ void func ( Point2D pt ) { printf ( "Func[1] : pt.x = %d, pt.y = %d\n", pt.x, pt.y ); pt.x = pt.x + 1; /* x は一つふやす */ pt.y = pt.y - 1; /* y は一つ減らす */ printf ( "Func[2] : pt.x = %d, pt.y = %d\n", pt.x, pt.y ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない */ } /* * main * */ int main( int argc, char *argv[] ) { Point2D pa; pa.x = 12; pa.y = 34; printf ( "Main[1] : pa.x = %d, pa.y = %d\n", pa.x, pa.y ); func ( pa ); /* 関数を呼び出す時に構造体型の変数 pa を指定 */ printf ( "Main[2] : pa.x = %d, pa.y = %d\n", pa.x, pa.y ); /* 関数の中の変更は、呼出し側の変数に影響しない */ /* 渡されているのは「値」のみ */ return 0; }
C:\usr\c>sample-002 Main[1] : pa.x = 12, pa.y = 34 Func[1] : pt.x = 12, pt.y = 34 Func[2] : pt.x = 13, pt.y = 33 Main[2] : pa.x = 12, pa.y = 34 C:\usr\c>
Download : sample-003.c ( SJIS 版 )
/* * 2014/11/07 sample-003.c */ /* * 関数への引数渡し(配列型変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-003.c * 実行 * BASENAME */ #include <stdio.h> /* * func * 配列型変数の引数 */ void func ( int array[2] ) { printf ( "Func[1] : array[0] = %d, array[1] = %d\n", array[0], array[1] ); array[0] = array[0] + 1; array[1] = array[1] - 1; printf ( "Func[1] : array[0] = %d, array[1] = %d\n", array[0], array[1] ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない ... ????? */ } /* * main * */ int main( int argc, char *argv[] ) { int ia[2]; ia[0] = 12; ia[1] = 34; printf ( "Main[1] : ia[0] = %d, ia[1] = %d\n", ia[0], ia[1] ); func ( ia ); /* 関数を呼び出す時に「配列名」を指定する */ /* 「ia[2]」ではない事に注意 */ printf ( "Main[1] : ia[0] = %d, ia[1] = %d\n", ia[0], ia[1] ); /* 関数の中の変更が、呼出し側の変数に影響 !!!! */ /* 「値」が渡されるのでは ??? */ /* この内容説明については後日 */ /* 今回は、「そうゆうもの」と考える */ return 0; }
C:\usr\c>sample-003 Main[1] : ia[0] = 12, ia[1] = 34 Func[1] : array[0] = 12, array[1] = 34 Func[1] : array[0] = 13, array[1] = 33 Main[1] : ia[0] = 13, ia[1] = 33 C:\usr\c>
Download : sample-004.c ( SJIS 版 )
/* * 2014/11/07 sample-004.c */ /* * 関数への引数渡し(副作用の問題) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-004.c * 実行 * BASENAME */ #include <stdio.h> /* * funcArray * 配列型変数の引数 */ void funcArray ( int array[1] ) { printf ( "Func[1] : array[0] = %d\n", array[0] ); array[0] = - array[0]; printf ( "Func[2] : array[0] = %d\n", array[0] ); /* 結果的に呼出し元の変数の値を変更していまう(副作用がある) */ } /* * funcSimple * 単純型変数の引数 */ void funcSimple ( int simple ) { printf ( "Func[1] : simple = %d\n", simple ); simple = -simple; printf ( "Func[1] : simple = %d\n", simple ); } /* * main * */ int main( int argc, char *argv[] ) { int ia[1]; /* サイズ 1 !! の配列 */ int is; /* 単純変数 */ ia[0] = 12; is = 34; /* Test 1 : 単純変数 */ printf ( "<Test 1>\n" ); printf ( "Main[1-1] : is = %d\n", is ); funcSimple ( is ); printf ( "Main[1-2] : is = %d\n", is ); /* 影響はない */ /* 関数を呼んでも、main の変数の値は変更されない → 気を付かう必要がない */ /* Test 2 : 配列変数 */ printf ( "<Test 2>\n" ); printf ( "Main[2-1] : ia[0] = %d\n", ia[0] ); funcArray ( ia ); /* 配列名を指定 */ printf ( "Main[2-2] : ia[0] = %d\n", ia[0] ); /* 影響がある */ /* 関数を呼ぶと、main の変数の値は変更されてしまう(副作用) → 気を付かう必要がでてしまう ( ia の値は変更されるのされないの ? ) */ /* 関数を呼ぶと(代入文でないのに..) 変数の値値が変る事が前にも.. → scanf */ return 0; }
C:\usr\c>sample-004 <Test 1> Main[1-1] : is = 34 Func[1] : simple = 34 Func[1] : simple = -34 Main[1-2] : is = 34 <Test 2> Main[2-1] : ia[0] = 12 Func[1] : array[0] = 12 Func[2] : array[0] = -12 Main[2-2] : ia[0] = -12 C:\usr\c>
Download : sample-005.c ( SJIS 版 )
/* * 2014/11/07 sample-005.c */ /* * 関数への引数渡し(配列型と単純変数の比較) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-005.c * 実行 * BASENAME */ #include <stdio.h> /* * funcArray * 配列型変数の引数 */ void funcArray ( int array[1] ) { printf ( "Func[1] : array[0] = %d\n", array[0] ); array[0] = - array[0]; printf ( "Func[2] : array[0] = %d\n", array[0] ); } /* * funcSimple * 単純型変数の引数 */ void funcSimple ( int simple ) { printf ( "Func[1] : simple = %d\n", simple ); simple = -simple; printf ( "Func[1] : simple = %d\n", simple ); } /* * main * */ int main( int argc, char *argv[] ) { int ia[1]; /* サイズ 1 !! の配列 */ int is; /* 単純変数 */ ia[0] = 12; is = 34; /* Test 1 : 単純変数 */ printf ( "<Test 1>\n" ); printf ( "Main[1-1] : is = %d\n", is ); funcSimple ( is ); printf ( "Main[1-2] : is = %d\n", is ); /* 影響はない */ /* Test 2 : 配列変数 */ printf ( "<Test 2>\n" ); printf ( "Main[2-1] : ia[0] = %d\n", ia[0] ); funcArray ( ia ); /* 配列名を指定 */ printf ( "Main[2-2] : ia[0] = %d\n", ia[0] ); /* 影響がある */ /* Test 3 : 配列要素 */ printf ( "<Test 3>\n" ); printf ( "Main[3-1] : ia[0] = %d\n", ia[0] ); funcSimple ( ia[0] ); /* 配列要素を指定 */ printf ( "Main[3-2] : ia[0] = %d\n", ia[0] ); /* 影響はない */ /* Test 4 : 幻のテスト */ /* printf ( "<Test 4>\n" ); */ /* printf ( "Main[4-1] : is = %d\n", is ); */ /* funcArray ( is ); */ /* ココでエラーになる !! */ /* printf ( "Main[4-2] : is = %d\n", is ); */ /* Test 5 : & を付けると .. ? */ printf ( "<Test 5>\n" ); printf ( "Main[5-1] : is = %d\n", is ); funcArray ( &is ); /* 何だコリャ ???? */ printf ( "Main[5-2] : is = %d\n", is ); /* 影響がある !? */ /* scanf と同じ効果 ??? */ /* 謎は深まるばかりだが... */ return 0; }
C:\usr\c>sample-005 <Test 1> Main[1-1] : is = 34 Func[1] : simple = 34 Func[1] : simple = -34 Main[1-2] : is = 34 <Test 2> Main[2-1] : ia[0] = 12 Func[1] : array[0] = 12 Func[2] : array[0] = -12 Main[2-2] : ia[0] = -12 <Test 3> Main[3-1] : ia[0] = -12 Func[1] : simple = -12 Func[1] : simple = 12 Main[3-2] : ia[0] = -12 <Test 5> Main[5-1] : is = 34 Func[1] : array[0] = 34 Func[2] : array[0] = -34 Main[5-2] : is = -34 C:\usr\c>
Download : sample-006.c ( SJIS 版 )
/* * 2014/11/07 sample-006.c */ /* * 関数への引数渡し(配列を要素に持つ構造体変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-006.c * 実行 * BASENAME */ #include <stdio.h> /* * 構造体型の定義 */ typedef struct { /* 新しい構造体型の宣言 */ int x[2]; /* 構造体の要素が配列になっている */ } Point2D; /* 二次元の点型 */ /* * func * 配列を要素に持つ構造体型変数の仮引数 */ void func ( Point2D pt ) { printf ( "Func[1] : pt.x[0] = %d, pt.x[1] = %d\n", pt.x[0], pt.x[1] ); pt.x[0] = pt.x[0] + 1; /* x[0] は一つふやす */ pt.x[1] = pt.x[1] - 1; /* x[1] は一つ減らす */ printf ( "Func[1] : pt.x[0] = %d, pt.x[1] = %d\n", pt.x[0], pt.x[1] ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない */ } /* * main * */ int main( int argc, char *argv[] ) { Point2D pa; pa.x[0] = 12; pa.x[1] = 34; printf ( "Main[1] : pa.x[0] = %d, pa.x[1] = %d\n", pa.x[0], pa.x[1] ); func ( pa ); /* 関数を呼び出す時に構造体型の変数 pa を指定 */ printf ( "Main[2] : pa.x[0] = %d, pa.x[1] = %d\n", pa.x[0], pa.x[1] ); /* 関数の中の変更は、呼出し側の変数に影響しない */ /* 渡されているのは「値」のみ */ /* 構造体型の変数は中に配列があっても OK */ return 0; }
C:\usr\c>sample-006 Main[1] : pa.x[0] = 12, pa.x[1] = 34 Func[1] : pt.x[0] = 12, pt.x[1] = 34 Func[1] : pt.x[0] = 13, pt.x[1] = 33 Main[2] : pa.x[0] = 12, pa.x[1] = 34 C:\usr\c>
/* * 2014/11/07 sample-001.c */ /* * 関数への引数渡し(単純型変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * func * 整数(int)型単純変数の仮引数 */ void func ( int var ) { printf ( "Func[1] : var = %d\n", var ); /* 引数の値を出力 */ var = - var; /* 引数の値の符号を変更 */ printf ( "Func[2] : var = %d\n", var ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない */ } /* * main * */ int main( int argc, char *argv[] ) { int v = 123; /* 整数(int)型単純変数の引数 */ printf ( "Main[1] : v = %d\n", v ); /* v を出力 */ func ( v ); /* func を呼び出す時に v の値を渡す */ printf ( "Main[2] : v = %d\n", v ); /* v を出力 */ /* 変数 v の値は変更されない */ /* 渡されているのは「値」のみ */ func ( 456 ); /* 引数には定数も OK */ /* そもそも変更の対象となる変数がない */ /* 誤解(変数そのものを渡す)の可能性はない */ return 0; }
/* * 2014/11/07 sample-002.c */ /* * 関数への引数渡し(構造体型変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #include <stdio.h> /* * 構造体型の定義 */ typedef struct { /* 新しい構造体型の宣言 */ int x; int y; } Point2D; /* 二次元の点型 */ /* * func * 構造体型変数の仮引数 */ void func ( Point2D pt ) { printf ( "Func[1] : pt.x = %d, pt.y = %d\n", pt.x, pt.y ); pt.x = pt.x + 1; /* x は一つふやす */ pt.y = pt.y - 1; /* y は一つ減らす */ printf ( "Func[2] : pt.x = %d, pt.y = %d\n", pt.x, pt.y ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない */ } /* * main * */ int main( int argc, char *argv[] ) { Point2D pa; pa.x = 12; pa.y = 34; printf ( "Main[1] : pa.x = %d, pa.y = %d\n", pa.x, pa.y ); func ( pa ); /* 関数を呼び出す時に構造体型の変数 pa を指定 */ printf ( "Main[2] : pa.x = %d, pa.y = %d\n", pa.x, pa.y ); /* 関数の中の変更は、呼出し側の変数に影響しない */ /* 渡されているのは「値」のみ */ return 0; }
/* * 2014/11/07 sample-003.c */ /* * 関数への引数渡し(配列型変数版) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-003.c * 実行 * BASENAME */ #include <stdio.h> /* * func * 配列型変数の引数 */ void func ( int array[2] ) { printf ( "Func[1] : array[0] = %d, array[1] = %d\n", array[0], array[1] ); array[0] = array[0] + 1; array[1] = array[1] - 1; printf ( "Func[1] : array[0] = %d, array[1] = %d\n", array[0], array[1] ); /* 引数の値を再度出力 */ /* 仮引数変数の値は変化している */ /* その変更は、main には影響しない ... ????? */ } /* * main * */ int main( int argc, char *argv[] ) { int ia[2]; ia[0] = 12; ia[1] = 34; printf ( "Main[1] : ia[0] = %d, ia[1] = %d\n", ia[0], ia[1] ); func ( ia ); /* 関数を呼び出す時に「配列名」を指定する */ /* 「ia[2]」ではない事に注意 */ printf ( "Main[1] : ia[0] = %d, ia[1] = %d\n", ia[0], ia[1] ); /* 関数の中の変更が、呼出し側の変数に影響 !!!! */ /* 「値」が渡されるのでは ??? */ /* この内容説明については後日 */ /* 今回は、「そうゆうもの」と考える */ return 0; }
/* * 2014/11/07 sample-005.c */ /* * 関数への引数渡し(配列型と単純変数の比較) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-005.c * 実行 * BASENAME */ #include <stdio.h> /* * funcArray * 配列型変数の引数 */ void funcArray ( int array[1] ) { printf ( "Func[1] : array[0] = %d\n", array[0] ); array[0] = - array[0]; printf ( "Func[2] : array[0] = %d\n", array[0] ); } /* * funcSimple * 単純型変数の引数 */ void funcSimple ( int simple ) { printf ( "Func[1] : simple = %d\n", simple ); simple = -simple; printf ( "Func[2] : simple = %d\n", simple ); } /* * main * */ int main( int argc, char *argv[] ) { int ia[1]; /* サイズ 1 !! の配列 */ int is; /* 単純変数 */ ia[0] = 12; is = 34; /* Test 1 : 単純変数 */ printf ( "<Test 1>\n" ); printf ( "Main[1-1] : is = %d\n", is ); funcSimple ( is ); printf ( "Main[1-2] : is = %d\n", is ); /* 影響はない */ /* Test 2 : 配列変数 */ printf ( "<Test 2>\n" ); printf ( "Main[2-1] : ia[0] = %d\n", ia[0] ); funcArray ( ia ); /* 配列名を指定 */ printf ( "Main[2-2] : ia[0] = %d\n", ia[0] ); /* 影響がある */ /* Test 3 : 配列要素 */ printf ( "<Test 3>\n" ); printf ( "Main[3-1] : ia[0] = %d\n", ia[0] ); funcSimple ( ia[0] ); /* 配列要素を指定 */ printf ( "Main[3-2] : ia[0] = %d\n", ia[0] ); /* 影響はない */ /* Test 4 : 幻のテスト */ /* printf ( "<Test 4>\n" ); */ /* printf ( "Main[4-1] : is = %d\n", is ); */ /* funcArray ( is ); */ /* ココでエラーになる !! */ /* printf ( "Main[4-2] : is = %d\n", is ); */ /* Test 5 : & を付けると .. ? */ printf ( "<Test 5>\n" ); printf ( "Main[5-1] : is = %d\n", is ); funcArray ( &is ); /* 何だコリャ ???? */ printf ( "Main[5-2] : is = %d\n", is ); /* 影響がある !? */ /* scanf と同じ効果 ??? */ /* 謎は深まるばかりだが... */ return 0; }
#include <stdio.h> int main(int argc, char *argv[] ) { int i; i = 10; printf ( "i = %d\n", i ); scanf ( "%d", &i ); printf ( "i = %d\n", i ); return 0; }
/* * オセロ盤プログラム (version 4 : 2014/10/24) * v3 と同じ動きをするプログラム (機能は変更しない) * プログラムの整理をする ( refactring:リファクタリング ) * 機能単位をみつけ、それを関数の形で、抜き出す * 関数を作るので、その影響も補正する * 機能 * 初期化の部分 * 表示の部分 */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* \yoko 0 1 2 3 4 5 6 7 tate 0 -----> 1 | 2 v 3 4 5 6 7 */ printf ( "┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "┃" ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( "┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( "┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ init_board ( board ); /* 引数に配列名しか指定しない */ /* ゲームボードの初期化 : 最初の状態にする */ /* ゲームボードの内容が書き変わる */ /* board という変数(?)の内容が書き変わる ?? */ /* No !! そもそも board は「配列」であって「変数」ではない */ /* 内容が変更されたのも board 自身ではなく、 board の要素 board[][] の内容 */ print_board ( board ); /* 引数に配列名しか指定しない */ return 0; }
/* * オセロ盤プログラム (version 5 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 0 -----> 1 | 2 v 3 4 5 6 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ /* ここで入力をする */ /* とりあえず、具体的な A2 に黒が指定されたと思う */ /*2 A*/ /*t y*/ /* board[1][0] = '*'; */ /* A2 に黒 */ put_board_black ( board, 'A', '2' ); /* その結果が反映されているかどうかを確認する */ print_board ( board ); return 0; }
/* * オセロ盤プログラム (version 6 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 0 -----> 1 | 2 v 3 4 5 6 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 */ char tate; /* 縦の記号 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ /* ここで入力をする */ /* キーボードから 「A2<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ put_board_black ( board, yoko, tate ); /* その結果が反映されているかどうかを確認する */ print_board ( board ); return 0; }
/* * オセロ盤プログラム (version 7 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 0 -----> 1 | 2 v 3 4 5 6 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 */ char tate; /* 縦の記号 */ char color; /* 色の記号 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ put_board ( board, yoko, tate, color ); /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * オセロ盤プログラム (version 8 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 0 -----> 1 | 2 v 3 4 5 6 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 */ char tate; /* 縦の記号 */ char color; /* 色の記号 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ /* そこにコマがおけるかどうか (右方向しか考えない) */ /* 新規 v *ooo OK o NG * NG * NG o NG NG まず、自分の置く場所は空である必要がある 次に自分の左は相手のコマである必要がある 更に次の左以降は、相手のコマであるあいだは次ぎを見る そうでなければ、自分のコマなら OK それいがいは NG */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* 置く場所が空白なので、おけそう */ int yy; yy = yoko - 1; /* 左を見る */ if ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 左が相手コマなので、挟めそう..*/ yy = yy - 1; while ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 自分のコマがくるまで眺める */ yy = yy -1; /* 盤端の処理をしていない */ } if ( get_board ( board, yy, tate ) == color ) { /* 自分のコマを発見 -> 挟めた */ int yyy; /* はさんだコマをひっくりかえす(自分の色にする) */ for ( yyy = yy + 1; yyy < yoko; yyy++ ) { put_board ( board, yyy, tate, color ); } /* 自分のコマを置く */ put_board ( board, yoko, tate, color ); } } } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }