다짜고짜 C언어를 하기 시작했다. (이유?: 추후 공개) 포인터 이전까지는 회독을 많이 한 책이어서 이론 정리 없이 바로 도전 문제를 풀어본다.
복습
23/07/15 (o)
#include <stdio.h>
int main(void)
{
int decimalToHexadecimal = 0;
printf("16진수로 변환할 10진수 정수를 입력하세요: ");
scanf("%d", &decimalToHexadecimal);
printf("%x", decimalToHexadecimal);
return 0;
}
괜찮은 변수명을 정하기 위해 인터넷 서칭 후 정했다. 근데 좀 긴 것 같다. 줄여보겠다.
컴파일러는 왜 온라인을 사용했냐면, 설치중이기 때문이다...... 도전 2번부터는 VS 2022를 사용하도록 하겠다.
복습
23/07/15 (o)
#include <stdio.h>
void Gugudan(int num1, int num2) {
int n = 1;
while (num1 > num2) {
while (n < 10) {
printf("%d * %d = %d\n", num1, n, num1*n);
n++;
}
num1--;
}
while (num1 == num2) {
while (n < 10) {
printf("%d * %d = %d\n", num1, n, num1 * n);
n++;
}
}
while (num1<num2)
while (n < 10) {
printf("%d * %d = %d\n", num2, n, num2 * n);
n++;
}
num2--;
}
int main(void) {
int n1, n2;
printf("구구단 푸는 프로그램입니다. 순서는 자유로우니 2가지 정수를 써서 범위를 나타내세요: ");
scanf_s("%d %d", &n1, &n2);
Gugudan(n1, n2);
}
위의 코드는 망했다. 풀지 못하였다. 두 정수를 입력 받아 그 사이에 있는 단 수까지 구구단이 실행되어야 하는 부분에서 어려움을 느꼈다.
#include <stdio.h>
void NineNine(int num1, int num2);
int main(void)
{
int num1, num2;
printf("두개의 정수 입력 : ");
scanf("%d %d", &num1, &num2);
if(num1<num2)
NineNine(num1, num2);
else
NineNine(num2, num1);
return 0;
}
/* num1단부터 num2단까지 출력 */
void NineNine(int num1, int num2)
{
int i;
while(num1<=num2)
{
for(i=1; i<10; i++)
printf("%d * %d = %d \n", num1, i, num1*i);
printf("\n");
num1++;
}
}
정답 코드를 보면 나와 다르게 한꺼번에 하려고 하지 않고, 메인함수에서 큰 것과 작은 것을 미리 구분짓게 만들었고, 그렇게 하여 인자를 전송해 쉽게 풀어냈다. 함수를 이용하여 더 쉽게 풀어내도록 코딩을 하기 전에 생각하는 연습을 해야겠다.
함수로 기능을 만든다.
복습
23/07/18 (o)
#include <stdio.h>
void TwoIntGCD(int, int);
int main(void) {
int n1, n2;
printf("두 개의 정수를 입력하면 최대공약수를 구해주겠다: ");
scanf_s("%d %d", &n1, &n2);
TwoIntGCD(n1, n2);
}
void TwoIntGCD(int num1, int num2) {
int n;
for (n = 0; (n<=num1)&&(n<=num2); n++) {
if (num1 % n == num2 % n) {
printf("%d", n);
}
}
}
또한 망한 코드이다. 어떻게든 구현해보려 했지만 개념이 제대로 잡히지 않은 듯하다.
이 문제의 풀이 방법은 인터넷으로 검색했을 때 다양한 많은 방법이 있었다.
#include <stdio.h>
int main(void)
{
int a, b;
int i;
printf("정수 2개 입력: ");
scanf("%d %d", &a, &b);
if (a > b)
{
for (i = a; i > 0; i--)
if (a % i == 0 & b % i == 0)
break;
}
else
{
for (i = b; i > 0; i--)
if (a % i == 0 & b % i == 0)
break;
}
printf("%d와 %d의 최대공약수: %d \n", a, b, i);
return 0;
}
받은 두 정수 중 큰 정수를 하나씩 빼는식으로 반복문을 돌리는데, 나눴을 때 두 개다 0이 나오는 가장 큰 수를 최대공약수로 나타낼 수 있다.
🤫위는 잘못된 코드이다! 복습을 하는 중 발견하였다. &는 논리연산자가 아닌 비트연산자이다.
#include <stdio.h>
void GCD(int num1, int num2);
int main(void) {
int num1, num2;
printf("최대공약수를 만들 두 수를 입력하세요: ");
scanf_s("%d %d", &num1, &num2);
GCD(num1, num2);
return 0;
}
void GCD(int num1, int num2) {
/*1. 최대공약수로 두 수를 어떻게든 나눠도 0이다.*/
//2. 최대공약수는 두 수보다 클 수 없다.
int a;
if (num1 > num2) {
for (a = num1; a > 0; a--)
if ((num1 % a == 0) && (num2 % a == 0))
break;
}
else {
for (a = num2; a > 0; a--)
if ((num1 % a == 0) && (num2 % a == 0))
break;
}
printf("최대공약수: %d", a);
}
복습
23/07/18 (o)
접근은 좋았다. 중첩 반복문으로 x가 1일때 / x가 1이고 y가 1일때 ~ 이런식으로 쭉 반복하여 결과를 나타내려는 시도(고민)은 정말 잘했다고 본다. 하지만 조건식 (for문의 초기식;조건식;증감식 중에서) 이 문제였다. 어떻게 하면 조건을 정말 잘 걸었다고 소문이 날까 고민했지만 돈을 빵가격으로 나눈 것이 빵을 최대로 살 수 있는 개수라고는 생각도 못하였다.
#include<stdio.h>
const int BREAD=500;
const int SNACK=700;
const int DRINK=400;
int main(void)
{
int i, j, k;
int money;
printf("현재 당신이 소유하고 있는 금액 : ");
scanf("%d", &money);
for(i=1; i<money/BREAD; i++)
{
for(j=1; j<money/SNACK; j++)
{
for(k=1; k<money/DRINK; k++)
{
if(money==BREAD*i+SNACK*j+DRINK*k)
{
printf("크림빵 %d개, ", i);
printf("새우깡 %d개, ", j);
printf("콜 라 %d개 \n", k);
}
}
}
}
printf("어떻게 구입하시겠습니까? \n");
return 0;
}
그리고 const int(변하지 않는 상수)는 나중에 배우는 것인데 풀이에는 적용돼있었다. 나중에 const 선언 관련에 대해 배우고 다시 한 번 복습해보겠다.
도전 1번 이후로 하나도 제대로 맞춘게 없다. 도전 5는 잘 풀었다고 생각했는데 답이 제대로 나오지 않았다.
#include <stdio.h>
int main(void) {
int a;
int num;
for (num = 1; num < 30; num++) {
for (a = 1; a <= num; a++) {
if (num / a == num && num / a == 1)
printf("%d ", num);
}
}
}
뭐가 틀렸을까 ?
10개의 소수를 출력하기 위해 (2 3 5 7 11 13 17 19 23 29) for문의 num을 29까지 증가하도록 시켰다. 그리고 a로 나누는데 a의 값을 num보다 작거나 같게 설정하고, num / a == num 일때와 num / a == 1일 때와...............
아 잠시만
방법을 알았다. 다시 풀고 오겠다.
.
.
.
모르겠다. 근데, 저 풀이가 왜 틀렸는지는 알았다. 저 두 개의 조건을 만족하는건 1에서 29개의 숫자 전부 다이기 때문이다. 그래서 그것만 제외하는 방법을 구현하지 못한것이다. 어떻게 하는 것일까. 온갖 조건연산자를 갖다 붙혀봤다. 하지만 답은 계속 나오지 않았다..
#include<stdio.h>
int IsPrime(int n);
int main(void)
{
int i=2, cnt=0;
while(cnt!=10)
{
if(IsPrime(i)==1)
{
printf("%d ", i);
cnt++;
}
i++;
}
return 0;
}
int IsPrime(int n) // 소수면 true(1) 리턴
{
int divisors=0, i;
for(i=1; i<=n; i++)
{
if(n%i==0)
divisors++;
}
if(diverse)
if(divisors==2)
return 1;
return 0;
}
위는 답
하. 머리 아파서 내일
2023-07-21 다시 돌아왔다.
#include <stdio.h>
int main(void) {
int num = 2;
int i;
for (i = 1; i <= num; i++) {
if ((num / i) != (1 && num))
num++;
else {
printf("%d ", num);
num++;
}
}
return 0;
}
풀이를 하지 않고 까먹고 지나갔다보니, 다시 풀어도 여전히 틀렸다.
다시 한 번 정답을 보겠다.
#include<stdio.h>
int IsPrime(int n);
int main(void)
{
int i=2, cnt=0;
while(cnt!=10)
{
if(IsPrime(i)==1)
{
printf("%d ", i);
cnt++;
}
i++;
}
return 0;
}
int IsPrime(int n) // 소수면 true(1) 리턴
{
int divisors=0, i;
for(i=1; i<=n; i++)
{
if(n%i==0)
divisors++;
}
if(divisors==2)
return 1;
return 0;
}
while문으로 개수를 세는 용도로 변수 cnt를 만들어줬고,
Isprime 함수 리턴값으로 1을 받으면 입력하고 카운트가 세지는 알고리즘이다.
IsPrime 함수를 분석해보겠다. 이 함수는 소수 판독기이다.
소수면 1을 리턴하는 알고리즘인데, for문에서 나머지가 0이 나오는 개수 누적을 divisors에 한다.
정수가 1과 자기자신으로 밖에 나누어지지 않는다는 것은 나누어지는 횟수는 2번이라는 의미이다.
이 divisors의 나머지가 2개이면 소수이므로 1을 리턴 한다.
대단하다. 재밌는 로직이다. 카운트를 세는 원리를 잘 기억해야겠다.
👀👀복습요망
#include <stdio.h>
int main(void) {
int h=0,m,s,a,remain=0;
printf("초를 입력하시오 : ");
scanf_s("%d", &a);
if (a >= 3600) {
h = a / 3600;
remain = a % 3600;
if (remain >= 60) {
m = remain / 60;
s = remain % 60;
}
else {
m = 0;
s = remain;
}
}
else
if (remain >= 60) {
m = remain / 60;
s = remain % 60;
}
else {
m = 0;
s = remain;
}
printf("[h:%d / m:%d / s:%d]", h, m, s);
return 0;
}
꾸역꾸역 해냈다. 완전 노가다 식으로 한 것 같은데 이렇게 장기간 고민해서 노가다로 성공하면 의미가 있는건지 걱정된다. 실력이 느는 것인가.
답지를 꺼내 비교해보겠다.
#include<stdio.h>
const int H=60*60;
const int M=60;
void SecondToHMS(int sec);
int main(void)
{
int sec;
printf("초(second) 입력 : ");
scanf("%d", &sec);
SecondToHMS(sec);
return 0;
}
void SecondToHMS(int sec)
{
int h, m, s;
/*시 구하기 */
h=sec/H;
sec=sec%H;
/*분 구하기 */
m=sec/M;
sec=sec%M;
/*초 구하기 */
s=sec;
printf("[h:%d, m:%d, s:%d] \n", h, m, s);
}
내 코드는 딱 봐도 너무 복잡하게 생각한 티가 난다.
분(m)이 0이 되었을 때의 상황을 고려하다보니, 조건문까지 나왔다. 하지만 다시 생각해보면, 분이 0분이 나오더라도 60으로 나눴을때 나머지가 초가 되는 것이다.
함수를 이용해 더 깔끔하게 정리하는 연습을 해야겠다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int Square(int b) {
int a = 0;
a = 2 * (2 * (b - 1));
return a;
}
int main(void)
{
int k = 2;
int n;
printf("상수 n 입력: ");
scanf("%d", &n);
while (Square(k) < n) {
}
printf("공식을 만족하는 k의 최댓값은 %d", k);
return 0;
}
정답을 확신하고 결과를 냈지만, 틀리게 나왔다.
일단은 거듭제곱을 대신하는 저 공식이 틀렸다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int Square(int b) { //2의 거듭제곱 구하는 함수
if (b == 1)
return 2;
else
return (2 * Square(b-1));
}
int main(void)
{
int k=1;
int n;
printf("상수 n 입력: ");
scanf("%d", &n);
while (Square(k) <= n)//거듭제곱이 n보다 작거나 같을 때 동안
k++;
printf("공식을 만족하는 k의 최댓값은 %d", k-1);
return 0;
}
이 문제는 풀지 못하다가 문제 8번을 보고 힌트를 얻었다. 2의 n승을 구하는 함수를 재귀적으로 구현하였다. 8번을 동시에 풀어버렸다.
답지를 한 번 살펴보겠다.
#include <stdio.h>
int main(void)
{
int n, k;
int inc=1;
printf("상수 n 입력 : ");
scanf("%d", &n);
if(n==0)
{
printf("만족하는 k 없음 \n");
return 0;
}
for(k=0; inc*2<=n ; k++) // 무한루프
{
inc=inc*2;
}
printf("공식을 만족하는 k : %d \n", k);
return 0;
}
이걸 구현하지 못했다.
inc=inc*2;
말 아낀다...