C 언어/멘토링

[C언어/멘토링] 멘토링 재시험 오답 정리

luckyd8 2025. 6. 8. 18:42

 

문제 1. 

월을 입력. 며칠까지 있는지 출력. 단, 2월의 경우 28일까지 존재.

 

문제를 풀 때 30일까지인 달이 존재한다는 것을 까먹어버렸다...

답으로 작성한 코드이다. 

#include <stdio.h>

int main() {
   int m;
   scanf_s("%d", &m);

   if (m == 2) { // 달(m)이 2인 경우
      printf("28"); // 28을 출력
   } else { //그 외에 닫(m)의 경우
      printf("31"); // 31을 출력
   }
}

28일인 달은 2월, 31일인 달은 1, 3, 5, 7, 8, 10, 12월, 30일인 달은 4, 6, 8, 9, 11월이다.

이를 바탕으로 수정한 코드이다. 

#include <stdio.h>

int main() {
	int m;
	scanf_s("%d", &m);

	if (m == 2) {
		printf("28");
	} else if (m == 4 || m == 6 || m == 9 || m == 11) {
		printf("30");
	} else {
		printf("31");
	}
}

 

 

문제 2. 

숫자를입력. 입력받은 숫자 높이만큼의 별을 삼각형으로 출력. 단, 재귀함수를 이용하여 구현할 것.

 

재귀함수 개념에 대한 이해도가 부족했다.  

작성했던 코드이다. 논리적 오류도 많고, 개념이 불완전한 상태로 작성하다보니 재귀함수의 정확한 사용 흐름도 파악하지 못했다. 솔직히 그냥 무의미한 코드이다.  

#include <stdio.h>

int r(int a) {
	int n = 0; // n은 r 함수에서 항상 0이 됨 -> main에서 받은 n과 무관
	int result;
	for (int i = 0; i < n; i++) // n == 0이라 실행 불가
	{
		for (a = n; a < n - 1; a--) // 조건 자체가 논리적으로 성립 불가능
			result = printf("*"); // 의미 없음
	}
	return result; // 재귀함수 사용의 요구 조건이 지켜지지 않음 (재귀 함수 등장X)
}

int main() {
	int n = 0; // 불필요한 변수들의 중복 선언
	int a = 0;
	scanf_s("%d", &n);
	printf("%d", r(a)); //n을 r(a)에 넘기지 않음
}

 

이를 보완한 최종 코드이다.

#include <stdio.h>

void star(int n) {
	if (n == 0) return; // n=0일 경우, 종료
	for (int i = 0; i < n; i++) {
		printf("*"); // n개의 별 출력
	}
	printf("\n");

	star(n - 1); // n-1개로 재귀 호출 (다음 줄)
}

int main() {
	int n;
	scanf_s("%d", &n);
	star(n);
}

 

 

문제 3. 

16진수 숫자를(0~9,A~F) 입력. 2진수와 10진수로 변환한값을 출력.

 

우선 16진수를 2진수와 10진수로 변환하는 법도 몰라서 아예 손도 대지 못했다. 

정답 코드이다.

더보기

16진수 -> 10진수 

16진수란, 0 ~ 9까지의 숫자 +  A ~ F까지의 문자를 사용해 숫자를 표현함

문자 코드 숫자
'0' ~ '9' 0 ~ 9
'A' ~ 'F' 10 ~ 15

