C 사용자 정의 함수 4가지 검증된 패턴
C 사용자 정의 함수 4가지 검증된 패턴
어떤 숫자가 소수인지 판별하는 사용자 정의 함수를 네 가지 다른 방식으로 구현한 완전한 프로그램을 통해, 어느 접근법이 가장 명확하고 재사용성이 높은지 학습합니다.
아래 네 프로그램은 같은 논리적 작업을 서로 다른 함수 시그니처로 표현합니다. 네 가지 출력 모두 동일하지만 설계 선택이 달라 함수 설계의 핵심 트레이드오프를 보여줍니다.
예제 1: 인수 없음, 반환값 없음
#include <stdio.h>
void checkPrimeNumber();
int main() {
checkPrimeNumber(); // 인수 전달 안 함
return 0;
}
// 반환 타입이 void라 값 반환 안 함
void checkPrimeNumber() {
int n, i, flag = 0;
printf("양의 정수 입력: ");
scanf("%d", &n);
for(i=2; i <= n/2; ++i) {
if(n%i == 0) {
flag = 1;
}
}
if (flag == 1)
printf("%d is not a prime number.", n);
else
printf("%d is a prime number.", n);
}
checkPrimeNumber() 함수가 사용자 입력 읽기, 소수 판별, 결과 출력까지 모두 담당합니다. 반환 타입이 void라 결과는 사이드 이펙트(출력)로만 전달됩니다.
예제 2: 인수 없음, 반환값 있음
#include <stdio.h>
int getInteger();
int main() {
int n, i, flag = 0;
// 인수 전달 안 함
n = getInteger();
for(i=2; i<=n/2; ++i) {
if(n%i==0){
flag = 1;
break;
}
}
if (flag == 1)
printf("%d is not a prime number.", n);
else
printf("%d is a prime number.", n);
return 0;
}
// 사용자가 입력한 정수 반환
int getInteger() {
int n;
printf("양의 정수 입력: ");
scanf("%d", &n);
return n;
}
여기서 getInteger()가 입력 루틴을 캡슐화해 값을 main에 반환하고, main이 소수 판별 로직을 처리합니다. 이 분리로 입력 단계가 다양한 컨텍스트에서 재사용 가능해집니다.
예제 3: 인수 전달, 반환값 없음
#include <stdio.h>
void checkPrimeAndDisplay(int n);
int main() {
int n;
printf("양의 정수 입력: ");
scanf("%d", &n);
// n을 함수에 전달
checkPrimeAndDisplay(n);
return 0;
}
// 반환 타입 void라 값 반환 안 함
void checkPrimeAndDisplay(int n) {
int i, flag = 0;
for(i=2; i <= n/2; ++i) {
if(n%i == 0){
flag = 1;
break;
}
}
if(flag == 1)
printf("%d is not a prime number.", n);
else
printf("%d is a prime number.", n);
}
이 패턴에서는 결과 표시 책임이 헬퍼 함수로 이동합니다. main은 간결해지지만 알고리즘과 I/O가 결합돼 재사용성이 떨어집니다.
예제 4: 인수 전달, 반환값 있음
#include <stdio.h>
int checkPrimeNumber(int n);
int main() {
int n, flag;
printf("양의 정수 입력: ");
scanf("%d", &n);
// n을 checkPrimeNumber() 함수에 전달
// 반환값을 flag 변수에 대입
flag = checkPrimeNumber(n);
if(flag == 1)
printf("%d is not a prime number", n);
else
printf("%d is a prime number", n);
return 0;
}
// 함수에서 int 반환
int checkPrimeNumber(int n) {
int i;
for(i=2; i <= n/2; ++i) {
if(n%i == 0)
return 1;
}
return 0;
}
이 설계는 알고리즘을 격리하고 단순한 상태 플래그를 반환합니다. 호출자가 결과 표현 방식을 결정하므로 라이브러리나 대규모 애플리케이션에 쉽게 통합할 수 있어 함수가 고도로 재사용 가능합니다.
최적 패턴 선택
네 구현 모두 같은 출력을 내지만, 가장 유지보수와 테스트하기 좋은 접근은 예제 4입니다: 숫자를 인수로 전달하고 불리언 스타일 플래그를 반환. 이 패턴은 단일 책임 원칙을 준수하며, checkPrimeNumber를 I/O 의존성 없이 단위 테스트할 수 있고, 더 복잡한 시스템에 쉽게 통합됩니다.
궁극적으로 선택은 프로젝트 아키텍처에 달려 있습니다. 함수가 사용자와 직접 상호작용해야 한다면 예제 3으로 충분할 수 있습니다. I/O가 다른 곳에서 처리되는 라이브러리 코드나 서비스라면 예제 4가 가장 큰 유연성을 제공합니다.