728x90
반응형

< 함수 이해하기 >

 

> 함수 (Function) 의 개요

1) 함수란?

(1) 반복되어 실행될 명령문들을 모아 놓은 모듈

(2) 소스코드의 중복 회피

(3) 소스코드의 단순화

 

2) 함수의 종류

- 라이브러리(Library) 함수 : C언어 컴파일러에서 제공하는 함수

- 사용자 정의(User defined) 함수 : 프로그래머가 만들어서 사용하는 함수

 

3) main( ) 함수

- 프로그램이 시작되면 호출되는 첫 번째 함수

 

4) 라이브러리 함수

(1) include 문으로 라이브러리를 지정함

(2) 라이브러리에 정의된 함수를 호출하여 사용

#include <stdio.h>	// Library

int main()
{
	int a;
	printf("Hello Wordld\n");	//input print
	scanf_s("%d", &a);	//output scanf

	return 0;
}

 

5) 사용자 정의 함수

(1) 사용자 정의 함수의 구조

// 반환값이 있는 경우
int test(int a, int b)
{
	int c = a * b;

	return c;
}

// 반환값이 없는 경우
void test2(int x, int y)
{
	int z = x + y;

	return;	// 생략가능
}

 ***

int : 함수의 반환값 자료형

test : 함수이름

(int a, int b) : 입력 매개 변수

int c = a * b : 함수 본체

return c : 반환문

 

(2) 반환값 자료형 규칙

- 반환값이 있는 경우 : return 문에서 반환하는 값의 자료형과 일치해야 함

- 반환값이 없는 경우 : void 로 정의하고, return 문을 생략할 수 있음

 

 

> 함수 사용하기

1) 사용자 정의 함수 호출

(1) 함수의 호출 과정

#include <stdio.h>

int main()
{
	int result = 0;
	result = test(10, 5);
	printf("%d", result);

	return 0;
}

int test(int a, int b)
{
	int c = a * b;

	return c;
}

 

(2) 인수와 매개변수

- 인수 : 함수를 호출할 때 전달하는 값

- 매개변수 : 함수를 호출할 때 전달되는 인수의 값을 저장하는 변수

- 인수와 매개변수는 나열한 순서대로 1:1 매칭

- 인수와 매개변수는 자료형이 일치하여야 함

 

2) 인수 전달 방법

(1) 인수 전달 방법의 종류

- 값에 의한 호출 (call by value)

: 인수의 값이 전달됨

#include <stdio.h>

int test(int a, int b)
{
	a += 10;
	b += 10;

	return a + b;
}

int main()
{
	int result = 0;
	int x = 10, y = 5;
	result = test(x, y);
	
	printf("%d, %d", x, y);	// 10, 5

	return 0;
}

* 인수의 값만 매개변수에 전달됨

 

- 참조에 의한 호출 (call by reference)

: 인수의 포인터(메모리 주소값)가 전달됨

#include <stdio.h>

int test(int* a, int* b)
{
	*a += 10;
	*b += 10;

	return *a + *b;
}

int main()
{
	int result = 0;
	int x = 10, y = 5;
	result = test(&x, &y);

	printf("%d, %d", x, y);	// 20, 15

	return 0;
}

* x 와 y의 주소값을 test 함수의 포인터 변수로 선언된 매개변수 a 와 b로 전달

 

3) 함수의 원형 (prototype)

- 함수의 원형이란

: 함수를 정의하기 전에 함수가 존재한다는 것을 선언하는 것

 

- 함수의 원형 선언 방법

: 함수의 머리 부분을 동일하게 선언하고, 세미콜론(;)을 마지막에 붙여줌

#include <stdio.h>

int test(int a, int b);	// 함수의 머리부분에 ( ; ) 세미콜론 : 함수의 원형

/*
code
*/

int test(int a, int b)	// 함수 머리부분
{
						// 함수 본체부분
}

- 함수의 원형 선언 여부

** 함수의 원형을 선언해야 하는 경우 : 함수 호출 에 함수를 정의하는 경우

#include <stdio.h>

void test(int a, int b);	// 함수 원형 반드시 선언
int main()
{
	int x, y;
	
	test(x, y);		// 함수 호출
}


void test(int a, int b)	// 함수 정의
{
						
}

** 함수의 원형을 선언하지 않아도 되는 경우 : 함수 호출 에 함수를 정의하는 경우

#include <stdio.h>

// void test(int a, int b);	// 함수 원형 선언 안해도됨

void test(int a, int b)	// 함수 정의
{
						
}

int main()
{
	int x, y;

	test(x, y);		// 함수 호출
}

 

 

> 함수 기본 실습

#include <stdio.h>

