ProgrammingLanguage/C언어

C언어 | 함수 포인터 예제

씽쌩쏭 2021. 2. 14. 05:18
728x90

✅ 오늘의 문제 : 사칙연산 계산기 만들기

 

함수 포인터를 활용해서 사칙연산 계산기를 만들어 보세요.

 

  • 두 수를 먼저 입력받습니다.
  • 연산할 기호를 입력받습니다.
  • 해당 기호에 맞는 연산을 실시합니다.

 

(코뮤니티 모각코 과정 中 출제된 문제입니다.)

 

[초안]

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//연산 함수

int plus(int a, int b) {
	return a + b;
}
int minus(int a, int b) {
	return a - b;
}
int multiply(int a, int b) {
	return a * b;
}
int divide(int a, int b) {
	return a / b;

}

int main() {

	int a, b; // 두 수
	char c; // 연산 기호
	
	//두 수 입력 받기
	printf("a : ");
	scanf("%d", &a);
	printf("b : ");
	scanf("%d", &b);

	getchar(); //버퍼 비우기

	//연산할 기호 입력 받기 
	printf("연산 종류 (+, -, *, /) : ");
	scanf("%c", &c);


	//연산 및 출력
	int (*fptr)(int, int); // 함수 포인터

	switch (c)
	{
	case '+':
		fptr = plus;
		printf("%d %c %d = %d", a, c, b, fptr(a, b));
		break;
	case '-':
		fptr = minus;
		printf("%d %c %d = %d", a, c, b, fptr(a, b));
		break;
	case '*':
		fptr = multiply;
		printf("%d %c %d = %d", a, c, b, fptr(a, b));
		break;
	case '/':
		fptr = divide;
		printf("%d %c %d = %d", a, c, b, fptr(a, b));
		break;
	default: 
		printf("잘못 입력하셨습니다.");
		break;
	}

	return 0;
}

 

음 getchar( )로 버퍼 비우는 게 아리송해서 물어봤더니 이렇게 하는 게 맞다고 한다!

 

scanf()의 고질병인데... 다른 수를 입력받은 후%c를 받게 되면 \n이 자동으로 변수에 들어간다.

 

그래서 \n이 들어간 버퍼를 비워주기 위해 getchar()를 사용했다.

 

switch-case문에서 printf();가 반복되는 게 영...꼴보기가 싫다.

매니저님도 저건 바꾸라 하셨다... 그래서 고민 고민하다가 바꾼 코드

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//연산 함수

int plus(int a, int b) {
	return a + b;
}
int minus(int a, int b) {
	return a - b;
}
int multiply(int a, int b) {
	return a * b;
}
int divide(int a, int b) {
	return a / b;

}

int main() {

	int a, b; // 두 수
	char c; // 연산 기호
	
	//두 수 입력 받기
	printf("a : ");
	scanf("%d", &a);
	printf("b : ");
	scanf("%d", &b);

	getchar(); //버퍼 비우기

	//연산할 기호 입력 받기 
	printf("연산 종류 (+, -, *, /) : ");
	scanf("%c", &c);


	//연산 및 출력
	int (*fptr)(int, int); // 함수 포인터

	switch (c)
	{
	case '+':
		fptr = plus;
		break;
	case '-':
		fptr = minus;
		break;
	case '*':
		fptr = multiply;
		break;
	case '/':
		fptr = divide;
		break;
	default: 
		printf("잘못 입력하셨습니다.");
		break;
	}
	printf("%d %c %d = %d", a, c, b, fptr(a, b));

	return 0;
}

 

이렇게 하면 fptr에는 함수가 들어가니까 괜찮겠지? 하고 생각했던 나... 실행이 안되길래 봤더니

 

error C4703: 초기화되지 않았을 수 있는 로컬 포인터 변수 'fptr'이(가) 사용되었습니다.

 

오류 발생...

 

근데 아무리 생각해봐도 fptr을 초기화하는 방법을 모르겠더라.

그래서 오픈채팅방에 물어봄ㅎㅎ

 

 

그리하여 최종 코드

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//연산 함수

int plus(int a, int b) {
	return a + b;
}
int minus(int a, int b) {
	return a - b;
}
int multiply(int a, int b) {
	return a * b;
}
int divide(int a, int b) {
	return a / b;

}

int main() {

	int a, b; // 두 수
	char c; // 연산 기호
	
	//두 수 입력 받기
	printf("a : ");
	scanf("%d", &a);
	printf("b : ");
	scanf("%d", &b);

	getchar(); //버퍼 비우기

	//연산할 기호 입력 받기 
	printf("연산 종류 (+, -, *, /) : ");
	scanf("%c", &c);


	//연산 및 출력
	int (*fptr)(int, int); // 함수 포인터

	switch (c)
	{
	case '+':
		fptr = plus;
		break;
	case '-':
		fptr = minus;
		break;
	case '*':
		fptr = multiply;
		break;
	case '/':
		fptr = divide;
		break;
	default: 
		printf("잘못 입력하셨습니다.");
		return 1; //NULL 값
	}
	printf("%d %c %d = %d", a, c, b, fptr(a, b));

	return 0;
}

 

 

함수 포인터 너무 신기하다! 함수 반복해서 적어야 할 때... 편하고... 간단하다...편하고...간단하다...

 

+ 입력 시
- 입력 시
* 입력 시
/ 입력 시
잘못 입력 시

 

 

깔끔!!

도움 주신 분 감사합니다...

 

 

그리고 자꾸 이 솔루션 파일 열 때마다... VS2019에서 줄 끝이 일관성이 없다고 경고 메시지를 띄우는데...

해결법 알아냄

도구-> 옵션-> 환경-> 로드할 때 줄 끝 일관성 검사를 끄면 된다.

 

 

왜 띄우는 고 하니...

 

보통 윈도우의 줄 바꿈은 /r/n 페어로 끝나지만, 

다른 OS들, 맥이나 유닉스는 /r, /n 등 하나의 형으로만 이루어져 있다.

그렇게 문서가 일관된 하나의 타입으로 되어있지 않고,

혼용되어 작성되어있으면 Visual Studio에서 이런 경고창을 내보내게 된다고 한다!!

윈도우 환경이면... 경고창 띄우지 말지...^^;

 

암튼... 이거 해결법도 알아내고 함수 포인터도 배워서 알찬 예제였삼ㅎㅎ

점점 어려워지고 있다...