본문 바로가기
Language/C++

[C++_제 6장] 함수

by 전전긍긍 2021. 11. 23.

본 포스팅은 C++로 시작하는 객체지향 프로그래밍 책을 바탕으로 작성하였습니다.

 

C++로 시작하는 객체지향 프로그래밍

『C++로 시작하는 객체지향 프로그래밍』은 구문보다는 문제 해결에 중점을 두는 문제 구동 방식을 사용한 프로그래밍에 대해 가르치고 있다. 여러 가지 상황에서 문제를 야기한 개념을 사용함

book.naver.com


key point

  • 함수는 재사용이 가능한 코드를 정의하고 코드를 조직화하며 간략화하기 위해서 사용한다.
  • 함수정의
//함수 헤더
int//반환값 유형 max//함수 이름 (int i1, int i2)//매개변수,매개변수는 유형을 각각 선언해야 한다
{
	//함수 몸체
    int result;
    if (i1 > i2)
     result = n1;
    else
     result = n2;
     
    return result; //반환값(결과값을 반환)
}
//함수 호출
int z = max(x,y) //실 매개변수(인수)
  • void함수는 반환하는 값이 없이 함수를 호출한다. (즉, 반환값이 없는 함수)
  • 반환값이 있는 함수 : 값 반환 함수
  • 함수 생성 = 함수 정의 -> 함수 호출 = 함수 실행
  • 기본적으로 인수는 함수를 호출할 때 매개변수로 값에 의해 전달된다. (매개변수 순차 결합)
  • 함수 오버로딩 : 하나의 파일 안에서 이름은 같지만 매개변수 목록만 다른 여러 개의 함수를 정의
  • 함수 원형 : 함수의 내용을 기술하지 않고 함수를 선언하는 것.
  • 기본 인수 : 함수가 기본 인수 값을 가지도록 설정하여 함수가 정의되지 않을 때 기본 값을 출력
  • 인라인 함수 : 함수를 호출하지 않고 인라인 함수를 호출하는 지점에 함수 코드를 복사하는 방식 (함수가 짧은 경우)
#include <iostream>
using namespace std;

inline void f(int month, int year)
{
	cout << "month is " << month << endl;
    cout << "year is " << year << endl;
}

int main()
{
	int month = 10, year = 2008;
    f(month, year); //인라인 함수 호출
    f(9, 2010); //인라인 함수 호출
    
    return 0;
}

//month is 10
//year is 2001
//month is 0
//year is 2010
  • 값에 의한 전달의 제한 요소 : 함수 내에서만 매개변수값 변경(함수 밖에서는 변경X)
  • 값에 의한 전달 -> 참조에 의한 전달
  • 참조에 의한 전달 : 형식 매개변수를 실 매개변수의 별칭으로 동작되게 해 주며, 함수 내부에서 매개변수의 값이 변경되면 인수 값도 변경되도록 해 준다. (매개변수가 원변수의 별칭이 되는 것)
int& r=count;

//datatype& refVar;
//datadype & refVar;
//datadype &refVar;
//모두 동일한 표기법
  • 상수 참조 매개변수 : 매개변수의 값이 변경되지 않도록 컴파일러에 알리기 위해 매개변수를 상수로 지정
int max(const int& num1, const int& num2)

list

더보기

6.1 함수호출 (값 반환 함수)

#include <iostream>
using namespace std;

int max(int num1, int num2)
{
	int result;
	if (num1 > num2)
		result = num1;
	else
		result = num2;

	return result;
}
int main()
{
	int i = 5;
	int j = 2;
	int k = max(i, j);
	cout << "The maximum between " << i << " and " << j << " is " << k << endl;
	return 0;
}

 

6.2 void 함수

#include <iostream>
using namespace std;

void printGrade(double score)
{
	if (score >= 90.0)
		cout << 'A' << endl;
	else if (score >= 80.0)
		cout << 'B' << endl;
	else if (score >= 70.0)
		cout << 'C' << endl;
	else if (score >= 60.0)
		cout << 'D' << endl;
	else 
		cout << 'F' << endl;
}

int main()
{
	cout << "Enter a score: ";
	double score;
	cin >> score;

	cout << "The grade is ";
	printGrade(score);

	return 0;
}
//Enter a score: 97
//The grade is A

 

6.5 코드 모듈화 - 소수인지 아닌지

#include <iostream>
#include <iomanip>
using namespace std;

bool isPrime(int number)
{
	for (int divisior = 2; divisior <= number / 2; divisior++)
	{
		if (number % divisior == 0)
		{
			return false;
		}
	}
	return true;
}

