見出し画像

C言語教室 第15回 - 構造体の基本 (回答提出)

こちらの記事の課題回答です。

課題

立体空間における座標を表す構造体を定義してから、それを使って立体空間の2点を結ぶ直線を表す構造体を定義した上で、適当な座標を設定して、その直線の長さを求めなさい。なお、直線の長さは √((x2-x1)^2+(y2-y1)^2+(z2-z1)^2)で求められる。※^は累乗演算子だと解釈してください。右上に小さく書くやつです。

プログラム

three_dimension.h

struct Point3d
{
	int x;
	int y;
	int z;
};

double distance3d(const struct Point3d*const pa, const struct Point3d*const pb);

three_dimension.c

#include <stdlib.h>
#include <math.h>
#include "three_dimension.h"

double distance3d(const struct Point3d*const pa, const struct Point3d*const pb)
{
	int dx;
	int dy;
	int dz;
	int square_distance;
	double distance_ab;

	dx = abs(pa->x - pb->x);
	dy = abs(pa->y - pb->y);
	dz = abs(pa->z - pb->z);
	square_distance = (dx * dx) + (dy * dy) + (dz * dz);
	distance_ab = sqrt((double)square_distance);

	return distance_ab;
}

c14.c

#include <stdio.h>
#include "point3d.h"

int main()
{
	struct Point3d a1 = { 1,  1,  1};
	struct Point3d a2 = {-1, -1, -1};
	struct Point3d b1 = { 2,  2,  2};
	struct Point3d b2 = {-2, -2, -2};
	double distance;

	struct Point3d a;
	struct Point3d b;

	a = a1;
	b = b1;
	distance = distance3d(&a, &b);
	printf("distance of (%d, %d, %d) (%d, %d, %d) is %20.15lf\n", 
			a.x, a.y, a.z,  b.x, b.y, b.z,  distance);

	a = a2;
	b = b2;
	distance = distance3d(&a, &b);
	printf("distance of (%d, %d, %d) (%d, %d, %d) is %20.15lf\n", 
			a.x, a.y, a.z,  b.x, b.y, b.z,  distance);

	a = a1;
	b = b2;
	distance = distance3d(&a, &b);
	printf("distance of (%d, %d, %d) (%d, %d, %d) is %20.15lf\n", 
			a.x, a.y, a.z,  b.x, b.y, b.z,  distance);

	a = a1;
	b = a1;
	distance = distance3d(&a, &b);
	printf("distance of (%d, %d, %d) (%d, %d, %d) is %20.15lf\n", 
			a.x, a.y, a.z,  b.x, b.y, b.z,  distance);

	return 0;
}

実行結果

distance of (1, 1, 1) (2, 2, 2) is    1.732050807568877       
distance of (-1, -1, -1) (-2, -2, -2) is    1.732050807568877
distance of (1, 1, 1) (-2, -2, -2) is    5.196152422706632
distance of (1, 1, 1) (1, 1, 1) is    0.000000000000000

コメント

関数「distance3d」の引数を構造体「Point3d」のポインタにした。

ポインタにしない方法もあるのだけど、コピーが発生する。「コピーの処理時間を嫌う」というのは、もしかしたら前世代的であるのかもしれない。コピーした方が双方に干渉されないので強度が高いのだけども。

さらに、構造体をポインタにするとメンバ変数へのアクセスに「->」を使わなければならなくなる。これもイヤなんだけど。参照「&」があればいいんだけどな。

引数にポインタを指定すると、途端に「const」を付けたくなる。ポインタ引数はデータを共有することになるので、関数がデータを更新するのかしないのかの意思表示が重みを増すことになるので。


いいなと思ったら応援しよう!