새벽을 밝히는 붉은 달

1. 나의 첫번째 C언어 과제 본문

Develop/C

1. 나의 첫번째 C언어 과제

자윰 2019. 5. 26. 01:30

사실 과제를 한 지는 오래되었지만,

블로그도 새로 시작하기도 하고, 앞으로 나의 4년간의 대학 생활,

그리고 더 나아가 그 앞의 삶을 기록하기로 했기 때문에!

C언어의 첫발이었던 과제를 먼저 포스팅하기로 했다.


1. Decimal to binary, octal and hexadecimal numbers

 

이 문제는 10진수를 입력하면 2진수, 8진수, 16진수로 출력하는 문제이다.

0, 0x 를 사용하면 되는 것 아니냐! 라고 할 수도 있겠지만

과제의 조건이 loop와 conditional sentence를 사용하여 해결하는 것이었기 때문에

위 방법은 조용히 포기했다.

 

2진수의 경우 실습시간에 이미 한 번 만들어보기도 했고,

2로 나눈 나머지를 모아놓은 것이 2진수이기 때문에 꽤 쉽게 할 수 있었다.

같은 방법으로 8진수도 마찬가지.

 

문제는 16진수였다.

16으로 나누면... 나머지가 9까지일 때는 괜찮은데... 그 다음부터는 문자잖아!?

여기에서 문제에 봉착했다.

대학에 입학해서 처음으로 C언어라는 걸 접한 나는,

정수형 밖에 입출력할 줄 몰랐다.

 

어떡하지... 배열도 안 배웠고, 함수도 어떻게 쓰는지 잘 모르는데...

일단 과제라도 제출하고 보자! 하고 열심히 구글링을 했다.

그리고, 코드를 보며 하나하나 입력해보고

모르는 건 하나씩 공부해나갔다.

void형으로 함수 선언, 문자 배열, 아스키 코드 등등

 

그래서 완성한 코드는 다음과 같다.

#include <stdio.h>
#define HELP "This is a program that prints a table of binary, octal and hexadecimal equivalents of the decimal numbers in the range of 1 through 256.\n\n"

int Dec2Bin(int dec) {
	int rem, tmp, bin;
	tmp = 1;
	bin = 0;
	while (1) {
		if (dec == 0)
			break;
		rem = dec % 2;
		dec = dec / 2;
		bin = bin + rem * tmp;
		tmp = tmp * 10;
	}
	return bin;
}

int Dec2Oct(int dec) {
	int rem, tmp, oct;
	tmp = 1;
	oct = 0;
	while (1) {
		if (dec == 0)
			break;
		rem = dec % 8;
		dec = dec / 8;
		oct = oct + rem * tmp;
		tmp = tmp * 10;
	}
	return oct;
}

void Dec2Hex(int dec) {
	int rem;
	int T = 3;
	char Hex[4];

	int idx = 0;
	while (T--) {
		rem = dec % 16;
		dec = dec / 16;
		if (rem < 10) {
			Hex[idx] = rem + 48;
		}
		else {
			Hex[idx] = rem + 55;
		}
		idx++;
	}
	printf("%c%c%c\n", Hex[2], Hex[1], Hex[0]);
}

int main() {
	int dec = 1;
	int nBinary, nOctal;

	printf(HELP);
	printf("Deciaml\t\tBinary\t\tOctal\t\tHexadecimal\n");

	for( ; dec <= 256; dec++) {
		nBinary = Dec2Bin(dec);
		nOctal = Dec2Oct(dec);

		printf("%3d\t\t%09d\t%03d\t\t", dec, nBinary, nOctal);
		Dec2Hex(dec);
	}
	return 0;
}

2진수, 8진수는 숫자처럼 취급해서

2 -> 10(2)로 나타내는 걸 10진수 10으로 출력되게 했다.

 

문제의 16진수!

먼저, 256까지 출력하게 하라는 조건이 있었기 때문에 배열을 4의 크기로 선언해주었다.

그리고 나눗셈을 한 후, 나머지가 9이하라면 48을 더해 아스키코드로 숫자가 배열에 들어가게 했다.

나머지가 10 ~ 15라면 55를 더해 문자 A ~ F가 배열에 들어가게 했다.

그리고 얘는 배열로 선언했으므로, 순서대로 출력하게 했다.

 