void printPrimeNumbers(int numberOfPrimes)
{
	const int NUMBER_OF_PRIMES = 50; //출력할 소수의 개수
	const int NUMBER_OF_PRIMES_PER_LINE = 10; //한 줄에 10개씩 출력
	int count = 0; //소수의 개수
	int number = 2; //소수인지를 검사할 숫자

	while (count < numberOfPrimes)
	{
		if (isPrime(number))
		{
			count++;

			if (count % NUMBER_OF_PRIMES_PER_LINE == 0)
			{
				cout << setw(4) << number << endl;
			}
			else
				cout << setw(4) << number;
		}
		number++;
	}
}

int main()
{
	cout << "The first 50 prime numbers are \n";
	printPrimeNumbers(50);

	return 0;
}
/*
The first 50 prime numbers are
   2   3   5   7  11  13  17  19  23  29
  31  37  41  43  47  53  59  61  67  71
  73  79  83  89  97 101 103 107 109 113
 127 131 137 139 149 151 157 163 167 173
 179 181 191 193 197 199 211 223 227 229
*/

 

6.6 함수 오버로딩

#include <iostream>
using namespace std;

int max(int num1, int num2)
{
	if (num1 > num2)
		return num1;
	else
		return num2;
}

double max(double num1, double num2)
{
	if (num1 > num2)
		return num1;
	else
		return num2;
}

double max(double num1, double num2, double num3)
{
	return max(max(num1, num2), num3);
}

int main()
{
	cout << "The maximum between 3 and 4 is " << max(3, 4) << endl;
	cout << "The maximum between 3.0 and 4.0 is " << max(3.0, 4.0) << endl;
	cout << "The maximum between 3.0, 5.4 and 10.14 is " << max(3.0, 5.4, 10.14) << endl;

	return 0;
}

/*
The maximum between 3 and 4 is 4
The maximum between 3.0 and 4.0 is 4
The maximum between 3.0, 5.4 and 10.14 is 10.14
*/

 

6.11 지역변수, 전역변수

#include <iostream>
using namespace std;

void t1();
void t2();

int main()
{
	t1();
	t2();

	return 0;
}

int y; //전역변수 (기본값이 0)

void t1()
{
	int x = 1; //지역변수
	cout << "x is " << x << endl;
	cout << "y is " << y << endl;
	x++; //1
	y++; //0
}

void t2()
{
	int x = 1;
	cout << "x is " << x << endl; //1
	cout << "y is " << y << endl;//1
}

/*
x is 1
y is 0
x is 1
y is 1
*/

 

6.12 정적 지역 변수

#include <iostream>
using namespace std;

void t1();

int main()
{
	t1();
	t1();

	return 0;
}

void t1()
{
	static int x = 1; //정적 지역 변수
	int y = 1;
	x++;
	y++;
	cout << "x is " << x << endl; 
	cout << "y is " << y << endl; 
}

/*
x is 2
y is 2
x is 3
y is 2
*/

 

6.17 참조에 의한 전달

#include <iostream>
using namespace std;

void swqp(int& n1, int& n2)
{
	cout << "\tInside the swap function" << endl;
	cout << "\tBefore swapping n1 is " << n1 << " n2 is " << n2 << endl;

	int temp = n1;
	n1 = n2;
	n2 = temp;

	cout << "\tAfter swapping n1 is " << n1 << " n2 is " << n2 << endl;
}

int main()
{
	int num1 = 1;
	int num2 = 2;

	cout << "Before invoking the swap function, num1 is " << num1 << " and num2 is " << num2 << endl;

	swqp(num1, num2);

	cout << "After invoking the swap function, nm1 is " << num1 << " and num2 is " << num2 << endl;

	return 0;
}

/*
Before invoking the swap function, num1 is 1 and num2 is 2
        Inside the swap function
        Before swapping n1 is 1 n2 is 2
        After swapping n1 is 2 n2 is 1
After invoking the swap function, nm1 is 2 and num2 is 1

*/

 

6.18 예제: 16진수를 10진수로 변환

#include <iostream>
#include <string> //string
#include <cctype> //toupper
using namespace std;


int hex2Dex(const string& hex);
int hexCharToDemical(char ch);

int main()
{
	cout << "16진수를 입력해주세요: ";
	string hex;
	cin >> hex;

	cout << "The demical value for hex number " << hex 
		<< " is "  <<  hex2Dex(hex) << endl;

	return 0;
}

int hex2Dex(const string& hex)
{
	int descimalValue = 0;
	for (unsigned i = 0; i < hex.size(); i++)
		descimalValue = descimalValue * 16 + hexCharToDemical(hex[i]);

	return descimalValue;
}

int hexCharToDemical(char ch)
{
	ch = toupper(ch);
	if (ch >= 'A' && ch <= 'F')
		return 10 + ch - 'A';
	else
		return ch - '0';
}

