구조체는 정의되면 새로운 자료형처럼 사용할 수 있으며 기본 자료형을 함수에 넘기는 것과 동일한 방법으로 구조체 변수도 사용할 수 있다. 전 절에서 예로 든 Point 구조체를 예로 들어서 두 점간의 거리를 구하는 함수를 작성해 보자. 함수의 이름은 getDist()라고 하고 Point 구조체 변수 두 개를 받아서 double형 값(거리)를 반환해야 한다. 함수 본체는 다음과 같이 작성할 수 있다.


double getDist(Point a, Point b) {
double dx = b.x - a.x;
double dy = b.y - a.y;
double dist = sqrt(dx*dx + dy*dy);
return dist;
}


여기서 함수 헤더를 보면 기본 자료형의 경우와 동일한 방법으로 포인터 변수를 받음을 알 수 있다. 지역변수 a와 b는 Point형 변수이므로 Point구조체의 필드를 사용할 수 있다.


 두 점의 거리를 구하는 전체 프로그램은 다음과 같다.


ex08-06.c

#include <stdio.h>
#include <math.h>

typedef struct {
double x;
double y;
} Point;

double getDist(Point a, Point b);

int main(int argc, char **argv) {
Point a = {1.1, 2.2};
Point b = {3.3, 4.4};

double dist = getDist(a, b); //함수 호출
printf("a = {%f, %f}\n", a.x, a.y);
printf("b = {%f, %f}\n", b.x, b.y);
printf("dist = %f\n", dist);
}

double getDist(Point a, Point b) {
double dx = b.x - a.x;
double dy = b.y - a.y;
double dist = sqrt(dx*dx + dy*dy);
return dist;
}

실행 결과

a = {1.100000, 2.200000}
b = {3.300000, 4.400000}
dist = 3.111270


함수 getDist() 내에서 수학함수 sqrt()를 사용하기 위해서 math.h를 인클루드 시켰다.


 이와 같이 구조체를 정의하는 것은 새로운 자료형을 만드는 것과 같다. 구조체가 한 번 정의되면 기본 자료형과 동일한 방법으로 변수를 생성할 수 있고 함수의 인자로 넘길 수 있으며 함수의 반환값이 될 수도 있다. 예를 들어서 두 점의 좌표를 받아서 Point형 변수를 반환하는 간단한 함수를 작성해 보자.


ex08-07.c

#include <stdio.h>

typedef struct {
double x;
double y;
} Point;

Point getPoint(double, double); //← (1)

int main(int argc, char **argv) {
Point a = getPoint(0,0);
Point b = getPoint(1,1);
printf("a = {%f, %f}\n", a.x, a.y);
printf("b = {%f, %f}\n", b.x, b.y);
}

Point getPoint(double x, double y) {
Point a = {x, y};
return a;
}

실행 결과

a = {0.000000, 0.000000}
b = {1.000000, 1.000000}


이 예에서 getPoint()함수는 Point형 변수를 반환한다. 따라서 함수를 선언할 때 반환형을 (1)과 같이 명시해야 한다. 그리고 함수 내부에서는 Point형 변수를 return해야 한다.

Posted by 살레시오
,

 어떤 함수의 내부에서 호출하는 쪽의 변수를 직접 조작하려면 그 변수의 포인터를 넘겨받으면 된다. 이렇게 변수의 포인터를 넘겨 받아서 호출하는 함수의 변수를 직접 접근하는 방식을 참조에 의한 호출(call-by-reference) 라고 한다. 프로그래밍에서  참조(reference)라는 용어는 주소(address)와 거의 같은 의미로 사용된다.


 다음 예제를 살펴보자.


#include <stdio.h>
void addOne(float *); // 함수 선언

int main()
{
   float fa = 10.0f;
   addOne(&fa);
   printf("fa=%f\n",fa);
}

void addOne(float *fpa){
   *fpa += 1.0f;
}


 이 예제에서 addOne()함수는 float형 포인터를 받아서 fpa에 저장한다. addOne()함수에 &fa 를 넘긴 것을 눈여겨 보아야 한다. 그리고 내부에서 *fpa 값을 1,0만큼 증가시킨다. 하지만 addOne() 함수의 *fpa 는 main()함수의 fa 변수와 같다. 따라서 fa변수를 직접 조작하는 효과가 나는 것이다. 실행 결과를 보면 다음과 같다.


fa=11.000000


함수를 선언할 경우에는 굳이 인자의 이름을 써 줄 필요가 없고 인자의 자료형만 밝혀주면 된다. 위의 예제에서


void addOne(float *fpa);
void addOne(float *);//이렇게 인자의 이름 fpa를 생략해도 됨


라고 addOne()함수를 선언했는데 이 함수의 첫 번째 인자가 float형 포인터(float *)라고 명시한 것이다.


 다른 예로 두 변수의 값을 바꾸는 swap()함수를 작성해 보자.


#include <stdio.h>
void swap(int*, int*); // 함수 선언

int main()
{
   int ia = 11, ib = 22;
   swap(&ia, &ib);
   printf("ia=%d, ib=%d\n", ia, ib);
}

void swap(int *ipa, int *ipb){
   int itmp = *ipa;
   *ipa = *ipb;
   *ipb = itmp;
}


ia = 22, ib = 11


이 예에서 swap()함수는 두 개의 int형 포인터를 받는다. 그리고 그 내부에서 *ipa와 *ipb 값을 교환했는데 이는 main()함수에서 ia, ib를 바꾼 것과 같은 효과를 가진다.


C++ 강좌 전체 목록 >>>


c{c++},n{c0007}

Posted by 살레시오
,