개념/c++

C++ 함수

웅드 2023. 11. 15. 18:24

하나의 특별한 목적의 작업을 수행하기 위해 독립적으로 설계된 코드의 집합이다.

 

호출한 함수에게 값을 되돌려 주는 return value가 있는 함수와 없는 함수로 분류된다.

typeName functionName(parameterList){

    statement(s);
    return value;
} // return 값이 있는 타입

void functionName(parameterList){

    statement(s);
    
} // return 값이 없는 타입

 

functionName 함수는 한개의 매개변수를 갖고있다.

 

함수는 사용자의 필요에 따라 여러개의 매개변수를 가질 수 있고, 

함수를 호출할 때 ,로 값을 분리할 수 있다. 

 

실제로 함수를 호출할 때 사용되는 변수들을 전달인자 혹은 argument라고 한다.

 

const int SIZE=8;

int sumArr(int arr[], int);

int main(){

	int arr[SIZE] = {1,2,4,8,16,32,64,128};
	int sum = sumArr(arr,SIZE); //배열과 사이즈 전달
}
int sumArr(int arr[], int n){ // sumArr이라는 함수는 arr정수형 배열과 n이라는 매개변수를 사용한다.

    int total = 0;
    for(int i=0; i<n; i++)
    	total += arr[i];
    return total;
}

 

여기서 arr = &arr[0] 인데 arr은 arr배열의 첫번째 원소의 주소를 가리킨다.

그래서 아래 코드처럼 포인터 변수를 사용해서 표현해 줄 수도 있다.

const int SIZE=8;

int sumArr(int* arr, int);

int main(){

	int arr[SIZE] = {1,2,4,8,16,32,64,128};
	int sum = sumArr(arr,SIZE); //배열과 사이즈 전달
}
int sumArr(int *arr, int n){ // sumArr이라는 함수는 arr정수형 배열과 n이라는 매개변수를 사용한다.

    int total = 0;
    for(int i=0; i<n; i++)
    	total += arr[i];
    return total;
}
const int SIZE=8;

int sumArr(int* begin, int* end);

int main(){

	int arr[SIZE] = {1,2,4,8,16,32,64,128};
	int sum = sumArr(arr,arr + SIZE); //배열과 사이즈 전달
}
int sumArr(int *begin, int *end){ // sumArr이라는 함수는 arr정수형 배열과 n이라는 매개변수를 사용한다.

    int total = 0;
    int* pt;
    for(pt = begin; pt!=end; pt++)
    	total += *pt;
    return total;
}

 

위 코드처럼 명시한 시작 주소와 끝 주소까지의 배열의 값의 합을 return해준다.

배열을 호출할 때도 배열의 시작 주소와 시작 주소와 배열의 사이즈를 더한 값을 end값으로 주게 됨으로써

배열을 처음부터 끝까지 순회하여 total에 저장하여 출력이 되게 된다.

 

함수를 호출할 때 배열의 시작 주소와 사이즈의 합이 아니라 임의의 인덱스를 더해줌으로써 원하는 부분까지만 그 합의 계산도 가능하다.

 

구조체 변수와 배열은 모두 여러개의 항목을 한 군데 모아서 저장한 다는 공통점을 가지고 있지만

구조체 변수는 기본적으로 단일한 값을 가지는 변수처럼 행동한다.

 

구조체 변수는 배열처럼 배열의 첫번째 인자의 주소를 알려주는 방식이 아닌 함수의 온전한 값으로 전달할 수 있다.

구조체를 함수에 매개변수로 전달하고 리턴값으로 받을 수 있지만 구조체의 규모가 커질 수록 구조체를 복사하는 시간이 걸리고, 메모리에 대한 요구가 높아진다. -> 구조체를 함수에 전달할 때는 구조체의 값이 아닌 구조체의 내용에 접근하는 포인터를 이용하는 방식으로 접근!

struct Time{

	int hours;
    int mins;
};

const int minsPerHr = 60;

Time sum(Time*, Time*);

int main(){

	Time day1 = {5,45};
    Time day2 = {4,55};
    
    Time total  = sum(&day1, &day2);
    
    cout << "이틀간 소요 시간 : "<< endl;
    ShowTime(total);
}

Time sum(Time* t1, Time* t2){
	
    Time total;
    
	total.mins = (t1->mins + t2->mins) % minsPerHr;
    total.hours = t1->hours + t2->hours + ( t1->mins + t2->mins) / minsPerHr;
    
    return total;
}

void showTime(Time t1){
	cout << t1.hours << "시간, " << t1.mins << "분 입니다." << endl; //10시간 40분으로 출력

 

함수는 구조체의 원본이 아닌 복사본을 대상으로 작업한다는 특성 때문에 복사하는 시간이 너무 길어져 구조체를 포인터로써 하면 시간적 성능 저하를 예방할 수 있다.

 

주소에 대해서는 멤버에 접근할 때는 간접 멤버 연산자인 화살표 연산자를 사용하게 된다.

 

재귀함수

자기 자신을 호출하는 함수이다.

void countDown(int);

int main(){

	countDown(5);
}

void countDown(int n){

	cout << " Counting... " << n << endl;
    if(n>0)
    	countDown(n-1);
    cout << n << "번 째 재귀함수" << endl;
}

위 코드는 5 4 3 2 1 0 까지 실행 된 후 함수의 호출이 실행되지 않는다.

 

함수를 지시하는 포인터

함수 역시 메모리에 주소를 가지고 있다.

어떠한 함수에 함수의 주소를 매개변수로 넘겨주는 경우 유용하게 사용할 수 있다.

 

방법

함수의 주소를 얻는다

함수를 지시하는 포인터를 선언한다

함수를 지시하는 포인터를 사용하여 그 함수를 호출한다.

int function(int);

int main(){

	cout << function << endl;
    
    int (*pf)(int);
    pf = function; //이런 방식으로도 함수의 주소를 출력할 수 잇다
    cout << (*pf)(3) << endl; // 3+1 인 4가 출력되게 된다.
}

int function(int n){

	return n+1;
}

이렇게 해주면 함수의 시작 주소값을 출력한다.

반응형