일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 구조체배열
- OpenCV
- 컴포넌트스캔
- 코테
- 알고리즘
- python
- 가상면접사례로배우는대규모시스템설계기초
- Spring
- 프로그래머스
- Nodejs
- 카카오 코테
- 파이썬
- nestjs auth
- C언어
- 시스템호출
- C++
- 해시
- @Autowired
- spring boot
- 카카오
- git
- AWS
- nestJS
- 카카오 알고리즘
- TypeORM
- 스프링
- @Component
- 코딩테스트
- thymeleaf
- nestjs typeorm
- Today
- Total
공부 기록장 💻
C언어 Express 7장 Programming 심화 문제 추가 본문
1. 초기값 입력 받아 1씩 감소시키며 0이 될 때까지 반복하여 출력
(+1. for문 사용 / 2. while문 사용)
for문을 사용할 때엔 제어 변수의 초기값을 n으로 하여, 0이 될 때 까지 1씩 감소하는 i를 출력한다.
#include <stdio.h>
int main(void) {
int n;
printf("카운터의 초기값: ");
scanf_s("%d", &n);
for (int i = n;i > 0;i--)
printf("%d ", i);
printf("\n");
return 0;
}
while문을 사용할 때엔 후위 연산자를 이용하여 n의 값을 1씩 감소시키도록 하여 n의 값을 출력한다.
#include <stdio.h>
int main(void) {
int n;
printf("카운터의 초기값: ");
scanf_s("%d", &n);
while (n > 0)
printf("%d ", n--);
printf("\a\n");
return 0;
}
2. 정수를 입력받고, 1부터 해당 정수 사이의 모든 3의 배수의 합을 구하는 프로그램
#include <stdio.h>
int main(void) {
int n, sum = 0;
printf("정수 입력: ");
scanf_s("%d", &n);
for (int i = 1;i <= n;i++) {
if (i % 3 == 0)
sum += i;
}
printf("1부터 %d 사이의 모든 3의 배수의 합은 %d입니다.\n", n, sum);
return 0;
}
어떤 숫자의 배수라는 뜻은, 그 수로 나누어 떨어지는 나머지가 0이라는 것임을 참고하면 된다.
합을 저장할 변수 sum의 초기값은 0이다.
3. 사용자가 입력한 정수의 모든 약수를 출력하는 프로그램
#include <stdio.h>
int main(void) {
int n;
printf("정수 입력: ");
scanf_s("%d", &n);
for (int i = 1;i <= n;i++) {
if (n % i == 0)
printf("%d ", i);
}
printf("\n");
return 0;
}
해당 제어 변수가 약수라면, 입력받은 정수에 의해 나누어 떨어진다는 것을 참조하여 작성하면 된다.
4. 정수 입력 받아 해당 수의 높이만큼, 오른쪽 계단식으로 정렬된 별찍기 프로그램
#include <stdio.h>
int main(void) {
int n;
printf("정수 입력: ");
scanf_s("%d", &n);
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n - i;j++)
printf(" ");
for (int k = 1;k <= i;k++)
printf("*");
printf("\n");
}
return 0;
}
중첩 for문을 사용한다.
이런 별찍기 반복문 문제는 먼저 계단의 층 높이를 바깥 for문의 제어 변수를 이용해 식을 완성하고,
이후에 공백과 별의 개수의 변화를 살펴 이를 반복문 식으로 완성하면 조금 더 수월해진다.
보통은 제어 변수의 초기값을 0으로 두어 입력받은 정수까지 변수가 증가하도록 식을 세우는 경우가 있지만,
조금 복잡해지는 경우 각 계단의 층을 그대로 수로 (1~n) 사용하는 것이 안쪽 for문의 제어식을 세울 때 편하다고 생각해서
1부터 시작하는 편이다.
별찍기 문제는
무엇이 얼만큼 증가하고, 무엇이 얼만큼 감소하는지 판단하여,
이를 얼마나 간결하게 반복문의 식으로 작성하느냐가 관건이라 할 수 있겠다!
나는 반복문을 사용하면서부터 '아, 이래서 코딩할때 수학적 사고력이 필요하다는 거구나' 라는 생각을 했던 것 같다.
5. 정수를 입력 받아, 수가 하나씩 증가하며 왼쪽 계단식으로 정렬되어 출력되는 프로그램
#include <stdio.h>
int main(void) {
int n;
printf("정수 입력: ");
scanf_s("%d", &n);
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= i;j++)
printf("%d ", j);
printf("\n");
}
return 0;
}
별찍기 문제와 다르게 이번엔 '숫자'를 출력하는 문제이다.
역시나 층의 높이는 바깥 for문의 제어 변수로 설정하고,
각 층에 출력되는 수는 안쪽 for문의 제어 변수를 이용한다.
살펴보면 1층(위에서부터)부터 차례대로 층이 높아지면서 출력되는 숫자 또한 같은 양상으로 증가하기 때문에
안쪽 for문의 제어변수가 1~증가하는층수 까지 증가하도록 반복문을 작성하면 된다.
6. 계산기 프로그램
- do~while문 이용하여 메뉴 중 하나를 선택할 때까지 '연산을 선택하시오'를 반복 출력
- 연산 실행 뒤 또 메뉴를 선택할 수 있도록 반복하기
(A: Add, S: Subtract, M: Multiply, D: Divide, Q: Quit)
(+함수로 구현)
#include <stdio.h>
void menu();
int add(int x, int y);
int subtract(int x, int y);
int multiply(int x, int y);
int divide(int x, int y);
int main(void) {
int x, y, result;
char op;
menu();
while (1) {
do {
printf("연산을 선택하시오: ");
scanf_s(" %c", &op);
} while (op != 'A' && op != 'S' && op != 'M' && op != 'D' && op != 'Q');
if (op == 'Q')break;
printf("두 수를 공백으로 분리하여 입력: ");
scanf_s("%d %d", &x, &y);
switch (op) {
case 'A': printf("%d\n", add(x, y));break;
case 'S': printf("%d\n", subtract(x, y));break;
case 'M': printf("%d\n", multiply(x, y));break;
case 'D': printf("%d\n", divide(x, y));break;
default:break;
}
}
return 0;
}
void menu() {
printf("*******************\n");
printf("A---- Add\n");
printf("S---- Subtract\n");
printf("M---- Multiply\n");
printf("D---- Divide\n");
printf("Q---- Quit\n");
printf("*******************\n\n");
};
int add(int x, int y) {
return x + y;
}
int subtract(int x, int y) {
return x - y;
}
int multiply(int x, int y) {
return x * y;
}
int divide(int x, int y) {
return x / y;
}
1) do~while문을 이용해서 무조건 한 번은 해당 문장이 실행되어 op 문자변수를 입력받도록 한다.
while(); 문장이 거짓이 될 때 ( =입력받은 op변수가 A, S, M, D, Q가 아닌 경우) 다시 반복하도록 코드를 작성한다.
2) 위 문장이 참으로 성립된 후, op변수가 만약 Q라면 전체 반복문을 빠져나가도록 설정. (while & break 문 사용)
7. 소수 찾는 프로그램
(+함수로 구현하고, 두 개의 정수를 입력 받아 그 사이의 소수를 모두 출력하도록)
#include <stdio.h>
void getPrime(int x, int y);
int main(void) {
int x, y;
printf("두 정수 입력 : ");
scanf_s("%d %d", &x, &y);
getPrime(x, y);
return 0;
}
void getPrime(int x, int y) {
int i, j;
for (i = x;i <= y;i++) {
for (j = 2;j < i;j++)
if (i % j == 0)break;
if (i == j)
printf("%d ", i);
}
printf("\n");
}
소수를 구하기 위한 getPrime 함수를 작성한다.
이 함수에는 두 가지의 제어 변수가 존재함.
1) 입력받은 두 정수 사이의 숫자를 의미하는 바깥 for문의 제어변수 i
2) i가 소수인지 판별하기 위한 보조 제어변수 j
소수의 약수가 1과 자기 자신 뿐이라는 개념을 이용하여,
변수 i의 숫자를 2~(자기자신-1) 까지의 숫자로 나누어본다.
이 때, 왜 j는 i보다 1이 작아야 하느냐?
안쪽 for문이 작동된 직후, i와 j가 같은 경우 소수로 판단하여 이 수를 출력하는 조건문이 나오기 때문.
j변수가 i보다 1 작은 경우, 한마디로 마지막으로 안쪽 for문이 실행되는 경우에는,
증감식으로 인해 j의 값이 i와 같아지고, 그 반복문은 실행하지 않고 다음 조건문으로 넘어가게 된다.
이 때 i와 j의 값이 같아졌다는 것은, i가 2부터 (j-1)까지 그 어떠한 수로도 나누어지지 않았다는 뜻이므로
소수로 판별되어 출력된다.
이 문제를 처음 마주했을때, 정말 어려웠다.
for문에서 각 제어변수의 증감문과, 제어식을 올바르게 이해하고 넘어가는 것이 중요하다는 것을 깨달았다.
프로그래밍 언어의 문법을 배울 땐, 정말 꼼꼼히 완벽하게 이해를 하는 것이 중요하다 !
8. (1+2+3+...+n)가 10000을 넘지 않으면서 가장 큰 값과 그 때의 n의 값 구하는 프로그램
#include <stdio.h>
int main(void) {
int n=1, sum = 0;
while (1) {
sum += n;
if (sum > 10000) break;
n++;
}
n--;
sum -= n;
printf("1부터 %d까지의 합은 %d입니다.\n", n, sum);
return 0;
}
while문을 이용해 작성하는 프로그램이다.
두 가지의 방법이 있는데, 첫번째는 무한 반복문 속에 break문을 추가하는 방법이고,
두번째는 조건식을 이용해 참, 거짓을 판별하여 반복문을 제어하는 방법이다.
개인적으로 반복문을 처음 접하여 이 문제를 풀 때 매우 헷갈렸다.
논리적 사고력이 부족한 나에게 두 변수를 동시에 생각하는 연습을 하도록 도와준 문제라고 생각한다.
break문의 위치와 1씩 증가하는 변수 n, 변화하는 n의 값을 저장하는 변수 sum의 증감을 잘 파악하여서
while문이 끝난 뒤에, sum과 n의 값을 다시 감소시키는 것이 관건이다.
#include <stdio.h>
int main(void) {
int n=1, sum = 0;
while (sum < 10000) {
sum += n;
n++;
}
n--;
sum -= n;
n--;
printf("1부터 %d까지의 합은 %d입니다.\n", n, sum);
return 0;
}
무한 루프를 사용하는 방법을 잘 몰랐던 나는,
이 두번째 방법을 처음에 사용했고 계속 올바른 값이 나오지 않아 애를 썼었다.
n의 값이 마지막에 증가되기 때문에
반복문이 끝난 후 증가된 값을 다시 감소시키는 과정이 어렵게 다가왔던 것이 기억이 난다.
9. 실수의 거듭 제곱값을 계산하는 프로그램
(+실수 r과 거듭 제곱 횟수인 정수 n을 매개변수로 하여 결과값 실수를 반환하는 함수 추가 작성)
#include <stdio.h>
double power(int r, int n);
int main(void) {
double r;
int n;
printf("실수의 값: ");
scanf_s("%lf", &r);
printf("거듭제곱 횟수: ");
scanf_s("%d", &n);
printf("결과값은 %f\n", power(r, n));
return 0;
}
double power(int r, int n) {
int result = 1;
for (int i = 0;i < n;i++)
result *= r;
return result;
}
실수 r이 n번만큼 거듭해서 곱해져야 하기 때문에,
for 반복문을 사용하면 된다.
변수 result의 초기값을 1로 설정하고 n번만큼 반복문이 실행되어 r이 반복해서 곱해지도록 작성한다.
10. 1부터 n까지 각 수의 제곱을 더하여 계산하는 프로그램
(+위와 같은 방법으로 별도의 함수로 작성)
#include <stdio.h>
int sumofDouble(int n);
int main(void) {
int n;
printf("정수의 값: ");
scanf_s("%d", &n);
printf("1부터 %d의 제곱의 합의 결과값은 %d\n", n, sumofDouble(n));
return 0;
}
int sumofDouble(int n) {
int sum = 0;
for (int i = 1;i <= n;i++)
sum += i * i;
return sum;
}
이번엔 변수 sum의 초기값을 0으로 하고,
반복문의 초기식의 i값은 1로, 그리고 조건식은 i가 n 이하일 때까지로 설정하도록 한다.
그리고 i의 제곱의 값의 합을 저장하기 위해 적절한 식을 작성해준다.
11. 사용자가 입력한 특정한 정수의 자리수를 반대로 출력하는 프로그램 작성
#include <stdio.h>
int main(void) {
int n;
printf("정수 입력: ");
scanf_s("%d", &n);
do {
printf("%d", n % 10);
n /= 10;
} while (n > 0);
printf("\n");
return 0;
}
반복문에서 빠질 수 없는 문제인 것 같다. 수를 입력받아 반대로 출력하는 문제!
나머지/나눗셈의 원리를 잘 이해하면 쉽다.
처음에는 많이 당황케 한 유형의 문제이지만, 원리를 이해하다 보면 익숙해지고 더 어려운 문제를 만나도 쉽게 풀 수 있게 되는 것 같다.
어떤 수를 10으로 나눈 나머지를 출력하고, 남은 몫을 변수에 다시금 저장하는 방법이다.
#include <stdio.h>
int main(void) {
int n;
printf("정수 입력: ");
scanf_s("%d", &n);
do {
printf("n = %d , %d %% 10 = %d\n", n, n, n % 10);
n /= 10;
} while (n > 0);
printf("\n");
return 0;
}
이를 제대로 확인해 보기위해 출력 부분에 일부 문장을 더 추가해본다.
연산자를 출력하고 싶은 경우에는 해당 기호를 두 번 사용하면 된다.
마지막 문장을 실행한 뒤 n은 0이 되어 조건식이 거짓으로 판별되기 때문에 더 이상 해당 반복문은 실행되지 않게 된다.
'# Language & Tools > C' 카테고리의 다른 글
[C언어] 파일 입출력 - FILE 파일 포인터, 파일 관련 함수 (0) | 2021.01.28 |
---|---|
C언어 Express 15장 파일 입출력 Programming 심화 문제 추가 (2) | 2021.01.26 |
[C언어] 함수(function)의 정의, 선언, 호출 / 함수의 매개변수, 반환값, 함수 원형 (0) | 2021.01.25 |
C언어 Express 6장 Programming 심화 문제 추가 (0) | 2021.01.22 |
[C언어] 구구단 출력 프로그램 (0) | 2021.01.22 |