Download : sample-001.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-001 100 番地のセルに記録されている数値は 1 です。 101 番地のセルに記録されている数値は 10 です。 C:\usr\c>
Download : sample-002.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-002 100 番地のセルに 1 を記録。 一度目 : 100 番地のセルに記録されている数値は 1 です。 二度目 : 100 番地のセルに記録されている数値は 1 です。 三度目 : 100 番地のセルに記録されている数値は 1 です。 -------------------------------------- 100 番地のセルに 99 を記録。 変更後 : 100 番地のセルに記録されている数値は 99 です。 100 番地のセルに 21 を記録。 100 番地のセルに 22 を記録。 100 番地のセルに 23 を記録。 現在値 : 100 番地のセルに記録されている数値は 23 です。 C:\usr\c>
Download : sample-003.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-003 100 番地のセルに 1 を記録。 101 番地のセルに 2 を記録。 100 番地のセルに記録されている数値は 1 です。 101 番地のセルに記録されている数値は 2 です。 100 番地のセルに 99 を記録。 100 番地のセルに記録されている数値は 99 です。 101 番地のセルに記録されている数値は 2 です。 -------------------------------------- 101 番地のセルに 88 を記録。 100 番地のセルに記録されている数値は 99 です。 101 番地のセルに記録されている数値は 88 です。 C:\usr\c>
Download : sample-004.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-004 100 番地のセルに 0 を記録。 100 番地のセルに記録されている数値は 0 です。 100 番地のセルに 100 を記録。 100 番地のセルに記録されている数値は 100 です。 100 番地のセルに 255 を記録。 100 番地のセルに記録されている数値は 255 です。 -------------------------------------- 100 番地のセルに 300 を記録。 100 番地のセルに記録されている数値は 44 です。 C:\usr\c>
Download : sample-005.c ( SJIS 版 )
/*
* 2014/11/28 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
C:\usr\c>sample-005< sample-005.in 変数 cvar のアドレスは 16 進数表現で bfb6cf3e です。 変数 dvar のアドレスは 16 進数表現で bfb6cf3f です。 変数 cvar に記録されている文字は c です。 変数 dvar に記録されている文字は D です。 cvar は X です。 dvar は y です。 C:\usr\c>
Download : sample-006.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-006 文字列 "abc" のアドレスは 16 進数表現で 8048d1c です。 文字列 "abc" の先頭の文字は a です。 文字列 "abc" の先頭の次の文字は b です。 文字列 "abc" の先頭の次の次の文字は c です。 C:\usr\c>
Download : sample-007.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-007 変数 cvar のアドレスは 16 進数表現で bfc007cd です。 変数 dvar のアドレスは 16 進数表現で bfc007ce です。 変数 evar のアドレスは 16 進数表現で bfc007cf です。 cvar の所から記録されている文字列は (cD) です。 cvar に記録されている文字は c です。 dvar に記録されている文字は x です。 C:\usr\c>
Download : sample-008.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-008 変数 carray[0] のアドレスは 16 進数表現で bff09dcd です。 変数 carray[1] のアドレスは 16 進数表現で bff09dce です。 変数 carray[2] のアドレスは 16 進数表現で bff09dcf です。 carray[0] の所から記録されている文字列は (cD) です。 carray[0] に記録されている文字は c です。 carray[1] に記録されている文字は x です。 C:\usr\c>
Download : sample-009.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-009 carray[0] の所から記録されている文字列は (cD) です。 carray が表現している文字列は (cD) です。 carray が表現している文字列は (cU) です。 carray が表現している文字列は (pU) です。 C:\usr\c>
Download : sample-010.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-010 carray[0] は A です。 carray[1] は B です。 C:\usr\c>
Download : sample-011.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-011 carray[0] は A です。 carray[1] は B です。 C:\usr\c>
Download : sample-012.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-012 oxx xoo oxx C:\usr\c>
Download : sample-013.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-013 oxx xoo oxx C:\usr\c>
Download : sample-014.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-014 oxx xoo oxx C:\usr\c>
Download : sample-015.c ( SJIS 版 )
/*
* 2014/11/28 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;
}
/*
*
*/
C:\usr\c>sample-015 sizeof ( board[0][0] ) = 1 sizeof ( board[0] ) = 3 board[0]=bf9725af (0,0)=bf9725af (0,1)=bf9725b0 (0,2)=bf9725b1 board[1]=bf9725b2 (1,0)=bf9725b2 (1,1)=bf9725b3 (1,2)=bf9725b4 board[2]=bf9725b5 (2,0)=bf9725b5 (2,1)=bf9725b6 (2,2)=bf9725b7 C:\usr\c>
Download : sample-016.c ( SJIS 版 )
/*
* 2014/11/28 sample-016.c
*/
#include <stdio.h>
/*
* 三次の行列
*
* A 列
* 0 1 2
* +-----+-----+-----+
* 0 | a00 | a01 | a02 |
* +-----+-----+-----+
* 行 1 | a10 | a11 | a12 |
* +-----+-----+-----+
* 2 | a20 | a21 | a22 |
* +-----+-----+-----+
*
*/
#define DIM 3 /* 行列の次元 */
/*
* void print_array ( int array[DIM][DIM] )
* array を出力する
*/
void print_array ( int array[DIM][DIM] ) {
int row; /* 行 */
int col; /* 列 */
for ( row = 0; row < DIM; row++ ) {
printf ( "%c%c ", " | "[row], "/ \\"[row] );
for ( col = 0; col < DIM; col++ ) {
printf ( "%d ", array[row][col] );
}
printf ( "%c%c\n", "\\ /"[row], " | "[row] );
}
}
/*
* void add_array ( int c[DIM][DIM], int a[DIM][DIM], int b[DIM][DIM] )
* c = a + b
*/
void add_array ( int c[DIM][DIM], int a[DIM][DIM], int b[DIM][DIM] ) {
int row; /* 行 */
int col; /* 列 */
for ( row = 0; row < DIM; row++ ) {
for ( col = 0; col < DIM; col++ ) {
c[row][col] = a[row][col] + b[row][col];
}
}
}
int main ( void ) {
/*
*
*/
int a[DIM][DIM] = {
{1, 2, 3},
{2, 3, 4},
{3, 4, 5}
}; /* 配列の初期化 */
int b[DIM][DIM] = {
{1, 1, 1},
{3, 2, 1},
{4, 2, 0}
};
int c[DIM][DIM]; /* a + b の結果を入れる行列 */
/*
*
*/
printf ( "行列 a\n" );
print_array ( a );
printf ( "と、\n" );
printf ( "行列 b\n" );
print_array ( b );
printf ( "の和は\n" );
add_array ( c, a, b ); /* c = a + b */
print_array ( c );
printf ( "になります。\n" );
/*
*
*/
return 0;
}
/*
*
*/
C:\usr\c>sample-016 行列 a / 1 2 3 \ | 2 3 4 | \ 3 4 5 / と、 行列 b / 1 1 1 \ | 3 2 1 | \ 4 2 0 / の和は / 2 3 4 \ | 5 5 5 | \ 7 6 5 / になります。 C:\usr\c>
Download : sample-017-01.c ( SJIS 版 )
/*
* 2014/11/28 sample-017-01.c
*/
#include <stdio.h>
/*
*
*/
typedef struct {
unsigned char intAry[ sizeof ( int ) ];
} Int;
void print_int_as_char_list ( Int ia ) {
int i;
for ( i = 0; i < sizeof ( int ); i++ ) {
printf ( "%d ", ia.intAry[i] );
}
printf ( "\n" );
}
Download : sample-017.c ( SJIS 版 )
/*
* 2014/11/28 sample-017.c
*/
#include <stdio.h>
/*
* 整数とメモリモデル
*
* +---+---+---+---+ +---+
* int | | == char | |
* +---+---+---+---+ +---+
* | |
* +---+
* | |
* +---+
* | |
* +---+
*
*
*/
int make_int ( int b1, int b2, int b3, int b4 ) {
return b1 + 256 * ( b2 + 256 * ( b3 + 256 * b4 ) );
}
int main ( void ) {
/*
*
*/
int i;
printf ( "sizeof( int ) = %d\n", sizeof ( int ) );
i = make_int ( 1, 0, 0, 0 );
printf ( "i = make_int ( 1, 0, 0, 0 ) = %d\n", i );
print_int_as_char_list ( i );
i = make_int ( 2, 3, 0, 0 );
printf ( "i = make_int ( 2, 3, 0, 0 ) = %d\n", i );
print_int_as_char_list ( i );
i = make_int ( 3, 4, 5, 0 );
printf ( "i = make_int ( 3, 4, 5, 0 ) = %d\n", i );
print_int_as_char_list ( i );
i = make_int ( 4, 5, 6, 7 );
printf ( "i = make_int ( 4, 5, 6, 7 ) = %d\n", i );
print_int_as_char_list ( i );
/*
*
*/
printf ( "----\n" );
/*
*
*/
i = 255;
printf ( "i = %d\n", i );
print_int_as_char_list ( i );
i = 256;
printf ( "i = %d\n", i );
print_int_as_char_list ( i );
/*
*
*/
return 0;
}
/*
*
*/
C:\usr\c>sample-017 sizeof( int ) = 4 i = make_int ( 1, 0, 0, 0 ) = 1 1 0 0 0 i = make_int ( 2, 3, 0, 0 ) = 770 2 3 0 0 i = make_int ( 3, 4, 5, 0 ) = 328707 3 4 5 0 i = make_int ( 4, 5, 6, 7 ) = 117835012 4 5 6 7 ---- i = 255 255 0 0 0 i = 256 0 1 0 0 C:\usr\c>
Download : sample-018.c ( SJIS 版 )
/*
* 2014/11/28 sample-018.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;
}
/*
*
*/
C:\usr\c>sample-018 fact(5)=120 C:\usr\c>
Download : sample-019.c ( SJIS 版 )
/*
* 2014/11/28 sample-019.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;
}
/*
*
*/
C:\usr\c>sample-019 (main) n = 5, &n = bff60fe8 (fact:前) n = 5, &n = bff60fd0 (fact:前) n = 4, &n = bff60fa0 (fact:前) n = 3, &n = bff60f70 (fact:前) n = 2, &n = bff60f40 (fact:前) n = 1, &n = bff60f10 (fact:前) n = 0, &n = bff60ee0 (fact:後) n = 0, &n = bff60ee0 (fact:後) n = 1, &n = bff60f10 (fact:後) n = 2, &n = bff60f40 (fact:後) n = 3, &n = bff60f70 (fact:後) n = 4, &n = bff60fa0 (fact:後) n = 5, &n = bff60fd0 fact(5)=120 C:\usr\c>
Download : sample-020.c ( SJIS 版 )
/*
* 2014/11/28 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 );
}
int main ( void ) {
/*
*
*/
subfunc ( 2, 4 );
/*
*
*/
return 0;
}
/*
*
*/
C:\usr\c>sample-020 a = 2, &a = bfa4c3e0 b = 4, &b = bfa4c3e4 C:\usr\c>
Download : sample-021.c ( SJIS 版 )
/*
* 2014/11/28 sample-021.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;
}
/*
*
*/
C:\usr\c>sample-021 a = 2, &a = bfa5edd0 b = 4, &b = bfa5edd4 *(&b-1) = 2, &b-1 = bfa5edd0 a = 10 C:\usr\c>
Download : sample-022.c ( SJIS 版 )
/*
* 2014/11/28 sample-022.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;
}
/*
*
*/
C:\usr\c>sample-022 a = 1, &a = bfec3260 *(&a+1) = 2, &a + 1 = bfec3264 *(&a+2) = 3, &a + 2 = bfec3268 C:\usr\c>
Download : sample-023.c ( SJIS 版 )
/*
* 2014/11/28 sample-023.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;
}
/*
*
*/
C:\usr\c>sample-023 subfunc ( 5,1,2,3,4,5 ); arg[0]=1 arg[1]=2 arg[2]=3 arg[3]=4 arg[4]=5 subfunc ( 3,9,8,7,6 ); arg[0]=9 arg[1]=8 arg[2]=7 C:\usr\c>
Download : sample-024.c ( SJIS 版 )
/*
* 2014/11/28 sample-024.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;
}
/*
*
*/
C:\usr\c>sample-024 i = , j = 1 st = , 2nd = , 3rd = C:\usr\c>
Download : sample-025.c ( SJIS 版 )
/*
* 2014/11/28 sample-025.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;
}
/*
*
*/
C:\usr\c>sample-025 99 i=10, j=20, k=90 i=10, j=20, k=90 C:\usr\c>
Download : sample-026.c ( SJIS 版 )
/*
* 2014/11/28 sample-026.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;
}
/*
*
*/
C:\usr\c>sample-026 abc i=10 i=10, j=20 a=12.340000 i=123, a=12.340000, c=a, s=abc C:\usr\c>
Download : sample-027.c ( SJIS 版 )
/*
* 2014/11/28 sample-027.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;
}
/*
*
*/
C:\usr\c>sample-027 a=-12.340000 a= -12.3400000000 C:\usr\c>
Download : sample-028.c ( SJIS 版 )
/*
* 2014/11/28 sample-028.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
C:\usr\c>sample-028< sample-028.in i の値を入力してください 10 入力された i の値は 10 でした C:\usr\c>
/*
* 2014/11/28 sample-001.c
*/
#include <stdio.h>
#include "s_memory.h" /* memory モデルを理解するための関数定義 */
/*
* メモリの性質
* 0 〜 255 までの数値 ( 1 byte = 2^8 通り ) を記録できるセルの集まり
* 個々のセルには、 0 〜 FF...FF の番地(address)がふられていて、区別される
* 個々のセル(address を指定して..)に対して
* 値の設定 (set_memory_value_at)
* 一つのセルは値を一度に一つしか記憶できない
* set によって、新しい値を記録するように指示できるが、
* その場合は、前の記録を失う
* 値の取出し (get_memory_value_at)
* セルが記録している値を取り出す
* セルには、最後に set した値しか記録されていない
* 最後に set した値が取り出される
* セルからは何回でも値を取り出す事ができる
* ができる。
*/
int main ( void ) {
/*
* メモリの操作 ( 情報の記録 : set_memory_value_at )
*/
/*
メモリ
+-----------+
0 | ?? |
+-----------+
1 | ?? |
+-----------+
..
+-----------+
100 | ?? |
+-----------+
101 | ?? |
+-----------+
102 | ?? |
+-----------+
..
*/
set_memory_value_at ( 100, 1 ); /* 100 番地のセルに 1 を記録する */
/*
メモリ
+-----------+
0 | ?? |
+-----------+
1 | ?? |
+-----------+
..
+-----------+
100 | 1 | <= set_memory_value_at ( 100, 1 ); の結果
+-----------+
101 | ?? |
+-----------+
102 | ?? |
+-----------+
..
*/
set_memory_value_at ( 101, 10 ); /* 101 番地のセルに 10 を記録する */
/*
メモリ
+-----------+
0 | ?? |
+-----------+
1 | ?? |
+-----------+
..
+-----------+
100 | 1 |
+-----------+
101 | 100 | <= set_memory_value_at ( 101, 10 ); の結果
+-----------+
102 | ?? |
+-----------+
..
*/
/*
* メモリの操作 ( 情報の参照 : get_memory_value_at )
*/
printf ( "100 番地のセルに記録されている数値は %d です。\n",
get_memory_value_at ( 100 )
);
/*
+-----------+
100 | 1 | -> この値が get_memory_value_at ( 100 ) の結果
+-----------+
*/
printf ( "101 番地のセルに記録されている数値は %d です。\n",
get_memory_value_at ( 101 )
);
/*
+-----------+
101 | 100 | -> この値が get_memory_value_at ( 101 ) の結果
+-----------+
*/
/*
*
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28 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 ) {
/*
* メモリの参照 : 一度記録した情報は何度でも参照できる
*/
/*
メモリ
+-----------+
0 | ?? |
+-----------+
1 | ?? |
+-----------+
..
+-----------+
100 | ?? |
+-----------+
101 | ?? |
+-----------+
102 | ?? |
+-----------+
..
*/
print_memory_set ( 100, 1 ); /* 100 番地のセルに 1 を記録する */
/*
メモリ
+-----------+
0 | ?? |
+-----------+
1 | ?? |
+-----------+
..
+-----------+
100 | 1 | <- print_memory_set ( 100, 1 ) の結果
+-----------+
101 | ?? |
+-----------+
102 | ?? |
+-----------+
..
*/
printf ( "一度目 : " );
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 (一度目) */
/*
+-----------+
100 | 1 | <- print_memory_value ( 100 ); で取り出す値
+-----------+
*/
/*
+-----------+
100 | 1 | <- print_memory_value ( 100 ); で取り出す値
+-----------+
*/
printf ( "二度目 : " );
print_memory_value ( 100 ); /* 二度目 */
/*
+-----------+
100 | 1 | <- print_memory_value ( 100 ); で取り出す値
+-----------+
*/
printf ( "三度目 : " );
print_memory_value ( 100 ); /* 三度目 */
/*
+-----------+
100 | 1 | <- print_memory_value ( 100 ); で取り出す値
+-----------+
*/
/*
* 参照は何度行っても、同じ情報が得られる
*/
/*
set は、変更(副作用)を伴うが、get は変更(副作用)がおきない
*/
print_line();
/*
* 記憶の破壊 : 新しい情報を記録すると以前の記録は失われる
*/
print_memory_set ( 100, 99 ); /* 100 番地のセルに 99 を記録する */
/*
+-----------+
100 | 99 | <- print_memory_set ( 100, 99 );
+-----------+
セルの値は、新しく指定された 99 になる
以前、記録されていた 1 は失われる(永遠に..)
*/
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 を記録する */
/*
何度も set すると、最後の set だけが有効
途中で設定した値は、取り出されず、そのまま、失われる
-> なかった同じ
*/
printf ( "現在値 : " );
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
/*
* 記録されている情報は最後に記録された物だけ
*/
/*
*
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28 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 ) {
/*
* メモリセルの独立性 : 番地の異るセルは独立に振る舞う
*/
/*
+-----------+
100 | ?? |
+-----------+
101 | ?? |
+-----------+
*/
print_memory_set ( 100, 1 ); /* 100 番地のセルに 1 を記録する */
/*
+-----------+
100 | 1 | <= print_memory_set ( 100, 1 );
+-----------+
101 | ?? |
+-----------+
*/
print_memory_set ( 101, 2 ); /* 101 番地のセルに 2 を記録する */
/*
+-----------+
100 | 1 |
+-----------+
101 | 2 | <= print_memory_set ( 101, 2 );
+-----------+
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
print_memory_value ( 101 ); /* 101 番地のセルの内容を出力 */
/*
+-----------+
100 | 1 | -> print_memory_value ( 100 );
+-----------+
101 | 2 | -> print_memory_value ( 101 );
+-----------+
*/
/*
* 番地が異れば、記録されている情報も異る
*/
/*
* 記憶の独立性
*/
print_memory_set ( 100, 99 ); /* 100 番地のセルに 99 を記録する */
/*
+-----------+
100 | 99 | <= print_memory_set ( 100, 99 );
+-----------+
101 | 2 |
+-----------+
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
print_memory_value ( 101 ); /* 101 番地のセルの内容を出力 */
/*
+-----------+
100 | 99 | -> print_memory_value ( 100 );
+-----------+
101 | 2 | -> print_memory_value ( 101 );
+-----------+
*/
print_line();
/*
* 100 番地の情報を書き換えても、101 番地の情報は影響しない
*/
print_memory_set ( 101, 88 ); /* 101 番地のセルに 88 を記録する */
/*
+-----------+
100 | 99 |
+-----------+
101 | 88 | <= print_memory_set ( 101, 88 );
+-----------+
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
print_memory_value ( 101 ); /* 101 番地のセルの内容を出力 */
/*
+-----------+
100 | 99 | -> print_memory_value ( 100 );
+-----------+
101 | 88 | -> print_memory_value ( 101 );
+-----------+
*/
/*
* 逆も真なり
*/
/*
*
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28 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 ) {
/*
* メモリセルの容量
*/
/*
セルには、0 から 255 迄しか記録できない
*/
/*
+-----------+
100 | ?? |
+-----------+
*/
print_memory_set ( 100, 0 ); /* 100 番地のセルに 0 を記録する */
/*
+-----------+
100 | 0 | <= print_memory_set ( 100, 0 );
+-----------+
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
print_memory_set ( 100, 100 ); /* 100 番地のセルに 100 を記録する */
/*
+-----------+
100 | 100 | <= print_memory_set ( 100, 100 );
+-----------+
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
print_memory_set ( 100, 255 ); /* 100 番地のセルに 255 を記録する */
/*
+-----------+
100 | 255 | <= print_memory_set ( 100, 255 );
+-----------+
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
/*
* 0 〜 255 ならば、記録できる
*/
print_line();
/*
* メモリセルの容量オーバー
*/
print_memory_set ( 100, 300 ); /* 100 番地のセルに 300 を記録しようとした */
/*
+-----------+
100 | 300??? | <= print_memory_set ( 100, 300 );
+-----------+
+-----------+
100 | 44 | <= print_memory_set ( 100, 300 );
+-----------+
44 は 300 を 256 で割った余り
実は、一般に n を set すると n を 256 で割った余りが記録される
n が 0 〜 255 だと、n を 256 で割った余りも
0 〜 255 になり、n 自身になる
*/
print_memory_value ( 100 ); /* 100 番地のセルの内容を出力 */
/*
* 300 は記憶されていない !!
* 実は 300 を 256 で割った余り ( 44 ) が記録されている
* 256 を越える(オーバーする)情報は捨てられる !!
*/
/*
*
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28 sample-005.c
*/
#include <stdio.h>
#include "s_variable.h" /* memory モデルを理解するための関数定義 */
/*
*
*/
int main ( void ) {
/*
* C 言語の変数のメモリモデルによる理解
*/
char cvar; /* char 型の変数 cvar の宣言 */
char dvar; /* char 型の変数 dvar の宣言 */
/*
cvar : 変数
これが、セル(の組み合わせ)と同じならば、
セルと同じようにアドレスがある.. (と考えることができる)
-> 実際にある
*/
/*
* 変数はアドレスをもっている
* 変数のアドレスを取り出す関数
* get_variable_address( cvar )
*
* コメント
* printf の書式文字列の中の %x は、int 型の値を 16 進数で出力する
*/
printf ( "変数 cvar のアドレスは 16 進数表現で %x です。\n",
get_variable_address( cvar )
);
printf ( "変数 dvar のアドレスは 16 進数表現で %x です。\n",
get_variable_address( dvar )
);
/*
* 変数名が異れば、番地も異っている
*/
/*
* 変数をアドレスを利用して参照
* もし、変数がセルと同じなら、番地(address)をつかって値が取り出せる
* get_variable_value_at
*/
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 ) )
);
/*
* 変数の値をアドレスを利用して変更
* もし、変数がセルと同じなら、番地(address)をつかって値が変更できる
* set_variable_value_at
*/
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;
}
/*
*
*/
/*
* 2014/11/28 sample-006.c
*/
#include <stdio.h>
#include "s_variable.h" /* memory モデルを理解するための関数定義 */
/*
*
*/
int main ( void ) {
/*
* C 言語の文字列のメモリモデルによる理解
*/
/*
* 文字列はアドレスをもっている
*/
/*
"abc" <-> +-----------+
8048560 | 'a' |
+-----------+
8048561 | 'b' |
+-----------+
8048562 | 'c' |
+-----------+
| '\0' | = 0 (End of String = EOS)
+-----------+
*/
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 )
);
/*
* 文字列がセルの並びならば、値の変更 (set) もできる筈だが..
* -> 許してくれる場合もある
* (が、最近は、セキュリティの観点から許さない事が多い)
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28
*
* 文字列に対して set は可能か ?
* 基本は許さない事が多いが、試してみよう
* -> linux では、禁止されていた...
*/
#include <stdio.h>
#include "s_variable.h" /* memory モデルを理解するための関数定義 */
/*
*
*/
void sub ( char *abc ) {
printf ( "sub : abc = %s\n", abc );
/* linux では、次の、文字列内の内容を変更する操作は禁止されている */
set_variable_value_at ( get_string_address( "abc" ), 'A' );
printf ( "sub : abc = %s\n", abc );
}
/*
*
*/
int main ( void ) {
printf ( "main : abc = %s\n", "abc" );
sub ( "abc" );
printf ( "main : abc = %s\n", "abc" );
return 0;
}
/*
*
*/
/*
* 2014/11/28 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 bffda59d | ?? |
+-----------+
dvar bffda59e | ?? |
+-----------+
evar bffda59f | ?? |
+-----------+
*/
cvar = 'c'; /* 変数 cvar に、値 'c' を代入 */
dvar = 'D'; /* 変数 dvar に、値 'D' を代入 */
evar = '\0'; /* 変数 evar に、値 '\0' を代入 */
/*
+-----------+
cvar bffda59d | 'c' | <- "cD" と同じ状況になっている
+-----------+
dvar bffda59e | 'D' |
+-----------+
evar bffda59f | '\0' |
+-----------+
参考 +-----------+
"abc" <-> | 'a' |
+-----------+
| 'b' |
+-----------+
| 'c' |
+-----------+
| '\0' |
+-----------+
*/
printf ( "cvar の所から記録されている文字列は (%s) です。\n",
get_variable_address( cvar ) /* cvar のアドレスを指定 */
);
/*
* アドレス経由で、変数の内容を変更
*/
set_variable_value_at ( get_variable_address( cvar ) + 1, 'x' );
/* 変数 cvar のアドレスの次のアドレスは dvar のアドレスなので.. */
/* cvar を利用して、dvar の値を変更している */
printf ( "cvar に記録されている文字は %c です。\n",
cvar
);
/* 結果的に、dvar の内容が書き変わる */
printf ( "dvar に記録されている文字は %c です。\n",
dvar
);
/*
*
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28 sample-008.c
*/
#include <stdio.h>
#include "s_variable.h" /* memory モデルを理解するための関数定義 */
/*
*
*/
int main ( void ) {
/*
* C 言語の変数のメモリモデルによる理解
*/
/*
* 先程の例では、
* char cvar;
* char dvar;
* char evar;
* とすると、これらが並んだセルに対応つけられる
* という「偶然」を利用した。
* 今回は、配列する事によって、「必然」にした
* <結論>
* 配列と単純変数の並びと違いは、連続したセルに対応するか否かの違い
*/
char carray[3]; /* char 型の一次元配列 carray の宣言 (サイズは 3) */
/*
これは実質、三つの変数の宣言と同じようなもの
char carray0;
char carray1;
char carray2;
*/
/*
意味的には
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;
}
/*
*
*/
/*
課題 1
*/
/*
* DATE-DIR-QQQQ.c
* メモリ操作での和
* s_memory.h を利用し、
* 100 番地の内容と 101 番地の内容の和を 102 番地に入れるプログラムを作成しなさい
*/
/*
*
*/
#include <stdio.h>
#include "s_memory.h"
/*
* print_memory_value
* 指定された address の記憶セルの内容を画面に出力する
*/
void print_memory_value ( int address ) {
printf ( "%d 番地のセルに記録されている数値は %d です。\n",
address,
get_memory_value_at ( address ) /* 値の取出し */
);
}
/*
*
*/
int main ( int argc, char *argv[] ) {
/* 値の設定 */
/*
* メモリセルの容量
*/
/*
+-----------+
100 | ?? |
+-----------+
101 | ?? |
+-----------+
102 | ?? |
+-----------+
*/
set_memory_value_at ( 100, 12 ); /* 100 番地のセルに 12 を記録する */
set_memory_value_at ( 101, 78 ); /* 100 番地のセルに 78 を記録する */
/*
+-----------+
100 | 12 |
+-----------+
101 | 78 |
+-----------+
102 | ?? |
+-----------+
*/
/*
* 100 番地の値と 101 番地の値の和を 102 番地にいれる
*/
/*
1) 安易だが、間違った答え
set_memory_value_at ( 102, 100 );
102 番地の内容を書き換える以上 set は不可欠
問題は 100 の部分をどうするか
2) おしい、が、一応、ギリギリ駄目な答え
set_memory_value_at ( 102, 12 + 78 );
3) これを考えた人は、かしこいが、まあ、ギリギリセーフ
int a = get_memory_value_at ( 100 );
int b = get_memory_value_at ( 101 );
int c = a + b; ここで足し算
set_memory_value_at ( 102, c );
4) 期待されている答えです..
set_memory_value_at ( 102, get_memory_value_at ( 100 ) + ... )
*/
/*
+-----------+
100 | 12 |
+-----------+
101 | 78 |
+-----------+
102 | 100 | <= 結果が、こうなっていれば OK
+-----------+
*/
/*
* 結果の出力
*/
print_memory_value ( 102 ); /* 102 番地のセルの内容を出力 */
/*
100 が表示さればよい
*/
return 0;
}
/*
*
*/
/*
* DATE-DIR-QQQQ.c
* アドレスを利用した間接参照
* 代入文を利用せず、s_variable.h を利用して、変数 cvar の値を 1 だけふやせ
*/
#include <stdio.h>
#include "s_variable.h" /* memory モデルを理解するための関数定義 */
/*
*
*/
int main ( void ) {
/*
* C 言語の変数のメモリモデルによる理解
*/
char cvar = 'p'; /* char 型の変数 cvar の宣言 */
printf ( "cvar は %c です。\n", cvar );
/*
1) 禁止事項
cvar = cvar + 1; <= 代入文を使っているので駄目
=> get_variable_value_ats
get_variable_address を使え
2) ×ではない答え
set_variable_value_at ( get_variable_address ( cvar ), cvar + 1 );
3) 期待されている答えは
set_variable_value_at ( get_variable_address ( cvar ), \
get_variable_value_at ( ... ) + 1 );
*/
/*
** この部分を完成させなさい
*/
printf ( "cvar は %c になりました。\n", cvar );
/*
*
*/
return 0;
}
/*
*
*/
/*
* 2014/11/28 sample-010.c
*/
#include <stdio.h>
/*
*
*/
int main ( void ) {
/*
* 文字配列の初期化
*/
char carray[3] = "AB"; /* 配列の初期化 */
/*
char carray[3] = { 'A', 'B', '\0' };
配列要素の初期値を、並べて、設定することができる。
但し、文字配列だけは、「文字列」で、でも初期化できる。
※ : 配列サイズより小さい個数の初期値があたえられた場合は、足りない残りの初期値は 0 になる。
逆に配列サイズより大きい個数数の初期値があたえられた場合は、余分な初期値は、無視される。
※※
char carray[] = "abc";
のように初期値を指定すると、配列のサイズは、省略できる
実際のサイズは、初期化の個数できまる
# 今回の場合は、配列サイズは 4 になる
# "abc" -> { 'a', 'b', 'c', '\0' }
# の四つの初期値だから
*/
/*
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;
}
/*
*
*/
/*
* 2014/11/28 sample-011.c
*/
#include <stdio.h>
/*
*
*/
int main ( void ) {
/*
* アドレス演算子「&」と間接演算子「*」
*/
char carray[3] = "AB"; /* { 'A', 'B', '\0' } */
/*
* 添字による参照
*/
printf ( "carry[0] = %c\n", carry[0] ); /* 'A' */
printf ( "carry[1] = %c\n", carry[1] ); /* 'B' */
/*
* 間接演算子('*')による参照
*/
/* これまで、文字列の前に「'*'」をつけると、「先頭の文字をとってくる」*/
/*
1. 配列名は、実は、最初の要素のアドレス(ポインター)値をもっている
2. 「'*'」は、そのアドレス(ポインター)から、
そのアドレスの指すセルの値を取り出す
carry <-> get_string_address ( carry )
実は、get_string_address はほんとど何もしてない
*carry <-> get_variable_value_at ( carry )
実は、get_variable_value_at は '*' と同じ事をしている
*/
printf ( "*carry = %c\n", *carry ); /* 'A' */
/*
printf ( "*carry = %c\n", get_variable_value_at ( get_string_address ( \
carry ) ) );
printf ( "*carry = %c\n", get_variable_value_at ( carry ) );
printf ( "*carry = %c\n", *carry );
*/
printf ( "*(carry+1) = %c\n", *(carry+1) );
/*
printf ( "*carry = %c\n", get_variable_value_at ( get_string_address ( \
carry ) + 1 ) );
printf ( "*carry = %c\n", get_variable_value_at ( carry + 1 ) );
printf ( "*carry = %c\n", * ( carry + 1 ) );
*/
/*
配列名で、配列の最初の要素のアドレスがえられる
'*' (間接参照演算子)で、アドレスから、最初の要素を操作できる
メモリモデルを利用して
じゃあ、普通の変数 (単純変数) のアドレスは ?
-> '&' が、実は、変数のアドレス(ポインター)値を取り出す機能
*/
/*
* address の比較
*/
s_print_string ( "&carry[0] = %x\n", &carry[0] );
/* '&' は carray[0] のアドレス(ポインター)値を取り出す */
s_print_string ( "carry = %x\n", carry );
/* carray (配列名) は、最初の要素 ( carry[0] ) のアドレス(ポインター)値 */
/* つまり、上記の二つの表現は、同じものを表わしている */
/*
* 「&」と「*」は逆演算子
*/
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;
}
/*
*
*/
/*
* 2014/11/28 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
* +-----+-----+-----+ 1 対 1 +-----+
* 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
* +-----+
*
* 二次元の表現も、1 対 1 の対応を考えて
* 添字(アドレス)を計算してあげれば良い
*/
#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;
}
/*
*
*/
/*
* 2014/11/28 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[0*BOARD_SIZE+0] = 'o'; */
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;
}
/*
*
*/
/*
* 2014/11/28 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)|
* +-----+-----+-----+
*
* 「C 言語が、予め指定」している対応関係を利用する事に决めれば
* 「C 言語(のコンパイラ)」が、自動的計算してくれる
* 二元のデータと、一次元の対応は、自分で决めてよいが、
* 自分できめたら、面倒をみる必要がある
* C 言語にお任せでよければ C 言語が面倒をみてくれる
*
*/
#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'; */
/* board[index2d(0,0)] = 'o'; */
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;
}
/*
*
*/
プログラム文字列の中で
SJIS にすると、2 byte 目に「\(エンマーク)」がくる場合がある
-> 実行すると文字化けする
例
「表」
変数の世界 ( x が変数名である事に注意 )
x = x + 1
x の値をとってきて
その値に 1 を加えて
x に、その値を代入する
メモリの世界 ( アドレスを使う : &x = 「x のアドレス」 )
get_variable_at ( get_variable_address ( x ) );
その値に 1 を加えて
set_variable_at ( get_variable_address ( x ), get_variable_at ( \
get_variable_address ( x ) ) + 1 );
機械語 ( アセンブラ ) / 低級言語 では、メモリモデルをそのまま使う
<-> C 言語 (など、高級言語) では、変数を利用する
# C 言語は、低級言語 *でも* プログラムできる
Download : 20141205-01.c ( SJIS 版 )
/*
* DATE-DIR-QQQQ.c
* メモリ操作での和
* s_memory.h を利用し、
* 100 番地の内容と 101 番地の内容の和を 102 番地に入れるプログラムを作成しなさい
*/
/*
*
*/
#include <stdio.h>
#include "s_memory.h"
/*
* print_memory_value
* 指定された address の記憶セルの内容を画面に出力する
*/
void print_memory_value ( int address ) {
printf ( "%d 番地のセルに記録されている数値は %d です。\n",
address,
get_memory_value_at ( address ) /* 値の取出し */
);
}
/*
*
*/
int main ( int argc, char *argv[] ) {
/* 値の設定 */
/*
* メモリセルの容量
*/
set_memory_value_at ( 100, 12 ); /* 100 番地のセルに 12 を記録する */
set_memory_value_at ( 101, 78 ); /* 100 番地のセルに 78 を記録する */
/*
* 100 番地の値と 101 番地の値の和を 102 番地にいれる
*/
/*
** この部分を完成させなさい
*/
/*
* 結果の出力
*/
print_memory_value ( 102 ); /* 102 番地のセルの内容を出力 */
return 0;
}
/*
*
*/
C:\usr\c\> 20141205-01-QQQQ 102 番地のセルに記録されている数値は 90 です。 C:\usr\c\>
Download : 20141205-02.c ( SJIS 版 )
/*
* DATE-DIR-QQQQ.c
* アドレスを利用した間接参照
* 代入文を利用せず、s_variable.h を利用して、変数 cvar の値を 1 だけふやせ
*/
#include <stdio.h>
#include "s_variable.h" /* memory モデルを理解するための関数定義 */
/*
*
*/
int main ( void ) {
/*
* C 言語の変数のメモリモデルによる理解
*/
char cvar = 'p'; /* char 型の変数 cvar の宣言 */
printf ( "cvar は %c です。\n", cvar );
/*
** この部分を完成させなさい
*/
printf ( "cvar は %c になりました。\n", cvar );
/*
*
*/
return 0;
}
/*
*
*/
C:\usr\c\> 20141205-02-QQQQ cvar は p です。 cvar は q になりました。 C:\usr\c\>