/*
16진수를 입력해주세요: af71
The demical value for hex number af71 is 44913
*/

Quiz

 

section 6.3-6.4

void 함수는 값을 반환하지 않지만 void함수에서 정상적인 제어 흐름을 빠져 나가기 위해 유용하게 사용힐 수 있다.. 함수의 실행을 끝내거나 함수의 호출자로 되돌아가기 위해 return문을 사용할 수 있다.


section 6.13 Local, Global, and Static Local Varialbes

정적 지역 변수(static) : 다음 호출에서 지역 변수를 다시 사용하기 위해 지역 변수에 저장된 값을 유지


Section 6.14 Passing Arguments by References

x가 f함수에 들어가고 그 후 y도 함수에 들어간다.


프로그래밍 실습

 

6.2 정수의 자릿수 더하기

#include <iostream>
using namespace std;

int sumDigits(long n);

int main()
{
	cout << "숫자를 입력하세요: ";
	int num;
	cin >> num;

	cout << num << " 의 각 자리의 합은 " << sumDigits(num) << "입니다" << endl;

	return 0;
}

int sumDigits(long n)
{
	int sum = 0;
	int temp = abs(n);

	while (temp != 0)
	{
		sum += temp % 10;
		temp = temp / 10;
	}

	return sum;
}

/*
숫자를 입력하세요: 98
98 의 각 자리의 합은 17입니다
*/

 

6.4 정수를 역으로 출력

#include <iostream>
using namespace std;

void reverse(int number);

int main()
{
	cout << "숫자를 입력하세요: ";
	int number;
	cin >> number;

	cout << number << "의 역순은" << endl;
	reverse(number);

	return 0;
}

void reverse(int number)
{
	int sum = 0;
	while (number != 0)
	{
		sum = number % 10 + sum * 10;
		number = number / 10;
	}
	cout << sum << endl;
}
/*
숫자를 입력하세요: 1795
1795의 역순은
5971
*/

 

6.5 세 숫자 정렬

코드를 짜긴 짰는데 너무 비효율적인건가 생각이 든다. 더 좋은 방법이 떠오르지 않는다.

비효율적이라고 생각하는 이유는 코드의 길이가 너무 길다. 더 짧게 하고 싶다.

*배열을 사용할 수 있지만 함수까지 배운거라고 가정을 하였을 때, 풀 수 있는 범위를 한정하였다.

//방법 1. 반복문 사용
#include <iostream>
using namespace std;

void displaySortedNumbers(double num1, double num2, double num3);

int main()
{
	cout << "세 정수를 입력해주세요: ";
	double n1, n2, n3;
	cin >> n1 >> n2 >> n3;

	displaySortedNumbers(n1, n2, n3);

	return 0;
}

void displaySortedNumbers(double num1, double num2, double num3)
{
	double max = 0;
	double min = 0;
	double center = 0;
	
	//최댓값
	for (int i = 0; i < 3; i++)
	{
		if (max < num1)
			max = num1;
		else if (max < num2)
			max = num2;
		else if (max < num3)
			max = num3;
	}

	min = max;
    
	//최솟값
	for (int i = 0; i < 3; i++)
	{
		if (min > num1)
			min = num1;
		else if (min > num2)
			min = num2;
		else if (min > num3)
			min = num3;
	}

	//중앙값
	if (num1 != max && num1 != min)
		center = num1;
	else if (num2 != max && num2 != min)
		center = num2;
	else if (num3 != max && num3 != min)
		center = num3;

	cout << min << " " << center << " " <<  max << endl;
}

/*
세 정수를 입력해주세요: 2.7 55 16
2.7 16 55
*/
//방법 2. 함수 사용
#include <iostream>
using namespace std;

void displaySortedNumbers(double num1, double num2, double num3);
double maximumNumbers(double num1, double num2, double num3);
double minimumNumbers(double num1, double num2, double num3);

int main()
{
	cout << "세 정수를 입력해주세요: ";
	double n1, n2, n3;
	cin >> n1 >> n2 >> n3;

	displaySortedNumbers(n1, n2, n3);

	return 0;
}

void displaySortedNumbers(double num1, double num2, double num3)
{
	double max = maximumNumbers(num1, num2, num3);
	double min = minimumNumbers(num1, num2, num3);
	double center = 0;

	if (num1 != max && num1 != min)
		center = num1;
	else if (num2 != max && num2 != min)
		center = num2;
	else if (num3 != max && num3 != min)
		center = num3;

	cout << min << " " << center << " " <<  max << endl;
}

