Download : sample-001.c
/* * 2020/11/13 sample-001.c */ /* * 多次元配列 * * 利用方法 * コンパイル * cc -c sample-001.c * リンク * cc -o sample-001.exe sample-001.c * 実行 * ./sample-001.exe */ #include <stdio.h> /* * main * */ int main( int argc, char *argv[] ) { int a[3][4]; /* 二次元配列の宣言 3 x 4 (= 12) 個の変数を宣言 */ /* int a00, a01, .., a03, a10, .., a13, .., a23; と同様 */ int i; int j; a[0][0] = 0; /* 添字は、二つ必要 ( 二次なので.. ) で、0 から始まる */ a[2][3] = 6; /* 添字の大きさは、配列の大きさ - 1 まで */ /* 0 〜 2 と 0 〜 3 のかけ算表を作ってみる */ for ( i = 0; i < 3; i++ ) { for ( j = 0; j < 4; j++ ) { a[i][j] = i * j; /* a[i][j] 成分の値が i*j になるようにする */ } } printf ( "2 * 1 = %d\n", a[2][1] ); /* 2 と表示される筈 */ if ( a[1][2] == a[2][1] ) { /* 1 * 2 = 2 * 1 か ? */ printf ( "1 * 2 = 2 * 1 が成立\n" ); } else { printf ( "1 * 2 = 2 * 1 が成立しない.. 何か変だ..\n" ); } /* 0 〜 2 と 0 〜 3 のかけ算表を画面に表示 */ printf ( " * |" ); for ( j = 0; j < 4; j++ ) { printf ( "%2d", j ); } printf ( "\n" ); printf ( "---+---------\n" ); for ( i = 0; i < 3; i++ ) { printf ( " %1d |", i ); for ( j = 0; j < 4; j++ ) { printf ( "%2d", a[i][j] ); } printf ( "\n" ); } return 0; }
$ ./sample-001.exe 2 * 1 = 2 1 * 2 = 2 * 1 が成立 * | 0 1 2 3 ---+--------- 0 | 0 0 0 0 1 | 0 1 2 3 2 | 0 2 4 6 $
Download : sample-002.c
/* * 2020/11/13 sample-002.c */ /* * 集合の操作は操作の集合 * * 利用方法 * コンパイル * cc -c sample-002.c * リンク * cc -o sample-002.exe sample-002.c * 実行 * ./sample-002.exe */ #include <stdio.h> /* * main * */ #define ARRAY_SIZE 5 /* 配列のサイズを 5 とする */ int main( int argc, char *argv[] ) { int a[ARRAY_SIZE]; /* ARRAY_SIZE の配列の宣言 */ int i; for ( i = 0; i < ARRAY_SIZE; i++ ) { a[i] = 2 * i; /* 一桁の偶数の表を作る */ /* a = { 0, 2, 4, 6, 8 } */ } /* 偶数を出力 */ for ( i = 0; i < ARRAY_SIZE; i++ ) { printf ( "%d ", a[i] ); } printf ( "\n" ); /* 全ての要素に 1 を加えれば奇数の表になる */ /* { 0, 2, 4, 6, 8 } -> { 1, 3, 5, 7, 9 } */ for ( i = 0; i < ARRAY_SIZE; i++ ) { a[i] = a[i] + 1; } /* 奇数を出力 */ for ( i = 0; i < ARRAY_SIZE; i++ ) { printf ( "%d ", a[i] ); } printf ( "\n" ); return 0; }
$ ./sample-002.exe 0 2 4 6 8 1 3 5 7 9 $
Download : sample-003.c
/* * 2020/11/13 sample-003.c */ /* * 文字配列と文字列 (1) * * 利用方法 * コンパイル * cc -c sample-003.c * リンク * cc -o sample-003.exe sample-003.c * 実行 * ./sample-003.exe */ #include <stdio.h> /* * main * */ #define CSIZE 10 #define EOS '\0' /* End Of String */ int main( int argc, char *argv[] ) { char cary[CSIZE]; cary[0] = 'a'; cary[1] = 'b'; cary[2] = 'c'; cary[3] = EOS; /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'c'|EOS| ? | ? | ? | ? | ? | ? | */ printf ( "普通に文字列 \"abc\" を出力してみる : %s\n", "abc" ); /* 文字列を出力する場合の書式は「%s」を利用する */ printf ( "文字列の代りに文字配列を出力してみる : %s\n", cary ); /* 文字列の代りに文字配列名が使える */ return 0; }
$ ./sample-003.exe 普通に文字列 "abc" を出力してみる : abc 文字列の代りに文字配列を出力してみる : abc $
Download : sample-004.c
/* * 2020/11/13 sample-004.c */ /* * 文字配列と文字列 (2) * * 利用方法 * コンパイル * cc -c sample-004.c * リンク * cc -o sample-004.exe sample-004.c * 実行 * ./sample-004.exe */ #include <stdio.h> /* * main * */ #define CSIZE 10 #define EOS '\0' int main( int argc, char *argv[] ) { char cary[CSIZE] = { 'a', 'b', 'c', 'd', 'e', EOS }; /* 配列も「初期化」可能 (全ての要素を指定する必要はない) */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'c'|'d'|'e'|EOS| ? | ? | ? | ? | */ int i; int l; /* * 文字列と文字配列 */ printf ( "最初の cary = %s\n", cary ); /* * 文字の変更 */ cary[2] = 'A'; /* 文字列の途中の文字を差し替える */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'A'|'d'|'e'|EOS| ? | ? | ? | ? | */ printf ( "文字列の途中の文字を変更すると cary = %s\n", cary ); /* * 文字の尻尾を切断 */ cary[3] = EOS; /* 文字列の後ろを切断 */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'A'|EOS|'e'|EOS| ? | ? | ? | ? | */ printf ( "文字列を途中で切ると cary = %s\n", cary ); /* * 文字を尻尾に追加 */ cary[3] = 'X'; cary[5] = 'Y'; cary[6] = 'Z'; cary[7] = EOS; /* 文字列の最後に EOS を忘れずに !! */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'A'|'X'|'e'|'Y'|'Z'|EOS| ? | ? | */ printf ( "文字列の後ろに文字を追加すると cary = %s\n", cary ); /* * 文字配列の出力 */ printf ( "printf を使わず、文字配列を文字列のように出力すると : " ); for ( i = 0; cary[i] != EOS; i++ ) { putchar ( cary[i] ); } printf ( "と、なります。\n" ); /* 文字列の長さを求める */ for ( l = 0; cary[l] != EOS; l++ ) { /* やる事は何もない (l を増やす事が目的) */ } /* cary の中の文字列の長さは、変数 l に入る */ printf ( "文字列 %d の長さは %d です。\n", cary, l ); /* * 途中の文字を削除 */ for ( i = 3; cary[i] != EOS; i++ ) { cary[i] = cary[i+1]; } /* 文字列の途中(4 文字目)の文字('X')を削除 */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'A'|'X'|'e'|'Y'|'Z'|EOS| ? | ? | | | | / / / / |'a'|'b'|'A'|'e'|'Y'|'Z'|EOS|EOS| ? | ? | */ printf ( "文字列の途中の文字を削除すると cary = %s\n", cary ); return 0; }
$ ./sample-004.exe 最初の cary = abcde 文字列の途中の文字を変更すると cary = abAde 文字列を途中で切ると cary = abA 文字列の後ろに文字を追加すると cary = abAXeYZ printf を使わず、文字配列を文字列のように出力すると : abAXeYZと、なります。 文字列 -2142084352 の長さは 7 です。 文字列の途中の文字を削除すると cary = abAeYZ $
Download : sample-005.c
/* * 2020/11/13 sample-005.c */ /* * 配列の要素の参照 * * 利用方法 * コンパイル * cc -c sample-005.c * リンク * cc -o sample-005.exe sample-005.c * 実行 * ./sample-005.exe */ #include <stdio.h> /* * main * */ #define ARRAY_SIZE 10 int main( int argc, char *argv[] ) { int iary[ARRAY_SIZE]; int i; /* 配列の初期化 */ /* iary[i] = i*i */ for ( i = 0; i < ARRAY_SIZE; i++ ) { iary[i] = i*i; } /* これで、iary は i=0〜9 なら、関数 f(x)=x^2 と同じ振舞いをする */ /* 配列参照 : 普通の「添字参照」の場合 */ for ( i = 0; i < ARRAY_SIZE; i++ ) { printf ( "iary[%d]=%d\n", i, iary[i] ); } /* 配列参照 : 「間接参照("*" の利用)」の場合 *(iary + i) == iary[i] */ for ( i = 0; i < ARRAY_SIZE; i++ ) { printf ( "*(iary + %d)=%d\n", i, *(iary + i) ); } /* 配列参照 : 配列名を使った計算 ( 添字を 1 からスタート ) (iary-1)[i] = *((iary - 1) + i) == *(iary + (i-1)) = iary[i-1] */ for ( i = 1; i <= ARRAY_SIZE; i++ ) { printf ( "(iary-1)[i]=%d, iary[i-1]=%d\n", i, (iary-1)[i], i, iary[i-1] ); } return 0; }
$ ./sample-005.exe iary[0]=0 iary[1]=1 iary[2]=4 iary[3]=9 iary[4]=16 iary[5]=25 iary[6]=36 iary[7]=49 iary[8]=64 iary[9]=81 *(iary + 0)=0 *(iary + 1)=1 *(iary + 2)=4 *(iary + 3)=9 *(iary + 4)=16 *(iary + 5)=25 *(iary + 6)=36 *(iary + 7)=49 *(iary + 8)=64 *(iary + 9)=81 (iary-1)[i]=1, iary[i-1]=0 (iary-1)[i]=2, iary[i-1]=1 (iary-1)[i]=3, iary[i-1]=4 (iary-1)[i]=4, iary[i-1]=9 (iary-1)[i]=5, iary[i-1]=16 (iary-1)[i]=6, iary[i-1]=25 (iary-1)[i]=7, iary[i-1]=36 (iary-1)[i]=8, iary[i-1]=49 (iary-1)[i]=9, iary[i-1]=64 (iary-1)[i]=10, iary[i-1]=81 $
Download : sample-006.c
/* * 2020/11/13 sample-006.c */ /* * 配列名の関数への引渡し * * 利用方法 * コンパイル * cc -c sample-006.c * リンク * cc -o sample-006.exe sample-006.c * 実行 * ./sample-006.exe */ #include <stdio.h> /* * 配列サイズ */ #define ARRAY_SIZE 10 /* * 引数に配列を持つ関数 */ void print_array ( int a[ARRAY_SIZE] ) { int i; for ( i = 0; i < ARRAY_SIZE; i++ ) { printf ( "a[%d]=%d, %d*%d = %d\n", i, a[i], i, i, i*i ); } } /* * main * */ int main( int argc, char *argv[] ) { int iary[ARRAY_SIZE]; int i; /* 配列の初期化 */ /* iary[i] = i*i */ for ( i = 0; i < ARRAY_SIZE; i++ ) { iary[i] = i*i; } /* これで、iary は i=0〜9 なら、関数 f(x)=x^2 と同じ振舞いをする */ print_array ( iary ); /* 関数の引数に「配列名」を指定できる */ return 0; }
$ ./sample-006.exe a[0]=0, 0*0 = 0 a[1]=1, 1*1 = 1 a[2]=4, 2*2 = 4 a[3]=9, 3*3 = 9 a[4]=16, 4*4 = 16 a[5]=25, 5*5 = 25 a[6]=36, 6*6 = 36 a[7]=49, 7*7 = 49 a[8]=64, 8*8 = 64 a[9]=81, 9*9 = 81 $
Download : sample-007.c
/* * 2020/11/13 sample-007.c */ /* * 配列名の関数への引渡し(2) * * 利用方法 * コンパイル * cc -c sample-007.c * リンク * cc -o sample-007.exe sample-007.c * 実行 * ./sample-007.exe */ #include <stdio.h> /* * 配列サイズ */ #define I_ARRAY_SIZE 10 #define J_ARRAY_SIZE 5 /* * 配列のサイズは、省略可能 * サイズの異る配列に対しても同じ関数が利用できる !! */ void print_n_array ( int a[], int size ) { int i; for ( i = 0; i < size; i++ ) { printf ( "a[%d]=%d\n", i, a[i] ); } } /* * main * */ int main( int argc, char *argv[] ) { int iary[I_ARRAY_SIZE]; int jary[J_ARRAY_SIZE]; int i; /* 配列の初期化 */ /* iary[i] = i*i */ for ( i = 0; i < I_ARRAY_SIZE; i++ ) { iary[i] = i*i; } /* jary[i] = i*i*i */ for ( i = 0; i < J_ARRAY_SIZE; i++ ) { jary[i] = i*i*i; } printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 ); print_n_array ( iary, I_ARRAY_SIZE ); /* iary の内容を出力 */ printf ( "jary: 0 〜 %d\n", J_ARRAY_SIZE - 1 ); print_n_array ( jary, J_ARRAY_SIZE ); /* jary の内容を出力 */ /* 配列の一部の表示も可能 */ printf ( "iary: 0 〜 %d\n", J_ARRAY_SIZE - 1 ); print_n_array ( iary, J_ARRAY_SIZE ); /* 配列の途中からの表示も可能 */ printf ( "iary: %d 〜 %d\n", J_ARRAY_SIZE, I_ARRAY_SIZE - 1 ); print_n_array ( iary + J_ARRAY_SIZE, I_ARRAY_SIZE - J_ARRAY_SIZE ); return 0; }
$ ./sample-007.exe iary: 0 〜 9 a[0]=0 a[1]=1 a[2]=4 a[3]=9 a[4]=16 a[5]=25 a[6]=36 a[7]=49 a[8]=64 a[9]=81 jary: 0 〜 4 a[0]=0 a[1]=1 a[2]=8 a[3]=27 a[4]=64 iary: 0 〜 4 a[0]=0 a[1]=1 a[2]=4 a[3]=9 a[4]=16 iary: 5 〜 9 a[0]=25 a[1]=36 a[2]=49 a[3]=64 a[4]=81 $
Download : sample-008.c
/* * 2020/11/13 sample-008.c */ /* * 配列名の関数への引渡し(3) * * 利用方法 * コンパイル * cc -c sample-008.c * リンク * cc -o sample-008.exe sample-008.c * 実行 * ./sample-008.exe */ #include <stdio.h> /* * 配列サイズ */ #define I_ARRAY_SIZE 10 /* * 1 次元配列 (a[]) の仮引数変数宣言は、「*a」形の宣言でも良い */ void print_n_array ( int *a, int size ) { int i; for ( i = 0; i < size; i++ ) { printf ( "a[%d]=%d\n", i, a[i] ); } } /* * main * */ int main( int argc, char *argv[] ) { int iary[I_ARRAY_SIZE]; int i; /* 配列の初期化 */ /* iary[i] = i*i */ for ( i = 0; i < I_ARRAY_SIZE; i++ ) { iary[i] = i*i; } printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 ); print_n_array ( iary, I_ARRAY_SIZE ); /* iary の内容を出力 */ return 0; }
$ ./sample-008.exe iary: 0 〜 9 a[0]=0 a[1]=1 a[2]=4 a[3]=9 a[4]=16 a[5]=25 a[6]=36 a[7]=49 a[8]=64 a[9]=81 $
Download : sample-009.c
/* * 2020/11/13 sample-009.c */ /* * 配列名の関数への引渡し(4) * * 利用方法 * コンパイル * cc -c sample-009.c * リンク * cc -o sample-009.exe sample-009.c * 実行 * ./sample-009.exe */ #include <stdio.h> /* * 配列サイズ */ #define I_ARRAY_SIZE 10 /* * 1 次元配列 (a[]) の仮引数変数宣言は、「*a」形の宣言でも良い */ void print_n_array ( int *a, int size ) { int i; for ( i = 0; i < size; i++ ) { printf ( "a[%d]=%d\n", i, a[i] ); } } /* * 配列引数の要素の値を書き換える */ void change_at ( int *a, int pos, int value ) { a[pos] = value; } /* * main * */ int main( int argc, char *argv[] ) { int iary[I_ARRAY_SIZE]; int i; /* 配列の初期化 */ /* iary[i] = i*i */ for ( i = 0; i < I_ARRAY_SIZE; i++ ) { iary[i] = i*i; } printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 ); print_n_array ( iary, I_ARRAY_SIZE ); /* iary の内容を出力 */ printf ( "%d 番目の要素を %d に書き換える\n", 5, 100 ); change_at ( iary, 5, 100 ); printf ( "iary: 0 〜 %d\n", I_ARRAY_SIZE - 1 ); print_n_array ( iary, I_ARRAY_SIZE ); /* iary の内容を出力 */ return 0; }
$ ./sample-009.exe iary: 0 〜 9 a[0]=0 a[1]=1 a[2]=4 a[3]=9 a[4]=16 a[5]=25 a[6]=36 a[7]=49 a[8]=64 a[9]=81 5 番目の要素を 100 に書き換える iary: 0 〜 9 a[0]=0 a[1]=1 a[2]=4 a[3]=9 a[4]=16 a[5]=100 a[6]=36 a[7]=49 a[8]=64 a[9]=81 $
Download : sample-011.c
/* * 2020/11/13 sample-011.c */ /* * 文字列の入力\n *\tscanf の「%s」で文字列を入力する事ができる * * 利用方法 * コンパイル * cc -c sample-011.c * リンク * cc -o sample-011.exe sample-011.c * 実行 * ./sample-011.exe */ #include <stdio.h> /* * main 関数 */ #define LINE_SIZE 128 /* 入力する文字列より大きなサイズにする */ int main ( int argc, char *argv[] ) { char line[LINE_SIZE]; /* 入力する文字列を収める文字型配列 */ printf ( "キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: " ); scanf ( "%s", line ); /* 書式は「%s」で、文字型配列名を直接使う(&)は不要 */ printf ( "あなたが入力した文字列は「%s」です。\n", line ); /* 空白文字(空白/タブ/改行)があると、「文字列の区切」とみなされる */ return 0; }
空白(' ')を含んだ、適当な長さの文字列
$ ./sample-011.exe < sample-011.in キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: 空白(' あなたが入力した文字列は「空白('」です。 $
Download : sample-012.c
/* * 2020/11/13 sample-012.c */ /* * 文字列の入力 (2) * gets で文字列を入力する事ができる * * 利用方法 * コンパイル * cc -c sample-012.c * リンク * cc -o sample-012.exe sample-012.c * 実行 * ./sample-012.exe */ #include <stdio.h> /* * main 関数 */ #define LINE_SIZE 128 /* 入力する文字列より大きなサイズにする */ int main ( int argc, char *argv[] ) { char line[LINE_SIZE]; /* 入力する文字列を収める文字型配列 */ printf ( "キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: " ); gets ( line ); /* gets では、「一行(改行の直前迄:改行含まず)」の文字列が入力される */ printf ( "あなたが入力した文字列は「%s」です。\n", line ); /* gets は一行(改行)までを入力する */ return 0; }
空白(' ')を含んだ、適当な長さの文字列
$ ./sample-012.exe < sample-012.in キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: 空白(' ')を含んだ、適当な長さの文字列 あなたが入力した文字列は「空白(' ')を含んだ、適当な長さの文字列」です。 $
Download : sample-013.c
/* * 2020/11/13 sample-013.c */ /* * 文字列の入力 (3)\n *\tfgets で文字列を入力する事ができる * * 利用方法 * コンパイル * cc -c sample-013.c * リンク * cc -o sample-013.exe sample-013.c * 実行 * ./sample-013.exe */ #include <stdio.h> /* * main 関数 */ #define LINE_SIZE 128 /* 入力する文字列より大きなサイズにする */ int main ( int argc, char *argv[] ) { char line[LINE_SIZE]; /* 入力する文字列を収める文字型配列 */ printf ( "キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: " ); fgets ( line, LINE_SIZE, stdin ); /* 入力先は、「標準入力 (stdin)」となる */ /* fgets では、文字列サイズが指定できる (安全) */ /* 指定したサイズより長い文字列は、入力が「待たされ」る */ printf ( "あなたが入力した文字列は「%s」です。\n", line ); /* 入力文字列内には、「改行」も含まれる */ return 0; }
空白(' ')を含んだ、適当な長さの文字列
$ ./sample-013.exe < sample-013.in キーボードから、「空白(' ')を含んだ、適当な長さの文字列」と入力して Enter キーを押してください。: 空白(' ')を含んだ、適当な長さの文字列 あなたが入力した文字列は「空白(' ')を含んだ、適当な長さの文字列 」です。 $
Download : sample-021.c
/* * 2020/11/13 sample-021.c */ /* * sizeof 演算子\n *\t型名を指定する事により、そのサイズ(byte 単位)を得る事ができる * * 利用方法 * コンパイル * cc -c sample-021.c * リンク * cc -o sample-021.exe sample-021.c * 実行 * ./sample-021.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { printf ( "sizeof ( char ) = %d\n", sizeof ( char ) ); printf ( "sizeof ( int ) = %d\n", sizeof ( int ) ); printf ( "sizeof ( double ) = %d\n", sizeof ( double ) ); return 0; }
$ ./sample-021.exe sizeof ( char ) = 1 sizeof ( int ) = 4 sizeof ( double ) = 8 $
Download : sample-022.c
/* * 2020/11/13 sample-022.c */ /* * sizeof 演算子 (2)\n *\t変数名を指定する事により、そのサイズ(byte 単位)を得る事ができる * * 利用方法 * コンパイル * cc -c sample-022.c * リンク * cc -o sample-022.exe sample-022.c * 実行 * ./sample-022.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { char cvar; int ivar; double dvar; printf ( "sizeof ( cvar ) = %d\n", sizeof ( cvar ) ); printf ( "sizeof ( ivar ) = %d\n", sizeof ( ivar ) ); printf ( "sizeof ( dvar ) = %d\n", sizeof ( dvar ) ); return 0; }
$ ./sample-022.exe sizeof ( cvar ) = 1 sizeof ( ivar ) = 4 sizeof ( dvar ) = 8 $
Download : sample-023.c
/* * 2020/11/13 sample-023.c */ /* * sizeof 演算子 (3)\n *\t配列名を指定する事により、そのサイズ(byte 単位)を得る事ができる * * 利用方法 * コンパイル * cc -c sample-023.c * リンク * cc -o sample-023.exe sample-023.c * 実行 * ./sample-023.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { char cary[100]; int iary[100]; double dary[100]; printf ( "sizeof ( cary ) = %d\n", sizeof ( cary ) ); printf ( "sizeof ( iary ) = %d\n", sizeof ( iary ) ); printf ( "sizeof ( dary ) = %d\n", sizeof ( dary ) ); return 0; }
$ ./sample-023.exe sizeof ( cary ) = 100 sizeof ( iary ) = 400 sizeof ( dary ) = 800 $
Download : sample-024.c
/* * 2020/11/13 sample-024.c */ /* * sizeof 演算子 (4)\n *\t値を指定する事もできる * * 利用方法 * コンパイル * cc -c sample-024.c * リンク * cc -o sample-024.exe sample-024.c * 実行 * ./sample-024.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { printf ( "sizeof ( 'a' ) = %d\n", sizeof ( 'a' ) ); /* sizeof ( int ) [整数] になっている */ printf ( "sizeof ( 123 ) = %d\n", sizeof ( 123 ) ); printf ( "sizeof ( 12.3 ) = %d\n", sizeof ( 12.3 ) ); return 0; }
$ ./sample-024.exe sizeof ( 'a' ) = 4 sizeof ( 123 ) = 4 sizeof ( 12.3 ) = 8 $
Download : sample-025.c
/* * 2020/11/13 sample-025.c */ /* * sizeof 演算子 (5)\n *\t式のサイズも得られる\n *\tchar 型のデータは、計算の時に、int 型に昇格する * * 利用方法 * コンパイル * cc -c sample-025.c * リンク * cc -o sample-025.exe sample-025.c * 実行 * ./sample-025.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { char ch; char dh; printf ( "sizeof ( ch ) = %d\n", sizeof ( ch ) ); /* sizeof ( char ) [文字] になっている */ printf ( "sizeof ( ch + dh ) = %d\n", sizeof ( ch + dh ) ); /* sizeof ( int ) [整数] になっている */ /* 無条件の型の昇格がおきている */ return 0; }
$ ./sample-025.exe sizeof ( ch ) = 1 sizeof ( ch + dh ) = 4 $
Download : sample-026.c
/* * 2020/11/13 sample-026.c */ /* * 型の昇格\n *\tint 型から double 型への変換 * * 利用方法 * コンパイル * cc -c sample-026.c * リンク * cc -o sample-026.exe sample-026.c * 実行 * ./sample-026.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { int num; int mum; printf ( "sizeof ( num ) = %d\n", sizeof ( num ) ); printf ( "sizeof ( num + 'A' ) = %d\n", sizeof ( num + 'A' ) ); printf ( "sizeof ( num + mum ) = %d\n", sizeof ( num + mum ) ); printf ( "sizeof ( num + 1.0 ) = %d\n", sizeof ( num + 1.0 ) ); return 0; }
$ ./sample-026.exe sizeof ( num ) = 4 sizeof ( num + 'A' ) = 4 sizeof ( num + mum ) = 4 sizeof ( num + 1.0 ) = 8 $
Download : sample-027.c
/* * 2020/11/13 sample-027.c */ /* * 型の変換\n *\t代入では、必要に応じて型変換が行わる * * 利用方法 * コンパイル * cc -c sample-027.c * リンク * cc -o sample-027.exe sample-027.c * 実行 * ./sample-027.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { char ch = 'A'; /* そもそも 'A' は int 型 */ int num = 'A'; double fp = 'A'; /* int 型から double 型へ */ ch = ch - 'A' + 'a'; /* int 型から char 型へ */ ch = num; /* int 型から char 型へ */ num = fp; /* double 型から int 型へ */ printf ( "ch = %c\n", ch ); printf ( "num = %d\n", num ); printf ( "fp = %f\n", fp ); return 0; }
$ ./sample-027.exe ch = A num = 65 fp = 65.000000 $
Download : sample-028.c
/* * 2020/11/13 sample-028.c */ /* * 型の変換 (2)\n *\tサイズの大きい方から、小さい方への変換は危険 * * 利用方法 * コンパイル * cc -c sample-028.c * リンク * cc -o sample-028.exe sample-028.c * 実行 * ./sample-028.exe */ #include <stdio.h> /* * main 関数 */ int main ( int argc, char *argv[] ) { char ch = 'A'; int num = 'A'; double fp = 'A'; /* 個々に適切な値を入れれば問題はない */ printf ( "[適切な値]\n" ); printf ( "\tch = '%c' [%d]\n", ch, ch ); printf ( "\tnum = %d\n", num ); printf ( "\tfp = %f\n", fp ); /* char 型に収まらないサイズの値を代入すると ?? */ num = 1000; /* 1000 > 255 なので、1000 は char 型に収まらない */ ch = num; /* 代入を行うとどうなるか */ printf ( "[char に大きな値]\n" ); printf ( "\tch = '%c' [%d]\n", ch, ch ); printf ( "\tnum = %d\n", num ); /* int 型に収まらないサイズの値を代入すると ?? */ fp = 1000000000000; num = fp; ch = fp; printf ( "[int に大きな値]\n" ); printf ( "\tch = '%c' [%d]\n", ch, ch ); printf ( "\tnum = %d\n", num ); printf ( "\tfp = %f\n", fp ); return 0; }
$ ./sample-028.exe [適切な値] ch = 'A' [65] num = 65 fp = 65.000000 [char に大きな値] ch = '?' [-24] num = 1000 [int に大きな値] ch = ' ' [0] num = -2147483648 fp = 1000000000000.000000 $
/* * 課題 20201030-03 * * 20201030 20201030-03-QQQQ.c * * 3 次元ベクトルの差の計算 * 構造体で表現 */ #include <stdio.h> /* * 3 次元ベクトル */ typedef struct { /* 3 次元ベクトル */ double x; /* x 要素 */ double y; /* y 要素 */ double z; /* z 要素 */ } Vector3D; /* 新しい型 : Vector3D */ /* * void print_Vector3D ( Vector3D v ) * ベクトルの内容を書き出す * Vector3D v; 書き出すベクトル */ void print_Vector3D ( Vector3D v ) { printf ( " %f\n", v.x ); /* v の x 要素の出力 */ printf ( "( %f )\n", v.y ); /* v の y 要素の出力 */ printf ( " %f\n", v.z ); /* v の z 要素の出力 */ /* TeX で表現するならば、 printf ( "\\left(\\begin{array}{c} %f \\\\ %f \\\ %f \\end{array}\\right)\n", v.x, v.y, v.z ); などととすればよい。 */ } /* * Vector3D sub_Vector3D ( Vector3D dst, Vector3D src ) * 二つのベクトルの差を計算する * Vector3D dst; 引かれるベクトル * Vector3D src; 引くベクトル * 帰り値 二つのベクトルの差となるベクトル */ Vector3D sub_Vector3D ( Vector3D dst, Vector3D src ) { Vector3D result; /* 計算結果(差)を收める変数 */ /* result = dst - src; result.x = dst.x - src.x result.y = dst.y - src.y result.z = dst.z - src.z Vector3D Vector3D Vector3D | dst x src -> result = dst - src | | | | | | | | | v v v | dst.x src.x result.x dst.x-src.x | ( dst.y ) ( src.y ) -> ( result.y ) = ( dst.y-src.y ) v dst.z src.z result.z dst.z-src.z double ( double ) double */ result.x = dst.x - src.x; /* x 成分の計算 */ result.y = dst.y - src.y; /* y 成分の計算 */ result.z = dst.z - src.z; /* z 成分の計算 */ return result; /* 計算した結果を値として返す */ } /* * main */ int main( int argc, char *argv[] ) { Vector3D dst; Vector3D src; dst.x = 1.2; /* 1.2 */ dst.y = 2.3; /* dst = ( 2.3 ) */ dst.z = 3.4; /* 3.4 */ src.x = -9.8; /* -9.8 */ src.y = 8.7; /* dst = ( 8.7 ) */ src.z = 0.0; /* 0.0 */ print_Vector3D ( dst ); /* dst の出力 */ printf ( "と\n" ); print_Vector3D ( src ); /* src の出力 */ printf ( "の差は\n" ); print_Vector3D ( sub_Vector3D ( dst, src ) ); printf ( "となります。\n" ); return 0; }
/* * 課題 20201106-01 * * 20201106 20201106-01-QQQQ.c * * 複素数型の四則 * 実数 R : double * 複素数 C : 2 つの double の直積 => 構造体 * z (\in C) = x + y i ( x, y \in R, i は虚数単位 ) */ #include <stdio.h> /* * 複素数型の定義と計算 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe 20201106-01-QQQQ.c * 実行 * BASENAME */ #include <stdio.h> /* * 複素数型を表す Complex の定義 * * 複素数 z は、二つの実数 x, y を用いて * z = x + yi ( i は虚数単位 ) * と表現できる。 * C 言語では実数を表すのに浮動小数点数型の double を用いる * 型名 ( Complex ) を大文字で始めるのは「ソフトウェア概論ルール」 */ typedef struct { double real; /* 実部 */ double imaginary; /* 虚部 */ } Complex; /* 複素数型 */ /* * Complex make_Complex ( double x, double y ) * Complex 型の数を作り、返す * x, y -> z = x + yi */ Complex make_Complex ( double x, double y ) { Complex newComplex; /* 新しく作られる複素数 */ newComplex.real = x; /* 新しく作られた複素数の実部は x */ newComplex.imaginary = y; /* 新しく作られた複素数の実部は y */ return newComplex; /* 新しく作られる複素数を値として返す */ } /* * double real_part ( Complex z ) * Complex 型の数の実部を返す * z = x + yi -> x */ double real_part ( Complex z ) { return z.real; } /* * double imaginary_part ( Complex z ) * Complex 型の数の実部を返す * z = x + yi -> x */ double imaginary_part ( Complex z ) { return z.imaginary; } /* * print_Complex ( Complex z ) * Complex 型の数の出力 * z = x + y i だが、y < 0 の時は z = x - (-y) i となるように工夫 */ void print_Complex ( Complex z ) { if ( z.imaginary > 0.0 ) { printf ( "%f + %f i", z.real, z.imaginary ); } else { printf ( "%f - %f i", z.real, - z.imaginary ); } } /* * Complex add_Complex ( Complex z1, Complex z2 ) * Complex 型の数の足し算 * z1 = x1 + y1 i * z2 = x2 + y2 i * -> z1 + z2 = ( x1 + x2 ) + ( y1 + y2 ) i */ Complex add_Complex ( Complex z1, Complex z2 ) { Complex result; /* 複素数の和の実部は、実部の和 */ result.real = z1.real + z2.real; /* 複素数の和の虚部は、虚部の和 */ result.imaginary = z1.imaginary + z2.imaginary; return result; } /* * Complex sub_Complex ( Complex z1, Complex z2 ) * Complex 型の数の引き算 * z1 = x1 + y1 i * z2 = x2 + y2 i * -> z1 - z2 = ( x1 - x2 ) + ( y1 - y2 ) i */ Complex sub_Complex ( Complex z1, Complex z2 ) { Complex result; /* 複素数の差の実部は、実部の差 */ result.real = z1.real - z2.real; /* 複素数の差の虚部は、虚部の差 */ result.imaginary = z1.imaginary - z2.imaginary; return result; } /* * Complex mul_Complex ( Complex z1, Complex z2 ) * Complex 型の数のかけ算 * z1 = x1 + y1 i * z2 = x2 + y2 i * の時 * z1 * z2 = (x1 * x2 - y1 * y2) + (x1 * y2 + x2 * y1) i * = (x1 * x2 + i^2 y1 * y2) + (x1 * y2 + x2 * y1) i */ Complex mul_Complex ( Complex z1, Complex z2 ) { Complex result; result.real = z1.real * z2.real - z1.imaginary * z2.imaginary; result.imaginary = z1.real * z2.imaginary + z1.imaginary * z2.real; return result; } /* * Complex div_Complex ( Complex z1, Complex z2 ) * Complex 型の数の割り算 * z1 = x1 + y1 i * z2 = x2 + y2 i * の時 * z1 / z2 = ( x1 + y1 i ) / ( x2 + y2 i ) * = ( x1 + y1 i )( x2 - y2 i ) / ( x2 + y2 i )( x2 - y2 i ) * = ( x1 * x2 + y1 * y2) / ( x2^2 + y2^2 ) * + ( (- x1 * y2 + x2 * y1) / ( x2^2 + y2^2 ) ) i */ Complex div_Complex ( Complex z1, Complex z2 ) { Complex result; double denominator = z2.real * z2.real + z2.imaginary *z2.imaginary; /* 実部、虚部の割る数 |z2|^2 を予め計算しておく */ /* ** この部分を完成させなさい */ result.imaginary = ( - z1.real * z2.imaginary + z1.imaginary * z2.real ) / denominator; return result; } /* * print_result 演算結果を出力する */ void print_result ( Complex z1, Complex z2, char *operator, Complex z ) { print_Complex ( z1 ); printf ( " と、 " ); print_Complex ( z2 ); printf ( " との、%s は ", operator ); print_Complex ( z ); printf ( " です。\n" ); } /* * main */ int main( int argc, char *argv[] ) { Complex z1 = make_Complex ( 20.0, -15.0 ); /* z1 = 20 - 15i */ Complex z2 = make_Complex ( 1.0, 2.0 ); /* z2 = 1 + 2i */ /* 和の出力 */ print_result ( z1, z2, "和", add_Complex ( z1, z2 ) ); /* 差の出力 */ print_result ( z1, z2, "差", sub_Complex ( z1, z2 ) ); /* 積の出力 */ /* ** この部分を完成させなさい */ /* 商の出力 */ print_result ( z1, z2, "商", div_Complex ( z1, z2 ) ); return 0; }
/* * 課題 20201106-02 * * 20201106 20201106-02-QQQQ.c * * 二次元行列型の定義と計算 */ #include <stdio.h> /* * */ #define DIMENSION 2 /* 二次元 */ /* * 行列 A は、2 x 2 = 4 の要素をもっている * * A = ( 1 2 ) = ( a[0][0] a[0][1] ) * 3 4 a[1][0] a[1][1] * */ typedef struct { double a[DIMENSION][DIMENSION]; /* 二次元の行列の要素は 2 x 2 */ } Matrix2D; /* Matrix2D 型の宣言 */ /* * Matrix2D make_Matrix2D ( double a, double b, double c, double d ) * 「行列」を作成する * * A = ( a b ) = ( a[0][0], a[0][1] ) * ( c d ) ( a[1][0], a[1][1] ) */ Matrix2D make_Matrix2D ( double a, double b, double c, double d ) { Matrix2D newMatrix2D; /* 新しい行列 */ newMatrix2D.a[0][0] = a; newMatrix2D.a[0][1] = b; newMatrix2D.a[1][0] = c; newMatrix2D.a[1][1] = d; return newMatrix2D; } /* * void print_Matrix2D ( Matrix2D ary ); * 「行列」を表示する (表示の都合上、常に独立した行に出力する) * Matrix2D ary; 二次元行列 */ void print_Matrix2D ( Matrix2D ary ) { int r; /* 行 ( row ) */ int c; /* 列 ( colomun ) */ for ( r = 0; r < DIMENSION; r++ ) { printf ( "(" ); for ( c = 0; c < DIMENSION; c++ ) { printf ( " %10.5f", ary.a[r][c] ); /* * [注意] %10.5f は %f と同じく浮動小数点数を出力するが * 「全体の桁数は 10 桁、小数点数以下は 5 桁にする」 * という「表示上の指定」も加わっている * 詳しくは google で「printf 書式」で検索 */ } printf ( " )\n" ); } } /* * Matrix2D add_Matrix2D ( Matrix2D a1, Matrix2D a2 ); * 「行列」の和 * * ( a b ) + ( e f ) = ( a + e b + f ) * ( c d ) ( g h ) ( c + g g + h ) * * ( a[0][0] a[0][1] ) + ( b[0][0] b[0][1] ) * ( a[1][0] a[1][1] ) ( b[1][0] b[1][1] ) * = ( a[0][0]+b[0][0] a[0][1]+b[0][1] ) * ( a[1][0]+b[1][0] a[1][1]+b[1][1] ) * * (a_ij) + (b_ij) = (a_ij+b_ij) for i=0,1 j=0,1 * */ Matrix2D add_Matrix2D ( Matrix2D a1, Matrix2D a2 ) { Matrix2D result; /* 計算結果 */ int r; /* 行 ( row ) */ int c; /* 列 ( colomun ) */ for ( r = 0; r < DIMENSION; r++ ) { for ( c = 0; c < DIMENSION; c++ ) { result.a[r][c] = a1.a[r][c] + a2.a[r][c]; } } return result; } /* * Matrix2D sub_Matrix2D ( Matrix2D a1, Matrix2D a2 ); * 「行列」の差 * * ( a b ) - ( e f ) = ( a - e b - f ) * ( c d ) ( g h ) ( c - g g - h ) */ Matrix2D sub_Matrix2D ( Matrix2D a1, Matrix2D a2 ) { Matrix2D result; /* 計算結果 */ int r; /* 行 ( row ) */ int c; /* 列 ( colomun ) */ for ( r = 0; r < DIMENSION; r++ ) { for ( c = 0; c < DIMENSION; c++ ) { result.a[r][c] = a1.a[r][c] - a2.a[r][c]; } } return result; } /* * Matrix2D mul_Matrix2D ( Matrix2D a1, Matrix2D a2 ); * 「行列」の積 * * ( a b ) ( e f ) = ( a * e + b * g a * f + b * h ) * ( c d ) ( g h ) ( c * e + d * g c * f + d * h ) * * (d_rc) = (a_ri) (b_ic) = ( \sum_i a_ri b_ic ) */ Matrix2D mul_Matrix2D ( Matrix2D a1, Matrix2D a2 ) { Matrix2D result; /* 計算結果 */ int r; /* 行 ( row ) */ int c; /* 列 ( colomun ) */ int i; /* 内積の和の要素の番号 */ for ( r = 0; r < DIMENSION; r++ ) { for ( c = 0; c < DIMENSION; c++ ) { double products = 0.0; /* a1 の r 行と a2 の c 列の内積の結果 */ /* a1 の r 行と a2 の c 列の内積を計算する */ /* \sum_i a_ri b_ic */ for ( i = 0; i < DIMENSION; i++ ) { products = products + a1.a[r][i] * a2.a[i][c]; } result.a[r][c] = products; } } return result; } /* * print_result 演算結果を出力する */ void print_result ( Matrix2D a1, Matrix2D a2, char *operator, Matrix2D a ) { printf ( "%s の計算\n", operator ); print_Matrix2D ( a1 ); printf ( " と、 \n" ); print_Matrix2D ( a2 ); printf ( " との、%s は \n", operator ); print_Matrix2D ( a ); printf ( " です。\n\n" ); } /* * main */ int main( int argc, char *argv[] ) { /* a1 = ( 1 2 ) ( 3 -1 ) a2 = ( -3 1 ) ( 1 -2 ) */ Matrix2D a1 = make_Matrix2D ( 1.0, 2.0, 3.0, -1.0 ); Matrix2D a2 = make_Matrix2D ( -3.0, 1.0, 1.0, -2.0 ); /* 和の出力 */ print_result ( a1, a2, "和", add_Matrix2D ( a1, a2 ) ); /* 差の出力 */ /* ** この部分を完成させなさい */ /* 積の出力 */ print_result ( a1, a2, "積", mul_Matrix2D ( a1, a2 ) ); return 0; }
#include <stdio.h> /* 3 次元ベクトル v = ( x, y, z ) <= 三つの座標からなる 構造体版 */ typedef struct { double x; double y; double z; } Vector3D; int main(void) { Vector3D v; Vector3D u; Vector3D w; /* v = (1,2,3) */ v.x = 1; v.y = 2; v.z = 3; /* u = (4,5,6) */ u.x = 4; u.y = 5; u.z = 6; /* w = u + v */ w.x = u.x + v.x; w.y = u.y + v.y; w.z = u.z + v.z; /* u = (1,2,3), v=(4,5,6), w = u + v = ( 1+4, 2+5, 3+6) */ printf ( "w = ( %f, %f, %f )\n", w.x, w.y, w.z ); return 0; }
#include <stdio.h> /* 3 次元ベクトル v = ( x, y, z ) <= 三つの座標からなる 配列版 */ #define X 0 /* 定数 0 に X という名前を付ける */ /* 以下、X が現れる 0 に置き換える */ #define Y 1 #define Z 2 int main(void) { double v[3]; /* 同じ型(浮動小数点数型)変数の並び */ double u[3]; double w[3]; /* v = (1,2,3) */ v[X] = 1; v[Y] = 2; v[Z] = 3; /* u = (4,5,6) */ u[X] = 4; u[Y] = 5; u[Z] = 6; /* w = u + v */ w[X] = u[X] + v[X]; w[Y] = u[Y] + v[Y]; w[Z] = u[Z] + v[Z]; /* u = (1,2,3), v=(4,5,6), w = u + v = ( 1+4, 2+5, 3+6) */ printf ( "w = ( %f, %f, %f )\n", w[X], w[Y], w[Z] ); return 0; }
#include <stdio.h> /* 3 次元ベクトル v = ( x, y, z ) <= 三つの座標からなる 配列版 (単なる構造体の劣化版でなく、配列らしい表現) */ #define X 0 /* 定数 0 に X という名前を付ける */ /* 以下、X が現れる 0 に置き換える */ #define Y 1 #define Z 2 #define DIM 3 /* ベクトルの次元 */ int main(void) { double v[DIM]; /* 同じ型(浮動小数点数型)変数の並び */ double u[DIM]; double w[DIM]; int i; /* 配列の要素を参照する『添え字』を表す変数 */ /* v = (1,2,3) */ for ( i = 0; i < DIM; i++ ) { v[i] = i + 1; } /* u = (4,5,6) */ for ( i = 0; i < DIM; i++ ) { u[i] = i + 4; } /* w = u + v */ for ( i = 0; i < DIM; i++ ) { w[i] = u[i] + v[i]; /* w_i = x_i + y_i (for i = 0,1,2) */ } /* u = (1,2,3), v=(4,5,6), w = u + v = ( 1+4, 2+5, 3+6) */ printf ( "w = ( " ); for ( i = 0; i < DIM; i++ ) { printf ( "%f", w[i] ); if ( i < DIM - 1 ) { printf ( ", " ); } else { printf ( " " ); } } printf ( ")\n" ); return 0; }
#include <stdio.h> /* 3 次元ベクトル v = ( x, y, z ) <= 三つの座標からなる 配列版 (単なる構造体の劣化版でなく、配列らしい表現) 3 次元ベクトル => 10 次元ベクトル */ #define X 0 /* 定数 0 に X という名前を付ける */ /* 以下、X が現れる 0 に置き換える */ #define Y 1 #define Z 2 #define DIM 10 /* ベクトルの次元 */ /* 3 => 10 への変更は、一行だけ */ int main(void) { double v[DIM]; /* 同じ型(浮動小数点数型)変数の並び */ double u[DIM]; double w[DIM]; int i; /* 配列の要素を参照する『添え字』を表す変数 */ /* v = (1,2,3) */ for ( i = 0; i < DIM; i++ ) { v[i] = i + 1; } /* u = (4,5,6) */ for ( i = 0; i < DIM; i++ ) { u[i] = i + 4; } /* w = u + v */ for ( i = 0; i < DIM; i++ ) { w[i] = u[i] + v[i]; /* w_i = x_i + y_i (for i = 0,1,2) */ } /* u = (1,2,3), v=(4,5,6), w = u + v = ( 1+4, 2+5, 3+6) */ printf ( "w = ( " ); for ( i = 0; i < DIM; i++ ) { printf ( "%f", w[i] ); if ( i < DIM - 1 ) { printf ( ", " ); } else { printf ( " " ); } } printf ( ")\n" ); return 0; }
#include <stdio.h> int main(void) { int a[2][2]; /* 整数型の配列の配列 */ /* 整数型の 2 次元配列 */ /* => 結果的に 2x2 = 4 個の変数 */ /* a[0][0], a[0][1], a[1][0], a[1][1] */ /* a => { a[0], a[1] } */ /* => { { a[0][0], a[0][1] }, { a[1][0], a[1][0] } } */ /* a = ( 1 2 ) 3 4 */ a[0][0] = 1; a[0][1] = 2; a[1][0] = 3; a[1][1] = 4; printf ( "a = ( %d %d )\n", a[0][0], a[0][1] ); printf ( " %d %d\n", a[1][0], a[1][1] ); return 0; }
前回の内容 : データ構造 (2) 配列 : 複数の同じ型の変数(配列の要素)をまとめたもの 構造体 : 異なる型の変数の組み合わせ => 異なる型のデータの組み合わせを表現するために用いる 同じ型の値が並んだもの(ベクトル)を表現するデータ型 配列を、「同じ型の変数の組み合わせ」と考える => 構造体の方が便利 <= 要素の参照の仕方が異なる 配列の宣言 : 配列を構成する「要素数」を指定して宣言 例 : int a[3] -> 3 つの変数 ( a[0], a[1], a[2] ) を宣言 配列の要素(配列の一部となる変数)は、[] (添字) で参照可能 例 : a[1] -> 配列 a の 2 つ目 ( 1 つ目 a[0] なので.. ) を表す 「添え『字』」=>要素の位置を表す整数値(『数』) { '0', '1', '2' } : 『字』の集合 { 0, 1 , 2 } : 『数』の集合 => 『数』の場合は『計算』ができる 単なる集合ではなく(演算のついた..)空間 「添字」の所には、「整数値を持つ式」が入れられる !! 「式」の中には、「変数」を含める事ができる 配列は、「データ型」の表現 構造体に比べて、能力が落ちる 要素の参照に『添え字』という「整数式」が使える 要素の参照が便利(構造体より使いやすい..) 要素の番号を表す変数と併用する事により 要素のへの処理が繰り返し(for 構文)で実現できる データのサイズ(配列の要素数)からプログラムが独立化できる 配列による「集合」の表現 サイズ N の配列で、サイズ N の(有限)部分集合が表現できる 配列と for 構文の関係 配列の要素を処理する場合は for 構文が馴染む [2020/11/13] (資料: 2020/11/06) 単純型(0 次元)の配列は、1 次元(0+1 次元)の空間 (単純型:0)の配列(+1)の配列(+1)は、2(0+1+1)次元になる 次元 : 添え字の個数 多次元の配列 配列の配列が作れる : 多次元配列 [例] int d[3][4]; /* 二次元 3 × 4 の 12 個の要素を持つ配列 */ 次元は幾つでも増やす事ができる int t[3][4][5]; /* 三次元配列 */ データ構造の利用 ベクトル : 1 次元の配列 行列 : 2 次元の配列 (DLで利用するテンソルは、n 次元の配列) データ構造を作る要素(構造体、配列)を 組み合わせて利用する事により、 様々な(より複雑な)機能が より簡単(可換構造を利用して、単純な操作の組み合わせ)に表現できる
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20201113-01.c
/* * 課題 20201113-01 * * 20201113 20201113-01-QQQQ.c * * 浮動小数点数の配列の要素内の数値の総和を求める。 */ #include <stdio.h> /* * 浮動小数点数の配列の要素内の数値の総和を求める。 * * 利用方法 * コンパイル * cc -o BASENAME.exe 20201113-01-QQQQ.c * 実行 * ./BASENAME.exe */ #include <stdio.h> /* * double dsum ( double ary[], int size ) * 浮動小数点数の配列の要素内の数値の総和を求める関数 * double ary[]; 総和を求める要素を含む配列 * int size; 配列のサイズ */ double dsum ( double ary[], int size ) { double sum = 0.0; /* 総和は最初は 0 */ int i; /* 配列の要素を参照する添字変数 */ for ( i = 0; i < size; i++ ) { /* i = 0 〜 sum - 1 の間.. */ /* ** この部分を完成させなさい */ /* 「sum += ary[i]」とも書きける */ } return sum; /* 結果を返す */ } /* * main */ #define ARY_SIZE 5 int main( int argc, char *argv[] ) { double data[ARY_SIZE]; /* 大きさ ARY_SIZE の配列の宣言 */ int i; /* 配列の要素を参照する添字変数 */ double sum; /* 総和の計算結果を保持する */ printf ( "%d 個のデータを入力します。\n", ARY_SIZE ); for ( i = 0; i < ARY_SIZE; i++ ) { printf ( "%d 番目の数値を入力してください : ", i + 1 ); /* ** この部分を完成させなさい */ } sum = dsum ( data, ARY_SIZE ); printf ( "入力されたデータの総和は %f です。\n", sum ); return 0; }
2.3 9.1 5.9 2.7 3.2
$ ./20201113-01-QQQQ.exe 5 個のデータを入力します。 1 番目の数値を入力してください : 2.300000 2 番目の数値を入力してください : 9.100000 3 番目の数値を入力してください : 5.900000 4 番目の数値を入力してください : 2.700000 5 番目の数値を入力してください : 3.200000 入力されたデータの総和は 23.200000 です。 $
Download : 20201113-02.c
/* * 課題 20201113-02 * * 20201113 20201113-02-QQQQ.c * * 文字列の途中に文字を挿入する * * 利用方法 * コンパイル * cc -o BASENAME.exe 20201113-02-QQQQ.c * 実行 * ./BASENAME.exe */ #include <stdio.h> /* * */ /* * main * */ #define CSIZE 10 #define EOS '\0' int main( int argc, char *argv[] ) { char cary[CSIZE] = { 'a', 'b', 'c', 'd', 'e', EOS }; /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'c'|'d'|'e'|EOS| ? | ? | ? | ? | */ int i; int l; printf ( "最初の cary = %s\n", cary ); /* 文字列 "abcde" の入った文字配列 cary の 3 文字目 ('c') と 4 文字目 'd' の間に、一文字 'X' を入れる */ /* 文字列の長さを求める */ /* ** この部分を完成させなさい */ /* cary の中の文字列の長さは、変数 l に入る */ for ( i = l; 3 <= i; i-- ) { /* 後ろからコピーする必要がある */ /* ** この部分を完成させなさい */ } cary[3] = 'X'; /* 空けた場所に 'X' を入れる */ /* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | cary|'a'|'b'|'c'|'d'|'e'|EOS| ? | ? | ? | ? | | | | \ \ \ cary|'a'|'b'|'c'|'X'|'d'|'e'|EOS| ? | ? | ? | ? | */ printf ( "'X' を挿入した結果 : %s\n", cary ); return 0; }
123 987 456
$ ./20201113-02-QQQQ.exe 最初の cary = abcde 'X' を挿入した結果 : abcXde $
Download : 20201113-03.c
/* * 20201113-03-QQQQ.c * 一行分の文字列を入力して、その中の文字列を全て大文字に変換する */ #include <stdio.h> /* * islower (ch) : 指定された文字が、小文字かどうかを判定する */ int islower ( int ch ) { return 'a' <= ch && ch <= 'z'; /* 'a' 〜 'z' なら小文字 */ } /* * toupper ( ch ) : 指定された文字が、小文字なら大文字に変換 */ int toupper ( int ch ) { if ( islower ( ch ) ) { /* 小文字だった.. */ /* ** この部分を完成させなさい */ } else { /* そうでないなら */ return ch; /* そのまま返す */ } } /* * main */ #define EOS '\0' /* EOS を定義 */ #define LINE_SIZE 128 /* 入力するのに十分に大きなサイズにする */ int main ( void ) { char line[LINE_SIZE]; int i; printf ( "小文字を含んだ文字列を入力してください : " ); /* ** この部分を完成させなさい */ for ( i = 0; line[i] != EOS; i++ ) { line[i] = toupper ( line[i] ); /* 小文字を大文字に変換 */ } printf ( "結果 : %s", line ); return 0; }
aBcd123[]
$ ./20201113-03-QQQQ.exe 小文字を含んだ文字列を入力してください : 結果 : ABCD123[] $