조금 더 배운 지금은 저 배열을 문자열로 선언하여 %s로 출력하는 것이

256보다 훨씬 더 큰 수를 16진수로 출력해야 할 경우에도 대비할 수 있어

더 좋은 방법이라고 생각한다.

 

저 코드를 실행시키면 다음과 같이 나온다.

 

 


2.  Guessing three numbers (Baseball game) 

 

야구게임! 평소에 해보기만 했지 내가 이걸 직접 만들 줄은 몰랐다.

아직도 기억나는게, 친구랑 스카이프하며 코드를 작성하고 실행시키는데,

컴파일 에러가 계속 떠서 친구가 매우 안타까워했던 기억이 난다.

 

#define _CRT_SECURE_NO_WARNINGS

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

#define HELP "This is a Baseball Game.\n"
#define MSG4A "Please input three numbers (mutually-exclusive) between 1 ~ 10: "
#define ERR4A "Duplicated input.\n"
#define ERR4B "Not a valid input.\n"


int main() {
	int Ans[3];
	srand(time(NULL));
	for (int i = 0; i <= 2; i++) {
		Ans[i] = rand() % 9 + 1;
		if (Ans[i])
			continue;
	}

	printf(HELP);

	while (1) {
		int ball = 0;
		int strike = 0;
		int err = 0;
		int input[3];

		printf(MSG4A);
		scanf("%d%d%d", &input[0], &input[1], &input[2]);

		if (input[0] == input[1] || input[0] == input[2] || input[1] == input[2]) {
			printf(ERR4A);
			err++;
		}

		for (int cp = 0; cp <= 2; cp++) {
			if (input[cp] < 1 || input[cp]>10) {
				printf(ERR4B);
				err++;
				break;
			}
		}
		if (err > 0) continue;

		for (int rp = 0; rp <= 2; rp++) {
			input[rp];

			if (input[rp] == Ans[rp]) {
				strike++;
			}
			else if (input[rp] != Ans[0] && input[rp] != Ans[1] && input[rp] != Ans[2]) {

			}
			else {
				ball++;
			}
		}

		if (strike == 3) {
			printf("\n\nThe generated numbers were %d, %d, %d\n", Ans[0], Ans[1], Ans[2]);
			printf("3 Strike Out\n");
			printf("Good job! Bye!\n");
			return 0;
		}

		else {
			printf("\n%d Strike %d Ball\n\n", strike, ball);
		}
	}
}

먼저 난수를 생성해줬다.

난수를 생성하는 것은 실습시간에 배웠는데, 복습할 겸 나중에 포스트해야겠다.

(사실 지금도 잘 기억안남)

 

while문을 사용하여 사용자가 정답을 맞출 때까지 프로그램이 실행되도록 하였다.

그리고 사용자로부터 3개의 숫자를 입력받는다.

 

만약, 같은 숫자가 입력되었다면 if 문을 통해 에러문구를 띄우고,

다시 입력을 받도록 하였다.

 

또한 1~9까지의 범위를 지나도 에러문구를 띄우게 했다.

(근데 지금보니, 0은 안 받나?)

 

2개의 error handling을 거친 후에는 정답이 맞는지 확인하는 과정이다.

만약 위치와 숫자 모두 맞다면 strike++을 한다.

그리고 else if문을 통해 숫자가 전부 틀릴 경우를 거르고,

그 나머지 경우는 ball++를 하게 했다.

 

만약에 strike가 3이라면, 3개의 숫자를 모두 맞췄으므로

정답 문구를 출력하고 프로그램이 종료되도록 했고,

아닌 경우에는 strike 수와 ball 수를 출력하고 다시 입력받도록 했다.

 

야구게임은 누군가의 도움없이 나 혼자 작성해서 완성한 첫 소스라,

프로그램이 별탈없이 작동했을 때 너무 기뻤다.

이런게 C언어의 재미인가봐.


이 코드를 짠 지 아직 한달 반 밖에 안 지났음에도 불구하고,

지금 보니 매우 쉬웠던 문제였음이 느껴진다.

그동안 많은 걸 배웠다는 거겠지?

 

'Develop > C' 카테고리의 다른 글

2. 두번째 C언어 과제  (2) 2019.05.26
Comments