//max
double maximumNumbers(double num1, double num2, double num3)
{
	if (num1 > num2 && num1 > num3)
		return num1;
	if (num2 > num1 && num2 > num3)
		return num2;
	if (num3 > num1 && num3 > num2)
		return num3;
}

//min
double minimumNumbers(double num1, double num2, double num3)
{
	if (num1 < num2 && num1 < num3)
		return num1;
	if (num2 < num1 && num2 < num3)
		return num2;
	if (num3 < num1 && num3 < num2)
		return num3;
}

방법 2는 이분의 블로그의 코드를 참고했다. 나와는 다른 방법이고 함수를 이용하는 건 생각해봤지만 단순 if문으로 코드를 짠다는건 생각치도 못했다. (내가 함수를 이용하지 않는 이유는 코드의 길이가 길어질 거 같다고 생각했고 문제에서 void함수의 헤더를 사용하라고 제시했기 때문)

https://blog.naver.com/liberty914/220280925367 

 

C언어 Chapter 9-3. 함수 문제 3. 세 개의 정수를 입력받고, 가장 큰수와 작은수를 반환하는 함수를

안녕하세요? Rex 입니다 ^_^/ 함수 문제 3. 세 개의 정수를 입력받고, 가장 큰 수와 , 가장 작은 수를 반...

blog.naver.com

 

더 쉽게 푸는 방법을 알아내었다.

더 쉽게 푸는 방법은 "참조에 의한 전달"을 이용하는 것이다.

//방법 3. 단순 if문, 참조에 의한 전달
#include <iostream>
using namespace std;

void displaySortedNumbers(double& num1, double& num2, double& num3);

int main()
{
	cout << "세 정수를 입력해주세요: ";
	double num1, num2, num3;
	cin >> num1 >> num2 >> num3;

	displaySortedNumbers(num1, num2, num3);
	cout << "오름차순 정렬 : " << num1 << " " << num2 << " " << num3 << endl;
	return 0;
}

void displaySortedNumbers(double& num1, double& num2, double& num3)
{
	if (num1 > num3)
	{
		double temp = num1;
		num1 = num3;
		num3 = temp;
	}

	if (num1 > num2)
	{
		double temp = num1;
		num1 = num2;
		num2 = temp;
	}

	if (num2 > num3)
	{
		double temp = num2;
		num2 = num3;
		num3 = temp;
	}

}

/*
세 정수를 입력해주세요: 9 4 8
오름차순 정렬 : 4 8 9
*/

 

6.6  패턴 출력

* 공백 반복문과 숫자 반복문을 따로 작성하는 것이 포인트

#include <iostream>
using namespace std;

void displayPattern(int n)
{
  for (int row = 1; row <= n; row++)
  {
    // Print spaces
    for (int i = row; i < n; i++)
      cout << "  ";

    // Print numbers
    for (int i = row; i >= 1; i--)
      cout << " " << i;

    cout << endl;
  }
}

int main()
{
  displayPattern(7);

  return 0;
}
/*
             1
           2 1
         3 2 1
       4 3 2 1
     5 4 3 2 1
   6 5 4 3 2 1
 7 6 5 4 3 2 1
*/

 

6.16  0과 1의 행렬 출력

//6.16 0과 1의 행렬 출력
#include <iostream>
#include <ctime> //time 함수
#include <cstdlib> //rand와 srand 함수
using namespace std;

void printMatirx(int n); //함수 원형

int main()
{
	cout << "Enter n : ";
	int n;
	cin >> n;

	printMatirx(n);
	return 0;
}

void printMatirx(int n)
{
	//랜덤을 위한 시드 설정, srand(unsigned int) : rand()의 시드값 설정
	//프로그램에서 한 번만 호출
	srand((unsigned int)time(0));

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			int row = rand() % 2;
			cout << " " << row;
		}
		cout << endl;
	}	
}

/*
Enter n : 3
 1 1 0
 0 1 0
 1 1 0
 */

* for문 안에 srand() 함수를 넣었는데 이상하게 똑같은 값만 나와서 이상했다. 그 이유를 찾아보니까 srand(time())은 초 단위로 시드를 바꾸는데, 고작 for문 몇개의 반복은 cpu에게 초 단위를 셀 가치가 없을 만큼 빨라서 같은 값이 나오는 거였다.

(아래 블로그 포스팅을 참조하면 더 빠르게 이해할 수 있다.)

https://blog.naver.com/njw1204/221079839989

 

C언어/C++ rand 함수(랜덤 함수) 사용시 주의해야 할 점 (srand 함수 관련)

시작하기 앞서 C++ 레퍼런스의 rand 함수 정보를 보고 갑시다. rand 함수는 0이상 RAND_MAX이하의 ...

blog.naver.com