언어/C++

함수

빨대도둑 2022. 10. 22. 15:56

「함수」: 특정 작업을 수행하여 그 결과를 반환환 하는 것.

> 미리 만들어진 함수를 사용할 수도 있고, 프로그래머가 함수를 만들 수도 있다. 각 함수는 다른 함수들과 연결될 수 있으며 다른 프로그램에서도 사용될 수 있다. 함수라는 개념을 사용하게 되면 코드의 재활용 가능성, 가독성 증대, 유지 관리의 용이 등 많은 장점이 있다.

int 함수이름(매개면수1, 매개변수2){
	문장들...
    }
    
-> 예
int max(int x, int y){
	if (x>y)
    	return x;
    else
    	return y;
}
  • 함수를 정의할 때는 함수가 반환하는 값의 유형을 가장 먼저 적어준다. 이것을 반환형(return type)이라고 한다.
  • 함수를 정의하는 목적은 함수를 사용하기 위해서이다. 함수를 사용하려면 함수 이름을 써주고 함수가 필요로 하는 데이터를 나열한 다음 세미클론을 붙인다. 함수 호출을 (function call)이라고 한다. 함수가 출력되면 함수 안에 있는 문장들이 순차적으로 실행되며 문장들의 실행이 끝나면 호출한 위치로 돌아간다. 이때 작업의 결과값을 호출한 곳으로 전달할 수 있다. 

 

「함수 원형」: 함수를 사용할 때 미리 컴파일러에게 함수에 대한 정보를 알려주는 것

> 함수 원형은 함수의 이름, 매개변수, 반환형을 함수가 정의되기 전에 미리 한번 써주는 것이다. 함수 원형은 함수 헤더에 세미클론만을 추가한 것과 같다. 다만 원형에서는 매개 변수의 이름을 적지 않아도 되며, 매개변수의 자료형만 적으면 된다. 

> 함수 원형이 필요한 이유는 컴파일러에게 미리 함수에 대한 정보를 주어서 함수의 매개 변수 검사, 반환형 검사 등을 하게 하기 위한 것이다. 만약 함수 원형이 없다면 컴파일러는 함수가 어떤 매개 변수를 가지는지 함수인지 반환형은 무엇인지 알 수 없다. 따라서 컴파일러가 해야 할 중요한 검사를 할 수가 없게 된다. 

> 함수 원형이 주어진다면 함수 정의를 만나기 전에도 함수 호출시, 인수의 유형과 개수가 정확한지, 반환값도 정확하게 사용하고 있는지를 검사할 수 있다. 만약 유형이 일치하지 않다면 오류 메시지를 출력한다. 

#include <stdio.h>

int square(int n); //이렇게 미리 선언하는 것

int main(void) {
	int result;
	result = square(5);
	printf("%d \n", result);
}

int square(int n) {
	return (n * n);
}

 


「인수 전달」

- 값으로 호출하기(call by value): 함수 호출시 인수의 값이 매개 변수로 복사되는 방법

> 함수에 인수 값을 전달한다. 인수의 값이 매개변수로 복사되는 것이다. 또한 함수를 호출할 때 인수를 전달하는 기본적인 방법이다. 매개 변수를 변경한다고 해서 원본 변수에 영향을 주지 않기 때문에 안전성이 있다.

 

- 참조로 호출하기(call by reference): 원본 인수가 함수에 전달되는 방법이다. 매개 변수를 변경하면 원본 인수가 변경된다. 

> 함수 안에서 외부 변수를 변경할 필요가 있으며, 포인터를 사용하지 않고도 참조자를 이용하여 참주에 의한 호출을 구현할 수 있다. 

> 참조로 호출하기가 실행되면 값이 복사가 되는 것이 아니라 원본 변수가 전달된다. 따라서 함수 안에서 매개 변수의 값을 변경하면 매개 변수와 연결된 원본 변수의 값도 변경된다.

- 함수의 매개변수 외에도 참조자를 사용하려면 반드시 선언과 동시에 초기화를 해야 한다. 

 


「중복 함수」: 동일한 이름의 함수를 여러개 정의하는 것

int square(int n) {
	return n * n;
}

double square(double m) {
	return m * m;
}

> 매개 변수의 개수, 타입, 순서를 시그니처라고 하고, 중복함수는 이름은 같지만 시그니처는 달라야 한다. 

> 같은 이름에 매개변수만 변경하여서 함수를 정의하는 것이 가능하다. 

int beta(int n)
double beta(double m)
short beta(short z)
#include <iostream>
using namespace std;

int square(int n) {
	cout << "square(int): " << endl;
	return n * n;
}

double square(double m) {
	cout << "square(double): " << endl;
	return m * m;
}

int main(void) {
	cout << square(5) << endl;
	cout << square(5.0) << endl;
	return 0;
}

 

「디폴트 인수」

> 함수 호출 시에는 모든 변수에 대하여 값을 전달하여야 한다. 만약 인수를 전달하지 않아도 대신 디폴트를 넣어주는 기능이 있는데 이것을 디폴트 인수라 한다.

#include <iostream>
using namespace std;

void display(char c = '*', int n = 10) {
	for (int i = 0; i < n; i++)
		cout << c;
	cout << endl;
}

int main() {
	cout << "\n no factor case: \n";
	display('#');

	cout << "\n factor in case: \n";
	display('#', 5);

	return 0;
}
  1. 함수 호출 display()는 인수가 없으므로 디폴트 값이 사용된다. 즉 *문자가 10개 그려진다
  2. 함수 호출 display('#')는 1개의 인수이다 따라서 매개변수 c에는 '#'이 전달되고 매개변수 n에는 디폴트 값이 10을 가지게 된다.
  3. 함수 호출 display('#',5)는 정상적으로 2개의 인수를 가지고 있으므로 매개변수 c에는 '#'이 전달되고 n에는 5가 전달된다.

 