// 함수 선언
int add(int a, int b)	// Call by value (값에 의한 호출) 덧셈 함수
{
	int ret = 0;
	a += 10;
	b += 10;
	ret = a + b;
	return ret;
	// return a + b; // 직접 수식을 적어도 됨
}

void subtract(int a, int b)	// 반환값이 없는 함수, 뺄셈 함수
{
	printf("%2d - %2d = %d\n", (a * 2), (b * 2), (a * 2) - (b * 2));
}

int multiply(int* a, int* b)	// Call by reference (참조에 의한 호출), 곱셈함수
{
	int ret = 0;
	*a += 10;
	*b += 10;
	ret = *a * *b;
	return ret;
}

void printTitle()
{
	printf("함수 기본 실습\n");
}

void printString(char* a)
{
	printf("%s\n", a);
}

void operation(int a, char op, int b);	// 함수 호출 main 함수 위에 위치

int main()	// main 함수
{
	int x = 10, y = 5, result = 0;
	printTitle();

	printString("덧셈계산");
	result = add(x, y);
	printf("x = %d, y = %d, result = %d\n", x, y, result);

	printString("뺄셈계산");
	subtract(x, y);	// 위 덧셈과 달리 반환 result 변수가 없기 때문에 바로 출력

	printString("곱셈계산");
	result = multiply(&x, &y);
	printf("x = %d, y = %d, result %d\n", x, y, result);

	printString("사칙연산 함수 호출");
	operation(x, '+', y);
	operation(x, '-', y);
	operation(x, '*', y);
	operation(x, '/', y);

	return 0;
}

void operation(int a, char op, int b)	// 사칙연산 함수
{
	int result = 0;
	
	switch (op)
	{
	case '+':
		result = a + b;
		break;
	case '-':
		result = a - b;
		break;
	case '*':
		result = a * b;
		break;
	case '/':
		result = a / b;
		break;
	}
	printf("%d %c %d = %d\n", a, op, b, result);

}

 


< 함수 활용하기 >

 

> 변수의 사용 범위

1) 지역 변수

(1) 코드 블록 (중괄호( { } )) 내에서만 사용가능

- 코드 블록 실행이 완료되면 할당된 메모리가 해제됨

- 자동 변수 또는 동적 변수라고 할 수 있음

- 변수 선언 시 auto keyword 가 생략 되어 있음

 

(2) 함수의 매개변수는 지역 변수임

void test(int a, int b)
{
// 매개 변수의 사용 범위
}

 

(3) 지역 변수 선언 후 초기화하여 사용해야 함

int main()
{
	int a;	// uninitialized local variable 'a' used → int a = 0;
	printf("%d", a);
	return 0;
}

(4) 지역 변수 이름의 중복

- 서로 다른 코드 블록에 선언된 변수 이름은 중복이 가능함

- 지역 변수를 사용하는 코드 블록에 선언된 변수가 우선됨

int main()
{
	int a = 10;
	printf("%d\n", a);	// 바깥쪽 코드: 10
	if (a == 10)
	{
		int a = 20;
		printf("%d\n", a);	// 안쪽 코드: 20
	}
}

 

2) 전역 변수

(1) 소스 파일 전체에서 사용 가능

- 함수 외부에 선언함

- 프로그램이 시작될 때 메모리가 할당되고, 프로그램이 종료될 때 메모리가 해제됨

- 전역 변수를 선언하면 자동으로 0 또 NULL 로 초기화 됨

#include <stdio.h>

int a; // 전역변수 선언(아래 서로 다른 함수에서 동일한 변수 가짐)

void test()
{
	a += 20;
	printf("%d\n", a);
}

int main()
{
	a += 10;
	printf("%d\n", a);	// 10 출력
	test();	// 30 출력

	return 0;
}

 

(2) 전역 변수와 지역 변수 이름 중복

- 지역 변수가 우선됨

#include <stdio.h>

int a;	// 전역변수 a (지역 변수 a와 중복)

void test()
{
	a += 20;
	printf("%d\n", a);
}

int main()
{
	int a = 10;	// 지역변수 a
	printf("%d\n", a);	// 전역변수보다 우선되어 10 출력
	test();	// 전역변수 a가 대입되어 20 출력

	return 0;
}

 

3) 외부 변수와 외부 함수

- 하나의 프로젝트 내부에 두 개 이상의 소스파일에서 공유하는 변수 또는 함수

#include <stdio.h>

int a;	// 외부 전역변수 연결 보냄
extern void test();	// 외부함수 연결 받음

int main()
{
	a = 10;
	printf("%d\n", a);	// 10 출력
	test();

	return 0;
}
#include <stdio.h>

