Download : sample-001.c
/*
* 2019/11/08 sample-001.c
*/
/*
* 銀行口座への振込プログラム
*
* 利用方法
* コンパイル
* cc -c sample-001.c
* リンク
* cc -o sample-001.exe sample-001.c
* 実行
* ./sample-001.exe
*/
#include <stdio.h>
/*
* main
*
* 現実の世界 プログラムの世界
*
* [表現] 栗野の口座 kurino_account
*
* [事前] 100 万円 kurino_account = 1000000
*
* 振込額 10 万円 transfer_money = 100000
* <振込> kurino_account = kurino_account + transfer_money
* [事後] 110 万円
*
* <振込> という「情報上の機能」 <足し算> という「数値上の操作」
*/
int main( int argc, char *argv[] )
{
int kurino_account = 1000000; /* 栗野の銀行口座に 100 万円入っている */
int transfer_money = 100000; /* 10 万円の振込をしたい.. */
printf ( "現在の栗野の残高は %d 万円です。\n", kurino_account / 10000 );
/* <振込> を行うプログラム */
printf ( "栗野の口座に %d 万円の振込を行います。\n", transfer_money / 10000 );
/* 「足し算」が「振込」になる */
kurino_account = kurino_account + transfer_money;
printf ( "現在の栗野の残高は %d 万円です。\n", kurino_account / 10000 );
return 0;
}
$ ./sample-001.exe 現在の栗野の残高は 100 万円です。 栗野の口座に 10 万円の振込を行います。 現在の栗野の残高は 110 万円です。 $
Download : sample-002.c
/*
* 2019/11/08 sample-002.c
*/
/*
* ASCII Code を利用した「文字」の操作
*
* 利用方法
* コンパイル
* cc -c sample-002.c
* リンク
* cc -o sample-002.exe sample-002.c
* 実行
* ./sample-002.exe
*/
#include <stdio.h>
/*
* main
*/
int main( int argc, char *argv[] )
{
char mathematics_record = 'B'; /* 現在の数学の評価は 'B' */
printf ( "数学の前評価の結果は %c でした。\n", mathematics_record );
printf ( "再度確認した所、採点ミスが見付かり、加点した所、グレードが一つ高くなりました。\n" );
/*
*
*/
/* 成績のグレードを高くするために 'B' を 'A' にする */
/*
現実の世界 データ/表現 プログラムの世界
ASICC Code
('B'=66, 'A'=65)
グレードを一段階「高く」する : 'B' -----> 'A'
66 -----> 65 : 1 減らす
*/
mathematics_record = mathematics_record - 1;
/*
*
*/
printf ( "その結果、数学の最終評価は %c になりました。\n", mathematics_record );
return 0;
}
$ ./sample-002.exe 数学の前評価の結果は B でした。 再度確認した所、採点ミスが見付かり、加点した所、グレードが一つ高くなりました。 その結果、数学の最終評価は A になりました。 $
Download : sample-003.c
/*
* 2019/11/08 sample-003.c
*/
/*
* 平面上の「点」の二つの表現銀行口座への振込プログラム
*
* 利用方法
* コンパイル
* cc -c sample-003.c
* リンク ( M_PI,sin,cos を利用するので 「-lm」が必須 )
* cc -o sample-003.exe sample-003.c -lm
* 実行
* ./sample-003.exe
*/
#include <stdio.h>
#include <math.h> /* sin, cos を利用するので.. */
/*
* void print_orthogonal ( char name, double x, double y )
* 直交座標の表示
* char name; 点の名前
* double x; 直交座標の X 座標
* double y; 直交座標の Y 座標
*/
void print_orthogonal ( char name, double x, double y ) {
printf ( "点 %c の直交座標は (%f,%f) です。\n", name, x, y );
}
/*
* void print_polar ( char name, double r, double a )
* 極座標の表示
* char name; 点の名前
* double r; 極座標の動径
* double a; 極座標の偏角
*/
void print_polar ( char name, double r, double a ) {
printf ( "点 %c の極座標は (%f,%f) です。\n", name, r, a );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
/*
点 P : 座標 (2,3)
*/
double P_orthogonal_x = 2.0; /* 点 P の直交座標系の x 座標 */
double P_orthogonal_y = 3.0; /* 点 P の直交座標系の y 座標 */
double P_polar_radius; /* 点 P の極座標系の動径 */
double P_polar_argument; /* 点 P の極座標系の偏角 */
/*
点 Q : 原点から 7 離れており、角度は x 軸に対して 60 度 ( Pi/3 )
*/
double Q_orthogonal_x; /* 点 Q の直交座標系の x 座標 */
double Q_orthogonal_y; /* 点 Q の直交座標系の y 座標 */
double Q_polar_radius = 7.0; /* 点 Q の極座標系の動径 */
double Q_polar_argument = M_PI/3; /* 点 Q の極座標系の偏角 */
/*
* 点 P の表示
*/
print_orthogonal ( 'P', P_orthogonal_x, P_orthogonal_y );
/*
* r = \sqrt{x^2+y^2} なので
*/
P_polar_radius = sqrt ( P_orthogonal_x * P_orthogonal_x + P_orthogonal_y * P_orthogonal_y );
/*
* a = \tan^{-1}{y/x} なので
* cf. http://www1.cts.ne.jp/~clab/hsample/Math/Math2.html
*/
P_polar_argument = atan ( P_orthogonal_y / P_orthogonal_x );
print_polar ( 'P', P_polar_radius , P_polar_argument );
/*
* 点 Q の表示
*/
print_polar ( 'Q', Q_polar_radius, Q_polar_argument );
/*
* x = r \cos{a} なので
*/
Q_orthogonal_x = Q_polar_radius * cos( Q_polar_argument );
/*
* y = r \sin{a} なので
*/
Q_orthogonal_y = Q_polar_radius * sin( Q_polar_argument );
print_orthogonal ( 'Q', Q_orthogonal_x, Q_orthogonal_y );
return 0;
}
$ ./sample-003.exe 点 P の直交座標は (2.000000,3.000000) です。 点 P の極座標は (3.605551,0.982794) です。 点 Q の極座標は (7.000000,1.047198) です。 点 Q の直交座標は (3.500000,6.062178) です。 $
Download : sample-004.c
/*
* 2019/11/08 sample-004.c
*/
/*
* 直交座標で表現されている点 Q から、それと原点に対して対称な点 R を求める
*
* 利用方法
* コンパイル
* cc -c sample-004.c
* リンク
* cc -o sample-004.exe sample-004.c
* 実行
* ./sample-004.exe
*/
#include <stdio.h>
/*
* void print_orthogonal ( char name, double x, double y )
* 直交座標の表示
* char name; 点の名前
* double x; 直交座標の X 座標
* double y; 直交座標の Y 座標
*/
void print_orthogonal ( char name, double x, double y ) {
printf ( "点 %c の直交座標は (%f,%f) です。\n", name, x, y );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
/*
点 P : 座標 (2,3)
*/
double P_orthogonal_x = 2.0; /* 点 P の直交座標系の x 座標 */
double P_orthogonal_y = 3.0; /* 点 P の直交座標系の y 座標 */
double R_orthogonal_x; /* 点 P と原点対称な点 R の x 座標 */
double R_orthogonal_y; /* 点 P と原点対称な点 R の y 座標 */
/*
* 点 P の表示
*/
print_orthogonal ( 'P', P_orthogonal_x, P_orthogonal_y );
/*
* 点 R の計算
*/
/* R の x 座標は P の x 座標の符号を変えた物 */
R_orthogonal_x = - P_orthogonal_x;
/* R の y 座標は P の y 座標の符号を変えた物 */
R_orthogonal_y = - P_orthogonal_y;
/*
* 点 R の表示
*/
print_orthogonal ( 'R', R_orthogonal_x, R_orthogonal_y );
return 0;
}
$ ./sample-004.exe 点 P の直交座標は (2.000000,3.000000) です。 点 R の直交座標は (-2.000000,-3.000000) です。 $
Download : sample-005.c
/*
* 2019/11/08 sample-005.c
*/
/*
* 平面上の点を扱う
*
* 利用方法
* コンパイル
* cc -c sample-005.c
* リンク
* cc -o sample-005.exe sample-005.c -lm
* 実行
* ./sample-005.exe
*/
#include <stdio.h>
#include <math.h> /* sqrt を利用するので必要 (-lm も忘れずに ) */
/*
* void print_point ( double px, double py )
* 「点」を表示する
* double px -- 「点」の x 座標
* double py -- 「点」の y 座標
*/
void print_point ( double px, double py ) {
printf ( "( %f, %f )", px, py );
}
/*
* double point_distance ( double p1x, double p1y, double p2x, double p2y )
* ニ「点」間の距離を返す
* double p1x -- 「始点」の x 座標
* double p1y -- 「始点」の y 座標
* double p2x -- 「終点」の x 座標
* double p2y -- 「終点」の y 座標
*/
double point_distance ( double p1x, double p1y, double p2x, double p2y ) {
double dx = p2x - p1x; /* x 座標の差 */
double dy = p2y - p1y; /* y 座標の差 */
return sqrt ( dx*dx + dy*dy );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
double p1x = 1.0; /* p1 = ( 1.0, 2.0 ) */
double p1y = 2.0;
double p2x = 4.0; /* p2 = ( 4.0, 6.0 ) */
double p2y = 6.0;
printf ( "始点 " );
print_point ( p1x, p1y );
printf ( " と終点 " );
print_point ( p2x, p2y );
printf ( " との距離は %f です。\n", point_distance ( p1x, p1y, p2x, p2y ) );
return 0;
}
$ ./sample-005.exe 始点 ( 1.000000, 2.000000 ) と終点 ( 4.000000, 6.000000 ) との距離は 5.000000 です。 $
Download : sample-006.c
/*
* 2019/11/08 sample-006.c
*/
/*
* 平面上の点の操作
*
* 利用方法
* コンパイル
* cc -c sample-006.c
* リンク
* cc -o sample-006.exe sample-006.c -lm
* 実行
* ./sample-006.exe
*/
#include <stdio.h>
#include <math.h> /* sqrt を利用するので必要 (-lm も忘れずに ) */
/*
* void print_point ( double px, double py )
* 「点」を表示する
* double px -- 「点」の x 座標
* double py -- 「点」の y 座標
*/
void print_point ( double px, double py ) {
printf ( "( %f, %f )", px, py );
}
/*
* void mirror_x_point ( double py )
* x 軸に対し線対称の「点」の y 座標を求める
* double py -- 「点」の y 座標
*/
double mirror_x_point ( double py ) {
return - py;
}
/*
* void mirror_y_point ( double px )
* y 軸に対し線対称の「点」の x 座標を求める
* double px -- 「点」の x 座標
*/
double mirror_y_point ( double px ) {
return - px;
}
/*
* main
*/
int main( int argc, char *argv[] )
{
double p1x = 1.0; /* p1 = ( 1.0, 2.0 ) */
double p1y = 2.0;
double p2x;
double p2y;
/* x 軸に対して線対象 */
printf ( "点 " );
print_point ( p1x, p1y );
printf ( " と x 軸に対して線対称な点は " );
p2x = p1x; /* x 座標は変らない */
p2y = mirror_x_point ( p1y ); /* y 座標のみ計算 */
print_point ( p2x, p2y );
printf ( " となります。\n" );
/* y 軸に線対象 */
printf ( "点 " );
print_point ( p1x, p1y );
printf ( " と y 軸に対して線対称な点は " );
p2x = mirror_x_point ( p1x ); /* x 座標のみ計算 */
p2y = p1y; /* y 座標は変らない */
print_point ( p2x, p2y );
printf ( " となります。\n" );
return 0;
}
$ ./sample-006.exe 点 ( 1.000000, 2.000000 ) と x 軸に対して線対称な点は ( 1.000000, -2.000000 ) となります。 点 ( 1.000000, 2.000000 ) と y 軸に対して線対称な点は ( -1.000000, 2.000000 ) となります。 $
Download : sample-007.c
/*
* 2019/11/08 sample-007.c
*/
/*
* 平面上の点の操作
*
* 利用方法
* コンパイル
* cc -c sample-007.c
* リンク
* cc -o sample-007.exe sample-007.c
* 実行
* ./sample-007.exe
*/
#include <stdio.h>
/*
* void print_point ( double px, double py )
* 「点」を表示する
* double px -- 「点」の x 座標
* double py -- 「点」の y 座標
*/
void print_point ( double px, double py ) {
printf ( "( %f, %f )", px, py );
}
/*
* void mirror_o_point_x ( double px )
* 原点に対し点対称の「点」の x 座標を求める
* double px -- 「点」の x 座標
*/
double mirror_o_point_x ( double px ) {
return - px;
}
/*
* void mirror_o_point_y ( double py )
* 原点に対し点対称の「点」の y 座標を求める
* double py -- 「点」の y 座標
*/
double mirror_o_point_y ( double py ) {
return - py;
}
/*
* main
*/
int main( int argc, char *argv[] )
{
double p1x = 1.0; /* p1 = ( 1.0, 2.0 ) */
double p1y = 2.0;
double p2x;
double p2y;
/* 原点に点対象 */
printf ( "点 " );
print_point ( p1x, p1y );
printf ( " と原点に対して点線対称な点は " );
/* x と y の処理を別々に行う.. */
p2x = mirror_o_point_x ( p1x );
p2y = mirror_o_point_y ( p1y );
print_point ( p2x, p2y );
printf ( " となります。\n" );
return 0;
}
$ ./sample-007.exe 点 ( 1.000000, 2.000000 ) と原点に対して点線対称な点は ( -1.000000, -2.000000 ) となります。 $
Download : sample-008.c
/*
* 2019/11/08 sample-008.c
*/
/*
* 平面上の点の操作
*
* 利用方法
* コンパイル
* cc -c sample-008.c
* リンク
* cc -o sample-008.exe sample-008.c -lm
* 実行
* ./sample-008.exe
*/
#include <stdio.h>
#include <math.h> /* sqrt を利用するので必要 (-lm も忘れずに ) */
/*
* void print_point ( double px, double py )
* 「点」を表示する
* double px -- 「点」の x 座標
* double py -- 「点」の y 座標
*/
void print_point ( double px, double py ) {
printf ( "( %f, %f )", px, py );
}
/*
* void mirror_x_point ( double py )
* x 軸に対し線対称の「点」の y 座標を求める
* double py -- 「点」の y 座標
*/
double mirror_x_point ( double py ) {
return - py;
}
/*
* void mirror_y_point ( double px )
* y 軸に対し線対称の「点」の x 座標を求める
* double px -- 「点」の x 座標
*/
double mirror_y_point ( double px ) {
return - px;
}
/*
* main
*/
int main( int argc, char *argv[] )
{
double p1x = 1.0; /* p1 = ( 1.0, 2.0 ) */
double p1y = 2.0;
double p2x;
double p2y;
/* x 軸に対して線対象 */
printf ( "点 " );
print_point ( p1x, p1y );
printf ( " と x 軸に対して線対称な点は " );
p2x = p1x; /* x 座標は変らない */
p2y = mirror_x_point ( p1y ); /* y 座標のみ計算 */
print_point ( p2x, p2y );
printf ( " となります。\n" );
/* y 軸に線対象 */
printf ( "点 " );
print_point ( p1x, p1y );
printf ( " と y 軸に対して線対称な点は " );
p2x = mirror_x_point ( p1x ); /* x 座標のみ計算 */
p2y = p1y; /* y 座標は変らない */
print_point ( p2x, p2y );
printf ( " となります。\n" );
return 0;
}
$ ./sample-008.exe 点 ( 1.000000, 2.000000 ) と x 軸に対して線対称な点は ( 1.000000, -2.000000 ) となります。 点 ( 1.000000, 2.000000 ) と y 軸に対して線対称な点は ( -1.000000, 2.000000 ) となります。 $
Download : sample-009.c
/*
* 2019/11/08 sample-009.c
*/
/*
* 平面上の点の操作 (構造体の利用例)
*
* 利用方法
* コンパイル
* cc -c sample-009.c
* リンク
* cc -o sample-009.exe sample-009.c
* 実行
* ./sample-009.exe
*/
#include <stdio.h>
/*
* 最初に、直交座標で「点」を表現する型を作ってしまう
*/
typedef struct {
double x; /* 直交座標の x 座標を表すタグ名 */
double y; /* 直交座標の y 座標を表すタグ名 */
} Orthogonal; /* Orthogonal 型の宣言 */
/*
* void print_point ( Orthogonal pt );
* 「点」を表示する
* Orthogonal pt; 直交座標系で表現された「点」の座標
*/
void print_point ( Orthogonal pt ) {
/*
* 構造体の要素は、タグ名を利用して参照できる
*/
printf ( "( %f, %f )", pt.x, pt.y );
}
/*
* Orthogonal mirror_o_point ( Orthogonal pt )
* 原点に対し点対称の「点」を求める
* Orthogonal pt; 直交座標系で表現された「点」の座標
* 値 点対称の「点」を求める
*/
Orthogonal mirror_o_point ( Orthogonal pt ) {
Orthogonal result; /* 返す値を入れる変数 */
result.x = - pt.x; /* 結果の x 座標は、元の x 座標の符号をかえた物 */
result.y = - pt.y;
return result; /* 構造体の値が返せる */
}
/*
* main
*/
int main( int argc, char *argv[] )
{
Orthogonal p1;
Orthogonal p2;
p1.x = 1.0; /* p1 = ( 1.0, 2.0 ) */
p1.y = 2.0;
/* 原点に点対象 */
printf ( "点 " );
/* 構造体は引数で、そのまま渡せる */
print_point ( p1 );
printf ( " と原点に対して点線対称な点は " );
/* 構造体は、値としても取り出せるし、普通に代入もできる */
p2 = mirror_o_point ( p1 );
print_point ( p2 );
printf ( " となります。\n" );
return 0;
}
$ ./sample-009.exe 点 ( 1.000000, 2.000000 ) と原点に対して点線対称な点は ( -1.000000, -2.000000 ) となります。 $
Download : sample-010.c
/*
* 2019/11/08 sample-010.c
*/
/*
* 名前を付けた点
*
* 利用方法
* コンパイル
* cc -c sample-010.c
* リンク
* cc -o sample-010.exe sample-010.c
* 実行
* ./sample-010.exe
*/
#include <stdio.h>
/*
* 最初に、直交座標で「点」を表現する型を作ってしまう
*/
typedef struct {
double x; /* 直交座標の x 座標を表すタグ名 */
double y; /* 直交座標の y 座標を表すタグ名 */
} Orthogonal; /* Orthogonal 型の宣言 */
/*
* 更に、「名前付き」の「点」の型
*/
typedef struct {
char name; /* 点の名前 */
Orthogonal coordinate; /* 点の座標 */
} NPoint;
/*
* void print_point ( Orthogonal pt );
* 「点」を表示する
* Orthogonal pt; 直交座標系で表現された「点」の座標
*/
void print_point ( Orthogonal pt ) {
/*
* 構造体の要素は、タグ名を利用して参照できる
*/
printf ( "( %f, %f )", pt.x, pt.y );
}
/*
* void print_npoint ( NPoint npt );
* 名前付きの「点」を表示する
* NPoint npt; 名前付きの「点」
*/
void print_npoint ( NPoint npt ) {
printf ( "点 %c の直交座標は ", npt.name );
print_point ( npt.coordinate );
printf ( "です。\n" );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
NPoint p; /* 点「P」*/
p.name = 'P'; /* 点「P」の名前は 'P' */
p.coordinate.x = 1.0; /* p.coordinate = ( 1.0, 2.0 ) */
p.coordinate.y = 2.0;
print_npoint ( p ); /* 点「P」を表示 */
return 0;
}
$ ./sample-010.exe 点 P の直交座標は ( 1.000000, 2.000000 )です。 $
Download : sample-011.c
/*
* 2019/11/08 sample-011.c
*/
/*
* 三次元空間内の点の操作 (構造体の利用例)
*
* 利用方法
* コンパイル
* cc -c sample-011.c
* リンク
* cc -o sample-011.exe sample-011.c
* 実行
* ./sample-011.exe
*/
#include <stdio.h>
/*
* 「名前付き」の空間の「点」の型
*/
typedef struct {
char name; /* 点の名前 */
double x; /* 直交座標の x 座標を表すタグ名 */
double y; /* 直交座標の y 座標を表すタグ名 */
double z; /* 直交座標の z 座標を表すタグ名 */
} NPoint3D;
/*
* void print_point3D ( NPoint3D npt );
* 「点」を表示する
* NPoint3D npt; 直交座標系で表現された「点」の座標
*/
void print_point ( NPoint3D pt ) {
printf ( "点 %c の直交座標は ", pt.name );
printf ( "( %f, %f, %f )", pt.x, pt.y, pt.z );
printf ( "です。\n" );
}
/*
* NPoint3D mirror_o_point ( NPoint3D pt )
* 原点に対し点対称の「点」を求める
* NPoint3D pt; 直交座標系で表現された「点」の座標
* 値 点対称の「点」を求める
*/
NPoint3D mirror_o_point ( char newName, NPoint3D pt ) {
NPoint3D result; /* 返す値を入れる変数 */
result.name = newName; /* 名前は新しい物にする */
result.x = - pt.x; /* 結果の x 座標は、元の x 座標の符号をかえた物 */
result.y = - pt.y; /* 以下同様 */
result.z = - pt.z;
return result; /* 構造体の値が返せる */
}
/*
* main
*/
int main( int argc, char *argv[] )
{
NPoint3D p;
NPoint3D q;
p.name = 'P';
p.x = 1.0; /* P = ( 1.0, 2.0, 3.0 ) */
p.y = 2.0;
p.z = 3.0;
/* 原点に点対象 */
print_point ( p );
/* 構造体は、値としても取り出せるし、普通に代入もできる */
q = mirror_o_point ( 'Q', p );
printf ( "これと、原点に対して対称な、" );
print_point ( q );
return 0;
}
$ ./sample-011.exe 点 P の直交座標は ( 1.000000, 2.000000, 3.000000 )です。 これと、原点に対して対称な、点 Q の直交座標は ( -1.000000, -2.000000, -3.000000 )です。 $
Download : sample-012.c
/*
* 2019/11/08 sample-012.c
*/
/*
* N 次元空間内の点の操作 (構造体/配列の利用例)
*
* 利用方法
* コンパイル
* cc -c sample-012.c
* リンク
* cc -o sample-012.exe sample-012.c
* 実行
* ./sample-012.exe
*/
#include <stdio.h>
/*
* 「名前付き」の空間の「点」の型
*/
#define DIM 10 /* 10 次元 */
typedef struct {
char name; /* 点の名前 */
double coordinate[DIM]; /* 直交座標の x 座標を表すタグ名 */
} NPointND;
/*
* void print_pointND ( NPointND npt );
* 「点」を表示する
* NPointND npt; 直交座標系で表現された「点」の座標
*/
void print_point ( NPointND pt ) {
int dim;
printf ( "点 %c の直交座標は ", pt.name );
printf ( "( " );
dim = 0;
while ( dim < DIM ) {
printf ( "%f", pt.coordinate[dim] );
if ( dim < DIM - 1 ) {
printf ( ", " );
}
dim++;
}
printf ( " )" );
printf ( "です。\n" );
}
/*
* NPointND mirror_o_point ( NPointND pt )
* 原点に対し点対称の「点」を求める
* NPointND pt; 直交座標系で表現された「点」の座標
* 値 点対称の「点」を求める
*/
NPointND mirror_o_point ( char newName, NPointND pt ) {
NPointND result; /* 返す値を入れる変数 */
int dim;
result.name = newName; /* 名前は新しい物にする */
dim = 0;
while ( dim < DIM ) {
result.coordinate[dim] = - pt.coordinate[dim];
dim++;
}
return result; /* 構造体の値が返せる */
}
/*
* main
*/
int main( int argc, char *argv[] )
{
NPointND p;
NPointND q;
int dim;
p.name = 'P';
dim = 0;
while ( dim < DIM ) {
p.coordinate[dim] = dim; /* 浮動小数点型に整数値を入れると自動的に変換される */
dim++;
}
/* 原点に点対象 */
print_point ( p );
/* 構造体は、値としても取り出せるし、普通に代入もできる */
q = mirror_o_point ( 'Q', p );
printf ( "これと、原点に対して対称な、" );
print_point ( q );
return 0;
}
$ ./sample-012.exe 点 P の直交座標は ( 0.000000, 1.000000, 2.000000, 3.000000, 4.000000, 5.000000, 6.000000, 7.000000, 8.000000, 9.000000 )です。 これと、原点に対して対称な、点 Q の直交座標は ( -0.000000, -1.000000, -2.000000, -3.000000, -4.000000, -5.000000, -6.000000, -7.000000, -8.000000, -9.000000 )です。 $
/*
* 課題 20191108-01
*
* 20191108 20191108-01-QQQQ.c
*
* 極座標で表現されている点 Q から、それと原点に対して対称な点 R を求める
* 動径(原点との距離 : r) はそのまま
* 角度(動径と x 軸が成す角 : a) が π だけ増える
*/
#include <stdio.h>
#include <math.h> /* sin, cos を利用するので.. */
/*
* void print_polar ( char name, double r, double a )
* 極座標の表示
* char name; 点の名前
* double r; 極座標の動径
* double a; 極座標の偏角
*/
void print_polar ( char name, double r, double a ) {
printf ( "点 %c の極座標は (%f,%f) です。\n", name, r, a );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
/*
点 Q : 原点から 7 離れており、角度は x 軸に対して 60 度 ( Pi/3 )
*/
double Q_polar_radius = 7.0; /* 点 Q の極座標系の動径 */
double Q_polar_argument = M_PI/3; /* 点 Q の極座標系の偏角 */
double R_polar_radius; /* 点 Q と原点対称な点 R の動径 */
double R_polar_argument; /* 点 Q と原点対称な点 R の偏角 */
/*
* 点 Q の表示
*/
print_polar ( 'Q', Q_polar_radius, Q_polar_argument );
/*
* 点 R の計算
*/
/* 対称なので原点から距離は同じ */
R_polar_radius = Q_polar_radius;
/* 180(π)だけ回転 */
R_polar_argument = Q_polar_argument + M_PI; /* M_PI は円周率 */
/*
* 点 R の表示
*/
print_polar ( 'R', R_polar_radius, R_polar_argument );
return 0;
}
/*
* 課題 20191108-02
*
* 20191108 20191108-02-QQQQ.c
*
* 構造体を利用し、平行移動を行う関数を作成する
*/
/*
(x,y) を x 軸方向に dx, y 軸方向 dy だけ平行移動する場合、結果は
(x+dx,y+dy) になる
*/
#include <stdio.h>
/*
* 最初に、直交座標で「点」を表現する型 (Orthogonal) を作ってしまう
* Orthogonal 型は、二つの要素 ( x, y ) からなり、それらの型は double 型
*
* Orthogonal <----> double * double
* \in \in
* p <----> ( p.x, p.y )
*
* 残念ながら、C 言語の型定義機能で出来るのは「形(式)」の定義だけで
* 「意味」の定義はできない
* 「形」に「意味」をつけるのは、「それを扱うプログラム(関数)」の役目
*
* コーディングルール:
* 現実の世界 コンピュータの世界
*
* 平面上の点 P : ( x, y ) Orthogonal 型の pt : ( pt.x, pt.y )
* P の x 座標 : 3 pt.x = 3.0
* P の y 座標 : -2 pt.y = -2.0
*
* [注意]
* Orthogonal 型の pt を「現実の点 P」に対応させ、
* pt.x を点数 P の直交座標系における x 座標
* pt.y を点数 P の直交座標系における y 座標
* とする対応は、「决め(る)事」であり、
* 「必然的に『決る物』」では *ない*
* <反例 1>
* x と y の名前は恣意的な物なので、逆にしても問題はない
* つまり、
* pt.x を点数 P の直交座標系における y 座標
* pt.y を点数 P の直交座標系における x 座標
* と、対応させても、「プログラム上」はなんら問題ない
* (正く動くように作る事ができる)
* <反例 2>
* x と y の値の対応も恣意的な物なので、変更してもよい
* つまり、
* pt.x を点数 P の偏角
* pt.y を点数 P の動径
* 対応させても、「プログラム上」はなんら問題ない
* (正く動くように作る事ができる)
*/
typedef struct {
double x; /* 直交座標の x 座標を表すタグ名(x)とその型(double)の宣言 */
double y; /* 直交座標の y 座標を表すタグ名(y)とその型(double)の宣言 */
} Orthogonal; /* Orthogonal 型の宣言 */
/*
* void print_point ( Orthogonal pt );
* 「点」を表示する
* Orthogonal pt; 直交座標系の座標で表現された「点」
*/
void print_point ( Orthogonal pt ) {
/*
* 構造体の要素は、タグ名を利用して参照できる
*/
printf ( "( %f, %f )", pt.x, pt.y );
}
/*
* Orthogonal shift_point ( Orthogonal pt, double delta_x, double delta_y )
* 点を平行移動する
* Orthogonal pt; 直交座標系の座標で表現された「点」
* double delta_x; x 軸方向の変異 (Δx)
* double delta_y; y 軸方向の変異 (Δy)
* 値 平行移動した結果
*/
Orthogonal shift_point ( Orthogonal pt, double delta_x, double delta_y ) {
Orthogonal result; /* 返す値を入れる変数 */
/* x 軸方向に delta_x だけ平行移動した result.x を得るには、
pt の x 座標に delta_x を加えればよい */
result.x = pt.x + delta_x;
/* y 軸方向に delta_y だけ平行移動した result.x を得るには、
pt の y 座標に delta_y を加えればよい */
/* y も同様 */
return result; /* 構造体の値が返せる */
}
/*
* main
*/
int main( int argc, char *argv[] )
{
Orthogonal p1;
Orthogonal p2;
double dx = 10.0;
double dy = -100.0;
p1.x = 1.0; /* p1 = ( 1.0, 2.0 ) */
p1.y = 2.0;
/* 平行移動 */
printf ( "点 " );
/* 構造体は引数で、そのまま渡せる */
print_point ( p1 );
printf ( " を x 軸方向に %f, y 軸方向に %f 移動した点は ", dx, dy );
/* 構造体は、値としても取り出せるし、普通に代入もできる */
p2 = shift_point ( p1, dx, dy );
print_point ( p2 );
printf ( " となります。\n" );
return 0;
}
#include <stdio.h>
/*
平面上の点は、直交座標で表す。
一つの点に対し、二つの数で対応している
関数を使って、原点対称な点を作る事を考える。
*/
int trans_x ( int x ) { /* x 座標の変換 */
return -x;
}
int trans_y ( int y ) { /* y 座標の変換 */
return -y;
}
void print_orthogonal ( char name, double x, double y ) {
printf ( "点 %c の直交座標は (%f,%f) です。\n", name, x, y );
}
int main(int argc, char *argv[]) {
int px = 2;
int py = 3; /* 一つの点 (P) に対して、二つの数値 (px,py) */
int rx;
int ry;
/*
rx <- - px
ry <- - py
関数を利用して、この操作をおこないたいが、
関数は、一つの値しか返せない
=> 二つ同時に変更する事ができない
=> 二つの関数で実現する。
*/
print_orthogonal ( 'P', px, py );
rx = trans_x ( px );
ry = trans_y ( py );
print_orthogonal ( 'R', rx, ry );
return 0;
}
#include <stdio.h>
/*
平面上の点は、直交座標で表す。
一つの点に対し、構造体をつくって、それに対応させる
関数を使って、原点対称な点を作る事を考える。
*/
typedef struct {
int x;
int y; /* x, y はタグ名となり、構成要素を参照する名前になる */
} Point;
/*
(int, int) -> Point p
( x, y) <-> (p.x, p.y) = p
*/
/*
新しいデータ型 Point がつくられているかのようにみえる
ただし、こうやってつくられた型の変数に関しては、基本、
代入と参照しか操作ができない
=> 必要な演算は、自分で追加するする必要がある
cf. trans
*/
Point trans ( Point p ) { /* 引数にも、返り値にも Point が使える */
/* 基本、単純型が現れて良い所には、Point が使えるようになる */
Point w;
w.x = - p.x;
w.y = - p.y;
return w;
}
void print_orthogonal ( char name, Point p ) {
printf ( "点 %c の直交座標は (%d,%d) です。\n", name, p.x, p.y );
}
int main(int argc, char *argv[]) {
Point p; /* 「点 p」を「Point 型の p」で表現可能になった */
Point r;
p.x = 2;
p.y = 3;
print_orthogonal ( 'P', p );
/*
r.x = trans_x ( p.x );
r.y = trans_x ( p.y );
*/
r = trans ( p );
print_orthogonal ( 'R', r );
return 0;
}
/*
* 2019/11/08 sample-003.c
*/
/*
* 平面上の「点」の二つの表現銀行口座への振込プログラム
*
* 利用方法
* コンパイル
* cc -c sample-003.c
* リンク ( M_PI,sin,cos を利用するので 「-lm」が必須 )
* cc -o sample-003.exe sample-003.c -lm
* 実行
* ./sample-003.exe
*/
#include <stdio.h>
#include <math.h> /* sin, cos を利用するので.. */
/*
* void print_orthogonal ( char name, double x, double y )
* 直交座標の表示
* char name; 点の名前
* double x; 直交座標の X 座標
* double y; 直交座標の Y 座標
*/
void print_orthogonal ( char name, double x, double y ) {
printf ( "点 %c の直交座標は (%f,%f) です。\n", name, x, y );
}
/*
* void print_polar ( char name, double r, double a )
* 極座標の表示
* char name; 点の名前
* double r; 極座標の動径
* double a; 極座標の偏角
*/
void print_polar ( char name, double r, double a ) {
printf ( "点 %c の極座標は (%f,%f) です。\n", name, r, a );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
/*
点 P : 座標 (2,3)
*/
double P_orthogonal_x = 2.0; /* 点 P の直交座標系の x 座標 */
double P_orthogonal_y = 3.0; /* 点 P の直交座標系の y 座標 */
double P_polar_radius; /* 点 P の極座標系の動径 */
double P_polar_argument; /* 点 P の極座標系の偏角 */
/*
点 Q : 原点から 7 離れており、角度は x 軸に対して 60 度 ( Pi/3 )
*/
double Q_orthogonal_x; /* 点 Q の直交座標系の x 座標 */
double Q_orthogonal_y; /* 点 Q の直交座標系の y 座標 */
double Q_polar_radius = 7.0; /* 点 Q の極座標系の動径 */
double Q_polar_argument = M_PI/3; /* 点 Q の極座標系の偏角 */
/*
* 点 P の表示
*/
print_orthogonal ( 'P', P_orthogonal_x, P_orthogonal_y );
/*
* r = \sqrt{x^2+y^2} なので
*/
P_polar_radius = sqrt ( P_orthogonal_x * P_orthogonal_x + P_orthogonal_y * P_orthogonal_y );
/*
* a = \tan^{-1}{y/x} なので
* cf. http://www1.cts.ne.jp/~clab/hsample/Math/Math2.html
*/
P_polar_argument = atan ( P_orthogonal_y / P_orthogonal_x );
print_polar ( 'P', P_polar_radius , P_polar_argument );
/*
* 点 Q の表示
*/
print_polar ( 'Q', Q_polar_radius, Q_polar_argument );
/*
* x = r \cos{a} なので
*/
Q_orthogonal_x = Q_polar_radius * cos( Q_polar_argument );
/*
* y = r \sin{a} なので
*/
Q_orthogonal_y = Q_polar_radius * sin( Q_polar_argument );
print_orthogonal ( 'Q', Q_orthogonal_x, Q_orthogonal_y );
return 0;
}
/*
* 2019/11/08 sample-004.c
*/
/*
* 直交座標で表現されている点 Q から、それと原点に対して対称な点 R を求める
*
* 利用方法
* コンパイル
* cc -c sample-004.c
* リンク
* cc -o sample-004.exe sample-004.c
* 実行
* ./sample-004.exe
*/
#include <stdio.h>
/*
* void print_orthogonal ( char name, double x, double y )
* 直交座標の表示
* char name; 点の名前
* double x; 直交座標の X 座標
* double y; 直交座標の Y 座標
*/
void print_orthogonal ( char name, double x, double y ) {
printf ( "点 %c の直交座標は (%f,%f) です。\n", name, x, y );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
/*
点 P : 座標 (2,3)
*/
double P_orthogonal_x = 2.0; /* 点 P の直交座標系の x 座標 */
double P_orthogonal_y = 3.0; /* 点 P の直交座標系の y 座標 */
double R_orthogonal_x; /* 点 P と原点対称な点 R の x 座標 */
double R_orthogonal_y; /* 点 P と原点対称な点 R の y 座標 */
/*
* 点 P の表示
*/
print_orthogonal ( 'P', P_orthogonal_x, P_orthogonal_y );
/*
* 点 R の計算
*/
/* R の x 座標は P の x 座標の符号を変えた物 */
R_orthogonal_x = - P_orthogonal_x;
/* R の y 座標は P の y 座標の符号を変えた物 */
R_orthogonal_y = - P_orthogonal_y;
/*
* 点 R の表示
*/
print_orthogonal ( 'R', R_orthogonal_x, R_orthogonal_y );
return 0;
}
前回(2019/10/25)の内容
浮動小数点数 (double 型) の応用
ソフトウェア概論的 : C 言語でプログラムを書く
int, char に加えて double が使える
従来(double 型導入前..) でも、「万能」である
double を利用しなくても、「小数点数」を扱う事は可能
# 普通の整数に対して、小数点が、一番右の位の右にある (「123」=>「123.0」)と解釈可能
# (勝手に、「実は、小数点が、右から3番目にある『123456 => 123.456』と思う」ことも可能
=> double を使うと自然に、実数(もどき)が利用できる
=> double という「新しい型」を導入すると(できる事は増えてないが..)
表現が簡単で、間違いもへる
=> 扱えるデータ型が増えると、いろいろな表現が「楽に」なる
「型」:それを操作するときに、自動的に働く機能が付随する事によって、
それの性質が「自動的」に保たれる仕組み
# 「型」=> (数学) 「空間 : 集合とその集合上で利用な可能な演算の対」
数値積分 : 解析学の結果を応用 (解析的に解けない問題でも、近似解が得れる)
switch 構文
整数型(文字型を含む)の式を与え、その式の値によって複数の選択肢の一つを選択
break 文によって、switch 構文の実行を終了(中断)できる
リダイレクション
コマンド実行時に、画面への出力を、
コマンドの後ろに "> ファイル名" とする事によって、
ファイルに切り換える(リダイレクション)する機能
=> プログラムの出力を、ファイルに保存する事により、
出力の内容を再利用できる
# 出力の内容が、ファイルに入っているので、エディタで変更したり、
# 次の処理の入力したりできる
!! リダイレクションを使わなくても、プログラムの出力をファイルに行う方法は、講義でやる予定..
!! リダイレクションをしっていると多くの場合、上の機能は知らなくても済む
!! 上の機能は、プログラムを変更しないといけないが、リダイレクションは、どのプログラムに対しても使える
[まとめ]
講義の目的は、(C 言語で..) プログラムを書けるようにする
プログラム : 命令の組み合わせ
命令の組み合わせ方法 : 順接と条件分岐と、繰り返しの三種類で十分
順接
命令をならべる
関数を作る ( 並べた命令を一つの名前で呼べる )
条件分岐
if 構文
switch - case
繰り返し
再帰呼び出し
while
for
# do ? while
=> 命令を組み合わせる事ができれば、プログラムが書けるので、
命令の組み合わせの仕組みがわかれば、問題
型の導入
できることは、増えないが、「表現」がしやすくなる
「文字列」, char, int, double ...
[今日の話]
データ構造
=> データを組み合わせ作る(構造をもった..)データの「組み合わせ方?」の事
!!! 単にデータを組み合わせるだけでなく、
!!! その組み合わせたデータの操作を含めて、「データ構造」と呼ぶので、
!!! 「組み合わせ方」だけでは、説明として不十分
cf. char, int, double 型の値は、単純型(組み合わせていないデータ型)
プログラムが「役立つ」のは、
プログラムが処理しているデータ(数値)と、現実の情報が対応しているから
=> 現実の情報を、データで表現する
# 現実の情報が「整数、実数、文字」であれば、
# C 言語でも、「int, double, char」で表現できる
# => より、複雑な「情報」は、どうやって、C 言語で表現するか ?
例 : 平面上の点(の位置)という情報を、数値で表現したい
=> 素直に考えると、「一つの数値」では表現できなさそう.. (実際はできるが...)
=> 二つの「数の『組』」で一つの「点」を表現する
# 表現の方法は、いろいろある
# 点の全体の集合と、数値(の組み合わせ)の集合との間に「全単射な関数」があれば、
# それは、「表現」になる
# 平面上の点を、一つの数値で表現する事も可能
# cf.
# P:(x,y) where x, y は 1 未満の正実数
# x = 0.x1x2x3... (無限小数)
# y = 0.y1y2y3... (無限小数)
# z = 0.x1y1x2y2..
# (x,y) <-> z : 全単射
二つの数の組で、平面上の点(の位置)を表現
直交座標系
極座標系
# いずれも、「表現」になっている
# 「点」全体の集合と、二つの実数値の対の間に全単射な写像がある
!!! いろいろな手段がある場合
!!! そのうちの一つを選択するならば、それは、「選択」によって、メリットがほしい
もし、与えられた点に対して、
「原点対称な点を求める」という「情報処理」をする場合
直交座標系 : (x,y) => (-x,-y)
極座標系 : (r,a) => (r,a+π)
表現方法が変われば、
「同じ『機能』」を実現するのに
「異なる『計算(操作)』」
が必要になる
=> 「表現方法の違い」によって、「プログラミング上の違い」が生じる
=> (結果として..) 得失が生まれる
cf.
sample-004.c : 直交座標の場合の原点対称の変換になっている
20191108-01-9999.c : 極座標の場合の原点対称の変換になっている
# 比較して欲いの処理の違い
!! [注意したい事]
!! 事実 : 表現方法が異れば処理が異る
!! =>
!! 表現方法と、操作方法は、対にしないと意味がない
!! => 数学の「空間」と関係
!! => 「表現方法」と「操作方法」の対 => データ構造
!! =>
!! 「じゃあどちらを選べばよいか ?」という疑問をもって欲い
!! <= その時の都合が良い方を選択すると良い
例題 : 平面上の点の表現として、「直交座標系」と「極座標系」のどちらが ?
もし、操作が、平行移動のような場合は、直交座標系、
もし、操作が、(原点中心の...)回転のような場合は、極座標系
になる。
現実の世界の「情報」を表現するために、コンピュータ上のデータ表現と、その操作操作が必要になる
=> まずは、「データ表現」の話から始める。
[構造体]
構造体 : 複数の有限固定な、要素を並べたものを表現する仕組み。
構文
構造体 : struct { 構成要素 }
構成要素 : タグ名とその型をならべたもの
例:
struct { int x; int y; }
typedef と組合せる事によって、既存型と同じよう利用する事ができる
# typedef 構造 型名;
# => 「型名」の型がつくられ、既存型と同じ振舞をする
# => その型の「変数」が作れる
構造体は、複数の要素からなるので、個々の要素をタグ名で個々に独立に参照可能
!! 関数の引数や、返値にも指定できるので、
!! 関数から、複数の値を返すためにも利用可能
命令を組合せる事により、プログラムが作れる
三つの組み合せ (順接、条件分岐、繰り返し)
データを組合せる事により、データ構造が作れる
三つの組み合せ (構造体、共用体、配列)
# データ構造と、それを操作する演算の組 => オブジェクト
# C 言語では、オブジェクトを「間接的」にしか表現できない
# 最近のオブジェクト型言語 (C++, C#, Java, Go, Phyton, etc.. ) では、この「オブジェクト」が直接表現できる
課題プログラム内の「/*名前:ここ*/」の部分を書き換え「/*この部分を完成させなさい*/」の部分にプログラムを追加して、プログラムを完成させます。
Download : 20191108-01.c
/*
* 課題 20191108-01
*
* 20191108 20191108-01-QQQQ.c
*
* 極座標で表現されている点 Q から、それと原点に対して対称な点 R を求める
*/
#include <stdio.h>
#include <math.h> /* sin, cos を利用するので.. */
/*
* void print_polar ( char name, double r, double a )
* 極座標の表示
* char name; 点の名前
* double r; 極座標の動径
* double a; 極座標の偏角
*/
void print_polar ( char name, double r, double a ) {
printf ( "点 %c の極座標は (%f,%f) です。\n", name, r, a );
}
/*
* main
*/
int main( int argc, char *argv[] )
{
/*
点 Q : 原点から 7 離れており、角度は x 軸に対して 60 度 ( Pi/3 )
*/
double Q_polar_radius = 7.0; /* 点 Q の極座標系の動径 */
double Q_polar_argument = M_PI/3; /* 点 Q の極座標系の偏角 */
double R_polar_radius; /* 点 Q と原点対称な点 R の動径 */
double R_polar_argument; /* 点 Q と原点対称な点 R の偏角 */
/*
* 点 Q の表示
*/
print_polar ( 'Q', Q_polar_radius, Q_polar_argument );
/*
* 点 R の計算
*/
/* 対称なので原点から距離は同じ */
/*
** この部分を完成させなさい
*/
/* 180(π)だけ回転 */
/*
** この部分を完成させなさい
*/
/*
* 点 R の表示
*/
print_polar ( 'R', R_polar_radius, R_polar_argument );
return 0;
}
$ ./20191108-01-QQQQ.exe 点 Q の極座標は (7.000000,1.047198) です。 点 R の極座標は (7.000000,4.188790) です。 $
Download : 20191108-02.c
/*
* 課題 20191108-02
*
* 20191108 20191108-02-QQQQ.c
*
* 構造体を利用し、平行移動を行う関数を作成する
*/
#include <stdio.h>
/*
* 最初に、直交座標で「点」を表現する型 (Orthogonal) を作ってしまう
* Orthogonal 型は、二つの要素 ( x, y ) からなり、それらの型は double 型
*
* Orthogonal <----> double * double
* \in \in
* p <----> ( p.x, p.y )
*
* 残念ながら、C 言語の型定義機能で出来るのは「形(式)」の定義だけで
* 「意味」の定義はできない
* 「形」に「意味」をつけるのは、「それを扱うプログラム(関数)」の役目
*
* コーディングルール:
* 現実の世界 コンピュータの世界
*
* 平面上の点 P : ( x, y ) Orthogonal 型の pt : ( pt.x, pt.y )
* P の x 座標 : 3 pt.x = 3.0
* P の y 座標 : -2 pt.y = -2.0
*
* [注意]
* Orthogonal 型の pt を「現実の点 P」に対応させ、
* pt.x を点数 P の直交座標系における x 座標
* pt.y を点数 P の直交座標系における y 座標
* とする対応は、「决め(る)事」であり、
* 「必然的に『決る物』」では *ない*
* <反例 1>
* x と y の名前は恣意的な物なので、逆にしても問題はない
* つまり、
* pt.x を点数 P の直交座標系における y 座標
* pt.y を点数 P の直交座標系における x 座標
* と、対応させても、「プログラム上」はなんら問題ない
* (正く動くように作る事ができる)
* <反例 2>
* x と y の値の対応も恣意的な物なので、変更してもよい
* つまり、
* pt.x を点数 P の偏角
* pt.y を点数 P の動径
* 対応させても、「プログラム上」はなんら問題ない
* (正く動くように作る事ができる)
*/
typedef struct {
double x; /* 直交座標の x 座標を表すタグ名(x)とその型(double)の宣言 */
double y; /* 直交座標の y 座標を表すタグ名(y)とその型(double)の宣言 */
} Orthogonal; /* Orthogonal 型の宣言 */
/*
* void print_point ( Orthogonal pt );
* 「点」を表示する
* Orthogonal pt; 直交座標系の座標で表現された「点」
*/
void print_point ( Orthogonal pt ) {
/*
* 構造体の要素は、タグ名を利用して参照できる
*/
printf ( "( %f, %f )", pt.x, pt.y );
}
/*
* Orthogonal shift_point ( Orthogonal pt, double delta_x, double delta_y )
* 点を平行移動する
* Orthogonal pt; 直交座標系の座標で表現された「点」
* double delta_x; x 軸方向の変異 (Δx)
* double delta_y; y 軸方向の変異 (Δy)
* 値 平行移動した結果
*/
Orthogonal shift_point ( Orthogonal pt, double delta_x, double delta_y ) {
Orthogonal result; /* 返す値を入れる変数 */
/* x 軸方向に delta_x だけ平行移動した result.x を得るには、
pt の x 座標に delta_x を加えればよい */
/*
** この部分を完成させなさい
*/
/* y 軸方向に delta_y だけ平行移動した result.x を得るには、
pt の y 座標に delta_y を加えればよい */
/*
** この部分を完成させなさい
*/
return result; /* 構造体の値が返せる */
}
/*
* main
*/
int main( int argc, char *argv[] )
{
Orthogonal p1;
Orthogonal p2;
double dx = 10.0;
double dy = -100.0;
p1.x = 1.0; /* p1 = ( 1.0, 2.0 ) */
p1.y = 2.0;
/* 平行移動 */
printf ( "点 " );
/* 構造体は引数で、そのまま渡せる */
print_point ( p1 );
printf ( " を x 軸方向に %f, y 軸方向に %f 移動した点は ", dx, dy );
/* 構造体は、値としても取り出せるし、普通に代入もできる */
/*
** この部分を完成させなさい
*/
print_point ( p2 );
printf ( " となります。\n" );
return 0;
}
123 987 456
$ ./20191108-02-QQQQ.exe 点 ( 1.000000, 2.000000 ) を x 軸方向に 10.000000, y 軸方向に -100.000000 移動した点は ( 11.000000, -98.000000 ) となります。 $
Download : 20191108-03.c
/*
* 課題 20191108-03
*
* 20191108 20191108-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; /* 計算結果(差)を收める変数 */
/*
** この部分を完成させなさい
*/
/* 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;
}
$ ./20191108-03-QQQQ.exe 1.200000 ( 2.300000 ) 3.400000 と -9.800000 ( 8.700000 ) 0.000000 の差は 11.000000 ( -6.400000 ) 3.400000 となります。 $