- 디폴트 사용 시 주의점: 디폴트 인수는 반드시 마지막 인수여야 한다. 

int print(double dvalue=0.0, int prec); //오류를 발생한다.

 


「인라인 함수」

> 함수 호출 시에는 약간의 오버헤드가 발생한다. 

> 함수 호출 전에는 모든 레지스터가 저장되어야 하고 인수들을 복사해야 한다. 함수 호출 후에는 레지스터들이 다시 복구되어야 한다. 만약 아주 간단한 함수라면 함수 안의 문장을 실행하는 시간보다 함수 호출을 준비하는 시간이 더 걸릴 수 있다. 따라서 크기가 작은 함수의 경우에는 차라리 함수 호출을 하지 않고 코드를 복사하여 넣어주는 편이 효율적일 수도 있다. -> 이러한 경우를 대비해서 inline이라고 하는 키워드가 준비되어 있다. 

> 만약 함수 앞에 inline이 붙으면 컴파일러는 함수를 생성하지 않고 함수의 코드를 호출한 곳에 직접 집어넣는다. 이러한 함수를 inline(인라인) 함수라고 한다. 인라인 함수를 만들면 함수 호출 오버헤드가 사라지므로 프로그램이 더 빠르게 실행된다.

inline double water(double w){
	return w+w;
}

 


「문자열」: 문자들의 나열

> string클래스를 이용해서 문자열을 쉽게 저장하고 처리할 수 있다. 

> 클래스란 객체지향의 핵심적인 개념으로 변수와 함수를 묶은 것이다. 클래스 안에 정의도니 변수와 함수를 각각 멤버 변수와 멤버 함수라고 한다.

 

「string 클래스」: 문자열을 나타내기 위하여 작성된 클래스

> string클래스 안에는 문자열 저장 및 처리에 필요한 변수들과 함수들이 정의되어 있다. string 클래스를 사용하게 되면 string 클래스가 자세한 세부 사항을 모두 담당하기 때문에 프로그래머는 편리하게 사용할 수 있다. 

 

「string 객체」

> 클래스는 사용자가 정의하는 자료형의 일종으로 생각할 수 있다. 클래스를 이용하여 변수를 정의할 수 있고, 이것을 객체라고 한다. 

> string 클래스는 string이라는 헤더파일에 정의되어 있다. 따라서 stirng 클래스를 사용하려면  string 헤더파일을 포함시켜야 한다. string 클래스는 std이름 공간에 속해있기 때문에  using 지시어를 사용해서 std 이름공간을 사용하겠다고 명시해야 한다.

#include <iostream>
using namespace std;

 

「문자열의 결합」

> string클래스를 사용하면 '+'를 사용해서 두개의 문자열을 결합할 수 있다.  

> '+' 연산자는 정수를 더하는데 사용되지만 문자열 객체를 더할 대도 사용할 수 있다. '+'연산자의 정의가 피연산자의 자료형에 따라서 다르게 정의된다. 

 

「문자열의 비교」

> string 클래스를 사용하면 ==, >, <, 연산자들이 우리가 기대하는대로 정의되어 있다. string 객체의 경우 연산자들을 사용해서 문자열이 동일한지 검사할 수 있다. 또한 사전적인 순서로 어떤 문자열이 앞에 나오는지도 검사할 수 있다.

stirng s1="water",s2="melon"

if(s1==s2){
	cout<<"same"<<endl;
else
	cout<<"different"<<endl;
}


if(s1<s2){
	cout<<"'s1'is at the front"<<endl;
else
	cout<<"'s2' is at the front"<<endl;
}

 

「입출력」

- >>,<< 연산자를 사용해서 입출력 연산을 구현한다. 만약 cin에서 string객체로 입력하는 경우에 공백 문자가 있으면 입력을 중단한다.

> 한 줄 전체를 읽으려면, getline()함수를 허용한다. getline()는 매개변수로 cin을 받는다. 만약 한 문자씩 읽고자 한다면 cin의 멤버함수인 get()을 사용할 수 있다.  

string i;
cin>>i

string ling;
getling(cin,line);

 

「멤버함수」

> string클래스가 가지고 있는 많은 멤버함수들을 사용할 수 있는데, 객체가 생성된 후에 객체의 멤버함수를 호출하려면 도트(.) 연산자를 사용하면 된다. 

string s="water"
int size=s.size()
멤버함수 설명
s[i] i번째 원소
s.empty s가 비어있으면 true 반환
s.insert(pos,s2) s의 pos위치에 s2를 삽입
s.remove(pos,len) s의 pos위치에 len 만큼 삭제
s.find(s2) s에서 문자열 s2가 발견되는 첫번째 인덱스를 반환
s.find(pos,s2) s의 pos위치부터 문자열 s2가 발견되는 첫번째 인덱스를 반환

 

「문자열 추출」

> 문자열을 추출하려면 배열처럼 [ ] 연산자를 적용하면 된다. 

- line이라는 string객체에서 첫 번째 문자를 꺼내려면 line [0]을 사용하면 된다.

- i 번째 문자를 추출하려면 line[i]라고 사용하면 된다. 

 

 

'언어 > C++' 카테고리의 다른 글

포인터  (0) 2022.11.07
생성자와 접근제어  (0) 2022.10.27
클래스와 객체  (0) 2022.10.27
제어구조, 배열  (0) 2022.10.21
기초사항  (0) 2022.10.19