extern int a;	// 외부 전역변수 연결 받음

void test()	// 외부 함수 연결 보냄
{
	a += 20;
	printf("%d\n", a);

}

 

4) 레지스터 (register) 변수

 CPU 의 레지스터 저장공간을 사용하는 변수

- 실행 속도가 빠름

- 지역 변수로만 선언 가능

- 포인터 및 주소 참조 연산자 (&) 사용 못함

- register 키워드 사용하여 선언

#include <stdio.h>

int main()
{
	register int a = 10;
	printf("%d\n", a);

	return 0;
}

 

5) 정적 (static) 변수

(1) 정적 지역 변수

- 지역 변수 선언 시 static 키워드 지정

- 변수가 선언된 코드 블록 내부에서만 사용 가능

- 프로그램 실행 시 메모리 할당, 프로그램 종료 시 메모리 해제

- 자동 초기화 됨

- 변수 선언과 동시에 초기화하는 명령문은 한번만 실행됨

#include <stdio.h>

void counter()
{
	static int cnt = 0;	// 첫번째 호출 시 한번만 실행됨
	cnt += 10;	// 두번째 호출부터는 해당 증감식만
	printf("%d\n", cnt);
}

int main()
{
	counter();	// 10
	counter();	// 20
	counter();	// 30
}

 

(2) 정적 전역 변수

- 전역 변수 선언 시  static 키워드 지정

- 정적 전역 변수가 선언된 소스 파일에서만 사용

- 외부 변수로 사용하지 못함

- 자동 초기화 됨

int a;	// 외부 변수 연결 보냄 가능
static int b;	// 외부 변수 연결 보냄 불가
int main(){
}
extern int a;	// 외부 변수 연결 받음 가능
extern int b;	// 외부 변수 연결 받음 불가능
void test(){
}

 

(3) 정적 함수

- 함수 선언 시 static 키워드 지정

- 정적 함수가 선언된 소스 파일에서만 사용

- 외부 함수로 사용하지 못함

int set ();	// 외부 함수 연결 가능
static int get();	// 외부 함수 연결 불가능
int set() {...}
static int get() {...}
extern int set();	// 외부 함수 연결 가능
extern int get();	// 외부 함수 연결 불가능
void test(){
}

 

> main( ) 함수와 함수 포인터

1) main ( ) 함수

(1) main( ) 함수의 매개변수

- 첫 번째 매개변수 : 두 번째 매개변수 배열 요소의 개수

- 두 번째 매개변수 : 문자열 포인터 배열

#include <stdio.h>

int main(int argc, char* argv[])
// argc 문자열 포인터 배열의 크기
// 배열의 문자열을 지정하여 프로그램 실행
{
	// 첫번째 매개변수 argc 변수 값 화면 출력
	printf("argc = %d\n", argc);
	// argv의 내용을 출력하기 위해 argc 값만큼 반복
	for (int i = 0; i < argc; i++) {
		printf("argv[%d] = %s\n", i, argv[i]);
	}	// argv 배열 내용을 화면에 출력하면 main 함수의 매개변수 내용을 모두 화면에 출력
	return 0;	// 프로그램이 정상적으로 종료되었다 의미 운영체제에 전달
}

/*
argc = 1
argv[0] = C:\Users\mnkyu\Desktop\test\teess\x64\Debug\teess.exe
*/

(2) main ( ) 함수의 인수 지정하기

- 비주얼스튜디오 [디버그] - [속성] 실행

- 명령프롬프트에서 [프로젝트 폴더] - [debug 폴더] 이동

 

2) 함수 포인터

- 함수 포인터 : 함수를 가리키는 포인터 변수

- 함수 포인터 선언 : 가리키고자 하는 함수의 반환 자료형과 매개변수 자료형을 동일하게 선언

int add(int a, int b);	// add 함수 원형

int main()
{
	int(*p)(int, int);	
	// add함수 가리키는 함수포인터변수 p 선언
	// 매개변수의 변수이름 미지정, 자료형 지정
	p = add;	// add 함수의 주소를 함수 포인터 p에 저장
	int a = (*p)(10, 20);	// 함수포인터 p를 이용하여 add함수 호출할 수 있음
}

 

> main( ) 함수와 함수 포인터 실습

728x90
반응형

'Language > C & C++' 카테고리의 다른 글

HGC - Chapter 9 exam  (0) 2022.08.29
C_10. Basic Grammar of Structure  (0) 2022.08.15
C_08. Basic Grammar of Pointer  (0) 2022.08.11
C_07. Basic Grammar of Array  (0) 2022.08.11
C_06. Basic Grammar of Iteration Statement  (0) 2022.08.10

+ Recent posts