Download : sample-001.c ( SJIS 版 )
/* * 2014/10/17 sample-001.c */ /* * 多次元配列 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ int main( int argc, char *argv[] ) { int a[3][4]; /* 二次元配列の宣言 3 x 4 個の変数を宣言 */ /* 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; } } 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; }
C:\usr\c>sample-001 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 C:\usr\c>
Download : sample-002.c ( SJIS 版 )
/* * 2014/10/17 sample-002.c */ /* * 集合の操作は操作の集合 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #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; /* 一桁の偶数の表を作る */ } /* 偶数を出力 */ for ( i = 0; i < ARRAY_SIZE; i++ ) { printf ( "%d ", a[i] ); } printf ( "\n" ); /* 全ての要素に 1 を加えれば奇数の表になる */ 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; }
C:\usr\c>sample-002 0 2 4 6 8 1 3 5 7 9 C:\usr\c>
/* * 2014/10/17 sample-001.c */ /* * 他次元配列 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ int main( int argc, char *argv[] ) { int a[3][4]; /* 二次元配列の宣言 3 x 4 個の変数を宣言 */ /* int a00, a01, .., a03, a10, .., a13, .., a23; と同様 */ int i; int j; a[0][0] = 0; /* 添字は、二つ必要 ( 二次なので.. ) で、0 から始まる */ /* 注意 a[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; } } 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; }
/* * 2014/10/17 sample-001.c */ /* * 配列の応用 ( 2 次元ベクトル ) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define DIM 2 /* 2 次元のベクトルを考える */ #define X 0 #define Y 1 int main( int argc, char *argv[] ) { int a[DIM]; /* 2 次元のベクトル a */ /* ベクトル a の x 成分は a[0], a の y 成分は a[1] で 表現される ベクトル a の x 成分は a[X] となる */ int b[DIM]; /* 2 次元のベクトル b */ int c[DIM]; /* 2 次元のベクトル c */ a[X] = 1; a[Y] = 2; /* a = ( 1 ) 2 */ b[X] = -3; b[Y] = 5; /* b = ( -3 ) 5 */ /* ベクトル a と ベクトル b の和をベクトル c とする */ c[X] = a[X] + b[X]; c[Y] = a[Y] + b[Y]; /* c = a + b = ( 1 ) + ( -3 ) = ( -2 ) 2 5 7 */ printf ( " ( %d )\n", c[X] ); printf ( " %d \n", c[Y] ); return 0; }
/* * 2014/10/17 sample-001.c */ /* * 配列の応用 ( 2 次元ベクトル ) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define DIM 2 /* 2 次元のベクトルを考える */ #define X 0 #define Y 1 int main( int argc, char *argv[] ) { int a[DIM]; /* 2 次元のベクトル a */ int b[DIM]; /* 2 次元のベクトル b */ int c[DIM]; /* 2 次元のベクトル c */ int i; a[X] = 1; a[Y] = 2; b[X] = -3; b[Y] = 5; /* ベクトルの和 */ for ( i = 0; i < DIM; i++ ) { c[i] = a[i] + b[i]; } /* ベクトルの表示 */ for ( i = 0; i < DIM; i++ ) { if ( i == 0 ) { printf ( " ( %d )\n", c[i] ); } else { printf ( " %d \n", c[i] ); } } return 0; }
/* * 2014/10/17 sample-001.c */ /* * 配列の応用 ( 10 次元ベクトル ) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define DIM 10 /* 10 次元のベクトルを考える */ int main( int argc, char *argv[] ) { int a[DIM]; /* 2 次元のベクトル a */ int b[DIM]; /* 2 次元のベクトル b */ int c[DIM]; /* 2 次元のベクトル c */ int i; for ( i = 0; i < DIM; i++ ) { a[i] = i + 1; } for ( i = 0; i < DIM; i++ ) { b[i] = 2 * i; } /* ベクトルの和 */ for ( i = 0; i < DIM; i++ ) { c[i] = a[i] + b[i]; } /* ベクトルの表示 */ for ( i = 0; i < DIM; i++ ) { if ( i == 0 ) { printf ( " ( %d )\n", c[i] ); } else { printf ( " %d \n", c[i] ); } } return 0; }
/* * 2014/10/17 sample-001.c */ /* * 配列の応用 ( 2 次元ベクトル ) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define DIM 2 /* 2 次元のベクトルを考える */ #define X 0 #define Y 1 int main( int argc, char *argv[] ) { int a[DIM]; /* 2 次元のベクトル a */ int b[DIM]; /* 2 次元のベクトル b */ int M[DIM][DIM]; /* 2 x 2 (二次)の正方行列 */ int i; /* 添字 */ a[X] = 1; a[Y] = 2; M[0][0] = 1; /* 単位行列 */ M[0][1] = 0; M[1][0] = 0; M[1][1] = 1; /* M = ( 1 0 ) <-> ( M[0][0] M[0][1] ) 0 1 M[1][0] M[1][1] M は単位行列 */ /* ベクトルと行列のかけ算 */ /* b = M a */ /* b = ( b[0] ) = ( M[0][0] M[0][1] ) ( a[0] ) b[1] M[1][0] M[1][1] a[1] => b[0] = M[0][0] * a[0] + M[0][1] * a[1] b[1] = M[1][0] * a[0] + M[1][1] * a[1] */ b[0] = M[0][0] * a[0] + M[0][1] * a[1]; b[1] = M[1][0] * a[0] + M[1][1] * a[1]; /* ベクトルの表示 */ for ( i = 0; i < DIM; i++ ) { if ( i == 0 ) { printf ( " ( %d )\n", b[i] ); } else { printf ( " %d \n", b[i] ); } } return 0; }
/* * 2014/10/17 sample-001.c */ /* * 配列の応用 ( 2 次元ベクトル ) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define DIM 2 /* 2 次元のベクトルを考える */ #define X 0 #define Y 1 int main( int argc, char *argv[] ) { int a[DIM]; /* 2 次元のベクトル a */ int b[DIM]; /* 2 次元のベクトル b */ int M[DIM][DIM]; /* 2 x 2 (二次)の正方行列 */ int i; /* 添字 */ a[X] = 1; a[Y] = 2; M[0][0] = 0; /* y = x に対する対称変換 */ M[0][1] = 1; M[1][0] = 1; M[1][1] = 0; /* ベクトル a に M をかけると x, y 座標が交換されます */ /* M = ( 0 1 ) <-> ( M[0][0] M[0][1] ) 1 0 M[1][0] M[1][1] M は単位行列 */ /* ベクトルと行列のかけ算 */ /* b = M a */ /* b = ( b[0] ) = ( M[0][0] M[0][1] ) ( a[0] ) b[1] M[1][0] M[1][1] a[1] => b[0] = M[0][0] * a[0] + M[0][1] * a[1] b[1] = M[1][0] * a[0] + M[1][1] * a[1] */ b[0] = M[0][0] * a[0] + M[0][1] * a[1]; b[1] = M[1][0] * a[0] + M[1][1] * a[1]; /* ベクトルの表示 */ for ( i = 0; i < DIM; i++ ) { if ( i == 0 ) { printf ( " ( %d )\n", b[i] ); } else { printf ( " %d \n", b[i] ); } } return 0; }
/* * 2014/10/17 sample-001.c */ /* * 配列の応用 ( 2 次元ベクトル ) * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define DIM 2 /* 2 次元のベクトルを考える */ #define X 0 #define Y 1 int main( int argc, char *argv[] ) { int a[DIM]; /* 2 次元のベクトル a */ int b[DIM]; /* 2 次元のベクトル b */ int M[DIM][DIM]; /* 2 x 2 (二次)の正方行列 */ int i; /* 添字 */ a[X] = 1; a[Y] = 2; M[0][0] = 0; /* y = x に対する対称変換 */ M[0][1] = -1; M[1][0] = 1; M[1][1] = 0; /* ベクトル a に M をかけると 原点を中心に反時計回りに 90 度回転 */ /* M = ( 0 -1 ) <-> ( M[0][0] M[0][1] ) 1 0 M[1][0] M[1][1] 原点を中心に 90 度(Pi/2) 反時計回りに回転 M = ( \cos{\pi/2} -\sin{\pi/2} ) \sin{\pi/2} \cos{\pi/2} M = ( 0 -1 ) 1 0 */ /* ベクトルと行列のかけ算 */ /* b = M a */ /* b = ( b[0] ) = ( M[0][0] M[0][1] ) ( a[0] ) b[1] M[1][0] M[1][1] a[1] => b[0] = M[0][0] * a[0] + M[0][1] * a[1] b[1] = M[1][0] * a[0] + M[1][1] * a[1] */ b[0] = M[0][0] * a[0] + M[0][1] * a[1]; b[1] = M[1][0] * a[0] + M[1][1] * a[1]; /* for ( i = 0; i < DIM; i++ ) { int j; b[i] = 0; for ( j = 0; j < DIM; j++ ) { b[i] = b[i] + M[i][j] * a[j]; } } */ /* ベクトルの表示 */ for ( i = 0; i < DIM; i++ ) { if ( i == 0 ) { printf ( " ( %d )\n", b[i] ); } else { printf ( " %d \n", b[i] ); } } return 0; }
#include <stdio.h> /* 平面上の点 */ /* 構造体版 */ typedef struct { double x; /* 同じものでもよい */ double y; } Point; int main(int ac, char *av[] ) { Point p1; p1.x = 1.0; p1.y = 2.0; return 0; }
#include <stdio.h> /* 平面上の点 */ /* 配列版 */ #define DIM 2 int main(int ac, char *av[] ) { double p1[DIM]: p1[0] = 1.0; p1[1] = 2.0; return 0; }
#include <stdio.h> /* 平面上の点 (名前付) */ /* 構造体版 */ typedef struct { double x; /* 同じものでもよい */ double y; char name; } NamedPoint; int main(int ac, char *av[] ) { NamedPoint p1; p1.x = 1.0; p1.y = 2.0; p1.name = 'A'; return 0; }
#include <stdio.h> /* 平面上の点 */ /* 配列版 */ #define DIM 2 int main(int ac, char *av[] ) { double p1[DIM]: char p1name; p1[0] = 1.0; p1[1] = 2.0; p1name = 'A'; /* p1 という点がまとまっていない */ return 0; }
/* * 2014/10/17 sample-002.c */ /* * 集合の操作は操作の集合 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #include <stdio.h> /* * main * */ #define ARRAY_SIZE 5 /* 配列のサイズを 5 とする */ /* 要素を 5 つ含む集合を考えている */ int main( int argc, char *argv[] ) { int a[ARRAY_SIZE]; /* ARRAY_SIZE の配列の宣言 */ /* 整数を 5 つ含む集合 */ /* ただし、重複を許すので、実は bag になっている */ int i; for ( i = 0; i < ARRAY_SIZE; i++ ) { a[i] = 2 * i; /* 一桁の偶数の表を作る */ /* { 0, 2, 4, 6, 8 } */ } /* a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8; */ /* 「偶数の集合」を出力 */ printf ( "{ " ); for ( i = 0; i < ARRAY_SIZE; i++ ) { /* 繰り返す */ printf ( "%d ", a[i] ); /* 個々の要素の出力 */ } printf ( " }\n" ); /* 偶数の集合から奇数の集合に書き換える */ /* { 0 2 4 6 8 } -> { 1 3 5 7 9 } | | ^ ^ v | +1 | | +-|--->---->-----+ | | +1 | +----------------+ */ /* 全ての要素に 1 を加えれば奇数の表になる */ /* 偶数の集合を奇数の集合に換るという操作は 個々の偶数をそれぞれ奇数に書き換えるという操作の 繰返し */ printf ( "{ " ); 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; }
/* * 総和の計算 */ #include <stdio.h> #define DIM 10 int main(int ac, char *av[]) { int table[DIM]; /* データの表 */ int i; int sum; /* 総和の結果を保存する変数を準備 */ /* 値は擬似乱数で.. */ table[0] = 4; for ( i = 1; i < DIM; i++ ) { table[i] = ( table[i-1] * 13 + 153 ) % 100; } for ( i = 0; i < DIM; i++ ) { printf ( "%d ", table[i] ); } printf ( "\n" ); /* 総和の計算 (パターン) */ sum = 0; /* まず、総和を記録する変数を 0 で初期化 */ for ( i = 0; i < DIM; i++ ) { /* 集合の要素全てを処理 */ sum = sum + table[i]; /* 個々の要素を加える */ } /* 繰返しが終った時点で、 sum には table の値の総和が記録されている */ printf ( "sum = %d\n", sum ); return 0; }
/* * 最大値 */ #include <stdio.h> #define DIM 10 int main(int ac, char *av[]) { int table[DIM]; /* データの表 */ int i; int max; /* 最大の要素 */ /* 値は擬似乱数で.. */ table[0] = 4; for ( i = 1; i < DIM; i++ ) { table[i] = ( table[i-1] * 13 + 153 ) % 100; } for ( i = 0; i < DIM; i++ ) { printf ( "%d ", table[i] ); } printf ( "\n" ); /* 最大値を求める計算 (パターン) */ max = table[0]; /* 最大値の候補として、 最初の要素を無条件に採用 */ for ( i = 1; i < DIM; i++ ) { /* 全ての要素について.. i = 1 なのは i = 0 が無駄だから.. */ if ( max < table[i] ) { /* これから見る要素が、これまで候補より大きいなら .. */ max = table[i]; /* その要素を「最大値の候補」にする */ } else { /* そうでなければ */ /* なにもしない (これまで候補をそのまま採用..) */ } } printf ( "max = %d\n", max ); /* 課題(候補) : 最小値を求めるプログラムも考えてみる */ return 0; }
/* * 最大値の位置を求める */ #include <stdio.h> #define DIM 10 int main(int ac, char *av[]) { int table[DIM]; /* データの表 */ int i; int maxP; /* 最大の要素のある場所 */ /* 値は擬似乱数で.. */ table[0] = 4; for ( i = 1; i < DIM; i++ ) { table[i] = ( table[i-1] * 13 + 153 ) % 100; } for ( i = 0; i < DIM; i++ ) { printf ( "%d ", table[i] ); } printf ( "\n" ); /* 最大値を求める計算 (パターン) */ maxP = 0; /* 最大値のある場所の候補として、 最初の要素の位置を無条件に採用 */ for ( i = 1; i < DIM; i++ ) { /* 全ての要素について.. i = 1 なのは i = 0 が無駄だから.. */ if ( table[maxP] < table[i] ) { /* これから見る要素が、これまで候補より大きいなら .. */ maxP = i; /* その要素の位置を「最大値の位置の候補」にする */ } else { /* そうでなければ */ /* なにもしない (これまで候補をそのまま採用..) */ } } printf ( "maxP = %d\n", maxP ); /* 課題(候補) : 最小値を求めるプログラムも考えてみる */ return 0; }
/* * フィルタリング 50 より大きいものだけを出す */ #include <stdio.h> #define DIM 10 int main(int ac, char *av[]) { int table[DIM]; /* データの表 */ int i; /* 値は擬似乱数で.. */ table[0] = 4; for ( i = 1; i < DIM; i++ ) { table[i] = ( table[i-1] * 13 + 153 ) % 100; } for ( i = 0; i < DIM; i++ ) { printf ( "%d ", table[i] ); } printf ( "\n" ); /* フィルタリング : 条件を満すものだけを取り出す */ /* 条件の例 : 60 未満 */ for ( i = 0; i < DIM; i++ ) { /* 全ての人について.. */ if ( table[i] < 60 ) { printf ( "%i の方 %d 点で、不合格\n", i, table[i] ); } } return 0; }
/* 課題の一つ目 */ /* * 課題 CNAME-03 * * 20140926 20140926-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; /* 計算結果(差)を收める変数 */ /* dst.x src.x dst = ( dst.y ) src = ( src.y ) dst.z src.z dst.x + src.x dst + src = ( dst.y + src.y ) dst.z + src.z dst.x - src.x resutlt.x dst - src = ( dst.y - src.y ) = ( resutlt.y ) = resutlt dst.z - src.z resutlt.z */ result.x = dst.x - src.x; /* x 成分の計算 */ result.y = dst.y - src.y; /* y 成分の計算 */ /* ** この部分を完成させなさい (流石にココは考えて..) */ /* 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; }
/* 課題の二つ目 */ /* * 課題 20141010-01 * * 2014/10/10 20141010-01-QQQQ.c * * 複素数型の四則 */ #include <stdio.h> /* * 複素数型の定義と計算 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe 20141010-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 ) { 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 */ Complex mul_Complex ( Complex z1, Complex z2 ) { Complex result; /* z1 * z2 = ( x1 + y1 i ) ( x2 + y2 i ) = x1 * x2 + x1 * y2 i + y1 i * x2 + y1 i * y2 i = x1*x2 + x1*y2 i + y1*x2 i + y1*y2 * i^2 = x1*x2 + x1*y2 i + y1*x2 i - y1*y2 = (x1*x2-y1*y2) + (x1*y2+y1*x2) i */ 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 * 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 を予め計算しておく */ /* 1/z2 = 1 / ( x2 + y2 i ) = 1 * ( x2 - y2 i ) / ( x2 + y2 i ) * ( x2 - y2 i ) = ( x2 - y2 i ) / ( x2^2 + y2^2 ) = ( x2 - y2 i ) / ( |z2|^2 ) z1/z2 = z1 * (1/z2) = z1 * z2' / ( |z2|^2 ) = (z1 * z2') / ( |z2|^2 ) */ result.real = ( z1.real * z2.real + z1.imaginary * z2.imaginary ) / \ denominator; 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, "積", mul_Complex ( z1, z2 ) ); /* 商の出力 */ print_result ( z1, z2, "商", div_Complex ( z1, z2 ) ); /* 課題候補 : 複素数が扱えるので 二次方程式を解くプログラムが作れる(ような気分に)なった */ return 0; }
/* 課題その三 */ /* * 課題 20141003-02 * * 2014/10/03 20141003-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]; /* 2x2 の配列を唯一の要素とする構造体 */ /* これは単独の 「double a[2][2]」と何が違うの ? */ /* この詳しい説明は、次週以降.. */ /* 構造体は、代入や、関数への受渡ができるが 配列の場合は、それらができない(注意 !!!) ここでは、敢えて、構造体にしている */ /* 二次元の行列の要素は 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; /* newM の唯一の要素 a の更に 0,0 要素に代入 */ 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 ) */ 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 ) */ 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 列の内積を計算する */ for ( i = 0; i < DIMENSION; i++ ) { products = products + a1.a[r][i] * a2.a[i][c]; /* i = 0, 1 ( a1.a[r][0], a1.a[r][1] ) ( a2[0][c] ) a2[1][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 ) ); /* 差の出力 */ /* ** この部分を完成させなさい */ /* 積の出力 */ /* ** この部分を完成させなさい */ return 0; }
多次元配列 12 個の単純変数 int s0, s1, .., s11; /* イメージ (色々な所に箱がある) */ +-------+ s0 | | +-------+ +-------+ s1 | | +-------+ +-------+ s2 | | +-------+ .. サイズ 12 の一次元配列 int m[12]; /* イメージ (箱が一列に並んでいる) */ +-------+ m[0] | | +-------+ m[1] | | +-------+ | | .... | | +-------+ m[11] | | +-------+ サイズ 3 x 4 の二次元配列 int d[3][4]; /* イメージ (箱が平面上を埋めている) */ +-------+-------+-------+-------+ |d[0][1]|d[0][1]|d[0][2]|d[0][3]| +-------+-------+-------+-------+ |d[1][1]|d[1][1]|d[1][2]|d[1][3]| +-------+-------+-------+-------+ |d[2][1]|d[2][1]|d[2][2]|d[2][3]| +-------+-------+-------+-------+ サイズ 3 x 2 x 2 の三次元配列 int t[3][2][2]; /* イメージ (空間を.. ) */ 0 〜 2 と 0 〜 3 のかけ算表をつくってみる */ i*j | 0 1 2 3 | 0 1 2 3 ----+-------- => --+-------------------------------- 0 | 0 0 0 0 0 | a[0][0] a[0][1] a[0][2] a[0][3] 1 | 0 1 2 3 1 | a[1][0] a[1][1] a[1][2] a[1][3] 2 | 0 2 4 6 2 | a[2][0] a[2][1] a[2][2] a[2][3] a[i][j] == i * j という関係 a = ( 1 ) 2 | | | * a(1,2) * | a'(-2,1)| ----------+------------------- == データ構造の応用 配列 同じ種類の物が複数組み合された物 (同じでないといけない) <-> 構造体 : 異る種類の物が複数組み合わされた物 (同じ種類でもよい ) 配列使い方(その一) 同じ種類がまとまっている物 -> 集合を表現している 「集合」を表現する場合は、配列の方が良い 「集合の操作」は「要素の操作の繰返し」になる事が多い 「繰返し」と「配列」は相性がよい ( for 文 ) 配列使い方(そのニ) 「集合」から、「集計」を行う 全体の情報を集約して一つのデータ書き換える作業 例 : 総和、平均、最大値、最小値..
本日の課題は、以前出題したのに課題としなかった問題とするので、新規には設けていません。
以前の課題を提出してください。