'0' ` '9' 의 경우, '문자 코드' - '0' -> 숫자

예) '5'의 ASCII 값은 53, 문자 '0'의 ASCII 값은 48, '5' -'0' = 53 - 48 = 5 (진짜 숫자 5)

 

'A' ~ 'F'의 경우, '문자 코드' - 'A' + 10 -> 숫자 

예) 'B'의 ASCII 값은 66, 'A'의 ASCII 값은 65, 'B' - 'A' + 10 = 66 - 65 + 10 = 11 (10진수 11)

#include <stdio.h>

int main() {
	char c;
	int n;

	scanf_s("%c", &c);

	//16진수 -> 10진수
	if (c >= '0' && c <= '9') {
		n = c - '0';
	} else if (c >= 'A' && c <= 'F') {
		n = c - 'A' + 10;
	}

	//16진수 -> 2진수
	for (int i = 3; i >= 0; i--) {
		printf("%d", (n >> i) & 1);
	}
	printf("\n");
	printf("%d", n);
}

 

 

문제 4. 

두 구조체(포인터를 사용하지 않은 구조체와 동적으로 할당한 구조체)를 선언. Name과 comment, age를 입력받고, 세 멤버 변수가 전부 같은지 비교. 만약 다르다면, age가 더 큰 구조체의 정보를 출력.

 

정답 코드이다. 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct P{
	char name[20];
	char comment[100];
	int age;
}; P;

int main() {;
	P p1;
	P* p2;
	p2=(P*)malloc(sizeof(P)); //p2 포인터에 동적 할당
	
	printf("Name1: ");
	scanf_s("%[^\n]", p1.name, (unsigned)sizeof(p1.name)); // 공백을 포함한 문자열 입력 가능하도록 설정
	getchar(); // 개행문자 제거, 필수X, 오류가 나서 추가
	printf("comment1: ");
	scanf_s("%[^\n]", p1.comment, (unsigned)sizeof(p1.comment));
	getchar();
	printf("age1: ");
	scanf_s("%d", &p1.age);
	getchar();

	printf("\n");

	printf("Name2: ");
	scanf_s("%s", p2->name, (unsigned)sizeof(p2->name));
	getchar();
	printf("comment2: ");
	scanf_s("%[^\n]", p2->comment, (unsigned)sizeof(p2->comment));
	getchar();
	printf("age2: ");
	scanf_s("%d", &p2->age);
	getchar();

	printf("\n");

	if (strcmp(p1.name, p2->name) == 0 && 
		strcmp(p1.comment, p2->comment) == 0 && 
		p1.age == p2->age) {
		printf("Same!");
	} else {
		if (p1.age > p2->age) {
			printf("Name: %s\n", p1.name);
			printf("comment: %s\n", p1.comment);
			printf("age: %d", p1.age);
		} else if (p2->age > p1.age) {
			printf("Name: %s\n", p2->name);
			printf("comment: %s\n", p2->comment);
			printf("age: %d", p2->age);
		}
	}
	free(p2);
}

 

 

문제 5. 

문자열 2개를 입력받고, 두 문자열을 이어 붙여 출력. 단, 하나의 변수에 이어붙인 문자열을 저장하고 출력. stdio.h, stdlib.h 이외의  헤더파일 사용 금지

 

문자열을 복사할 때 흔히 사용하는 string.h 헤더 파일 사용이 금지되어 있어, 포인터를 활용하는 방식으로 시도해보았다.

처음 작성한 코드이다.

#include<stdio.h>
#include <stdlib.h>

int main() {
	char s1[10];
	char s2[10];

	char* p = s1;
	scanf_s("%s", p, sizeof(p));

	char* q = s2;
	scanf_s("%s", q, sizeof(q));

	printf("%s%s", p, q);
}

 

출력 결과는 예제와 동일하지만, '하나의 변수에 이어붙인 문자열을 저장하고 출력' 의 조건을 충족하지 않아 오답처리 되었다. 이 조건을 만족하기 위해선 두 문열을 붙인 결과를 하나의 변수(배열)에 저장해야 한 후 출력해야 한다. 

수정한 최종 코드이다.

#include<stdio.h>
#include <stdlib.h>

int main() {
	char s1[10];
	char s2[10];

	char* p = s1; // p는 s1 문자열의 시작 주소를 가리킴
	scanf_s("%s", p, sizeof(s1));

	char* q = s2;
	scanf_s("%s", q, sizeof(s2));

	// p를 s1 문자열 끝(null 문자 위치)으로 이동
	while (*p != '\0') {
		p++;
	}

	// s2 문자열을 이어붙임(s2 문자열을 s1 뒤에 복사)
	while (*q != '\0') {
		*p = *q; // *q(s2 시작 문자)를 *p(s1 끝 문자)에 복사
		p++; // s1 다음 위치로 이동
		q++; // s2 다음 문자로 이동
	}

	*p = '\0'; // 마지막에 null 문자 추가

	printf("%s", s1); // 하나의 변수(s1)에 저장된 최종 문자열 출력
}

 

 

문제 6. 

숫자를 입력받고, 입력받은 숫자를 2배해서 출력하세요. (단, +, -, *, / 연산자 사용 금지)

 

숫자를 2배 할 방법을 생각해내지 못했다. 찾아보니 비트 연산자를 사용하는 방법이 있었다. 

정답 코드이다.

#include <stdio.h>

int main() {
	int n;
	scanf_s("%d", &n);

	printf("%d", n << 1); // 2배 = 왼쪽으로 1비트 시프트
}