본문 바로가기
C언어/쉽게 풀어쓴 C언어 EXPRESS 개정4판

[5下] 쉽게 풀어쓴 C언어 EXPRESS 개정 4판 5장 PROGRAMMING (7~12번)

by EATSTAR 2023. 6. 18.
반응형

[ 1 ~ 6번 ]

 

[5上] 쉽게 풀어쓴 C언어 EXPRESS 개정 4판 5장 PROGRAMMING (上)

이 페이지는 5장 1~6번 문제에 대해 서술하므로 7~12번의 문제는 아래의 링크를 참조하세요. [5下] 쉽게 풀어쓴 C언어 EXPRESS 개정 4판 5장 PROGRAMMING (下) * 본문은 Microsoft Visual Studio 2022 버전 17.6.3를 사

eatstar.tistory.com

 

* 본문은 Microsoft Visual Studio 2022 버전 17.6.3를 사용하였으므로 다른 버전의 비쥬얼 스튜디오나 다른 C언어 작동 프로그램으로 작동할 경우 오류가 생길 수 있음을 양지해주세요.

7. 정수에 비트 연산자 <<를 한 번 적용하면 2를 곱한 값을 얻을 수 있다. 또 정수에 비트 연산자 >>를 한 번 적용하면 2로 나눈 값을 얻을 수 있다. 사용자로부터 정수 x, y를 입력받아서 x << y의 값을 출력하는 프로그램을 작성하여보자.  (비트 이동 연산자 / MEDIUM)

정수를 입력하시오: 10
2를 곱하고 싶은 횟수: 3

10<<3의 값: 80
문제 의도
비트 연산자 <<, >>를 사용할 수 있는가?

 

#include <stdio.h>

int main(void) {
	int x, time;
	
	printf("정수를 입력하시오: ");
	scanf_s("%d", &x);

	printf("2를 곱하고 싶은 횟수: ");
	scanf_s("%d", &time);

	printf("%d<<%d의 값: %d", x, time, x << time);

	return 0;
}
코드 설명
비트 이동연산자는 "정수 << 이동 횟수" 형식으로 입력하면 된다.

 

 


8. 구의 표면적과 체적을 구하는 프로그램을 작성하라. 구의 반지름은 실수로 입력된다. 아래의 공식을 사용하라. 파이값은 기호 상수를 사용하여 정의하라.  (실수 계산 / HARD)

구의 반지름을 입력하시오: 10.0
표면적은 1256.64입니다.
체적은 4188.79입니다.
문제 의도
파이값 기호상수를 포함한 일반 수식 계산, %.2f로 반올림

 

#include <stdio.h>
#define PI 3.141592

int main(void) {
	double rad = 0;
	double pyo = 0;
	double che = 0;

	printf("구의 반지름을 입력하시오: ");
	scanf_s("%lf", &rad);
	pyo = 4 * PI * rad * rad;
	che = (4.0 / 3.0) * PI * rad * rad * rad;

	printf("표면적은 %.2lf입니다.\n", pyo);
	printf("체적은 %.2lf입니다.\n", che);

	return 0;
}
코드 설명
PI를 define으로 기호상수 정의한다. %.2lf로 소수점 둘째 자리까지 반올림해서 출력한다.
물론 실수형을 float로 정의할 수도 있지만, double이 안정적이므로 double로 처리해준다.

 

 


9. 그리스 최초의 수학자이자 천문학자인 탈레스는 지팡이 하나로 피라미드의 높이를 재었다고 한다. 탈레스는 지팡이를 똑바로 땅에 세우고 지팡이를 움직여서 지팡이의 그림자와 피라미드의 그림자를 일치시켰다. 삼각형 ABC와 삼각형 ADE는 닮은꼴이므로 다음의 수식이 성립한다.

AC : AE = BC : DE

따라서 AC와 AE, BC를 안다면 DE를 계산할 수 있다. AC와 AE, BC를 입력하여서 DE를 구하는 프로그램을 작성하라. 입력되는 수치는 모두 실수로 한다. (실수 계산 / MEDIUM)

지팡이의 높이를 입력하시오: 100
지팡이 그림자의 길이를 입력하시오: 20
피라미드까지의 거리를 입력하시오: 1000
피라미드의 높이는 5000.00입니다
문제 의도
비례관계를 잘 활용해서 (내항 곱하기 외항) 코드를 구성하여 실수를 계산할 수 있는가?

 

#include <stdio.h>

int main(void) {
	double ae;
	double bc;
	double ac;
	double de;

	printf("지팡이의 높이를 입력하시오: ");
	scanf_s("%lf", &bc);
	printf("지팡이 그림자의 길이를 입력하시오: ");
	scanf_s("%lf", &ac);
	printf("피라미드까지의 거리를 입력하시오: ");
	scanf_s("%lf", &ae);

	de = ae * bc / ac;
	printf("피라미드의 높이는 %.2lf입니다.", de);

	return 0;
}
코드 설명
AC : AE = BC : DE이므로 내항을 곱한 것은 외항을 곱한 것과 같다. AE * BC = AC * DE인데, 구하는 것은 피라미드 높이인 DE이므로 AC를 이항시켜 DE = AE * BC / AC로 설정해준다.

 

 


10. 조건 연산자 ?만을 이용하여 2차원 공간의 x 좌표와 y 좌표를 입력받아서 그 좌표가 속하는 사분면을 출력하는 프로그램을 작성하시오. (x>0 && y>0) ? printf("1사분면"): printf(" ");와 같은 문장을 사용하여 작성해본다. (조건 연산자 / MEDIUM)

좌표의 부호 사분면
x > 0, y > 0 1사분면
x < 0, y > 0 2사분면
x < 0, y < 0 3사분면
x > 0, y < 0 4사분면
x 좌표를 입력하시오: 10
y 좌표를 입력하시오: 10

1사분면입니다.
문제 의도
조건 연산자와 논리곱(&&)을 활용할 수 있는가?

 

#include <stdio.h>

int main(void) {
	int x, y;

	printf("x좌표를 입력하시오: ");
	scanf_s("%d", &x);
	printf("y좌표를 입력하시오: ");
	scanf_s("%d", &y);

	(x > 0 && y > 0) ? printf("\n1사분면") : printf("");
	(x < 0 && y > 0) ? printf("\n2사분면") : printf("");
	(x < 0 && y < 0) ? printf("\n3사분면") : printf("");
	(x > 0 && y < 0) ? printf("\n4사분면") : printf("");

	return 0;
}
코드 해설
문제에서 알려준대로, 조건연산자를 활용한다.

 

 


11. 약 2200년 전에 그리스의 에라토스테네스는 최초로 지구의 크기를 측정하였다. 일단 지구를 구형으로 가정하고 또 태양 광선은 지구의 어느 곳에서나 평행하게 비친다고 가정하였다. 또 원호의 길이는 중심각에 비례한다는 원리를 사용하였다. 하지날 정오에 시에네에서 햇빛이 수직으로 비칠 때, 알렉산드리아에서는 막대와 그림자가 이루는 각도가 7.2도로 측정되었다. 또 시에네에서 알렉산드리아까지의 거리는 약 900km로 측정되었다. 이것을 이용하여서 지구의 반지름을 계산하여보자. (실수연산 /  HARD)

거리를 입력하시오: 900
각도를 입력하시오: 7.2
지구의 반지름은 7156.61입니다.
문제 의도
이전 문제보다 더 심화 난이도의 실수 연산을 할 수 있는가?

 

#include <stdio.h>
#define PI 3.1415926535

int main(void) {
    double km, angle, rad;

    printf("거리를 입력하시오: ");
    scanf_s("%lf", &km);
    printf("각도를 입력하시오: ");
    scanf_s("%lf", &angle);

    rad = (360 * km) / (PI * 2 * angle);

    printf("지구의 반지름은 %.2lf입니다.", rad);

    return 0;
}
코드 해설
PI를 define으로 기호상수로 정의하고, 문제의 설명대로 식을 구성한다.
일단 7.2°당 원주가 900km라고 하였으니, 360도일 때와 비교하는 비례식을 작성한다.
900km : 7.2° = 2πr : 360° 이므로 비례식을 이용해 반지름 r을 구할 수 있다.
(* 2πr은 원주 식)
내항과 외항을 곱하면 14.4πr = 900 * 360,
r = 900 * 360 / 14.4π, 이것을 기호로 나타내면 rad = (360 * km) / (PI * 2 * angle)이다.

8, 9번 문제보다는 사유의 여지가 있다.

 

프로그램에 약간의 오차가 발생하는 듯하다.

 


12. 비트 이동 연산을 이용하여 문자 4개를 받아서 하나의 unsigned int형의 변수 안에 저장하는 프로그램을 작성하라. 첫 번째 문자는 비트 0부터 비트 7까지에 저장되고 두 번째 문자는 비트 8부터 비트 15까지, 세 번째 문자는 비트 16에서 비트 23까지, 네 번째 문자는 비트 24부터 비트 31까지에 저장된다. 결과로 생성되는 정수값은 16진수로 출력하도록 한다. 비트 이동 연산과 비트 OR 연산을 사용하라. (비트 이동 연산 / HARD)

첫 번째 문자를 입력하시오: a
두 번째 문자를 입력하시오: b
세 번째 문자를 입력하시오: c
네 번째 문자를 입력하시오: d
결과값: 64636261
문제 의도
비트 이동연산과 비트 OR 연산을 활용하여 심화 비트 연산을 할 수 있는가?

 

#include <stdio.h>

int main(void) {
    char a, b, c, d;
    unsigned int sum;

    printf("첫 번째 문자를 입력하시오: ");
    scanf_s(" %c", &a);
    printf("두 번째 문자를 입력하시오: ");
    scanf_s(" %c", &b);
    printf("세 번째 문자를 입력하시오: ");
    scanf_s(" %c", &c);
    printf("네 번째 문자를 입력하시오: ");
    scanf_s(" %c", &d);

    sum = a;
    sum = b << 8 | sum;
    sum = c << 16 | sum;
    sum = d << 24 | sum;

    printf("%x", sum);

    return 0;
}
코드 설명
어려운 문제다. 비트 이동연산은 물론, OR 연산도 해야 한다.
비트 이동연산은 7번 문제와 같이 <<, >>를 정수 << 횟수 형식으로 진행할 수 있지만,
OR 연산도 있다. OR 연산은 이동을 한 이후에, 빈 자리에 저장한다고 생각할 수 있다.

예를 들어, a에 a를, b에 b를 저장한다고 가정하자.
00000000 00000000 이렇게 16 비트가 존재한다. 이곳에 a를 작성한다.
00000000 01100001 이런 식으로 sum에 a가 저장된다. (* 01100001은 a의 아스키코드 DEC 97의 2진수)
여기서 비트 이동을 하면 8칸 왼쪽으로 이동한다. 그리고 OR 연산을 통해 논리합을 진행해준다.
논리합은 0과 0일 때만 0이고, 0/1 1/0 1/1일 때는 1이므로 8칸 왼쪽으로 이동한 상태에서
b의 아스키코드와 00000000하고 논리합을 하면 b의 정보가 비트 8에서 비트 15까지 그대로 저장된다.
01100010 01100001 이렇게 마무리 된다.

또 %x로 16진수(아스키 코드의 hex값)로 출력해주자.

" %c"로 하는 이유는 첫번째 scanf에서 값을 받고 엔터를 치는데, 그 엔터(개행문자, \n)가 다음 scanf로 넘어가서 해당 scanf를 건너뛸 수 있기 때문에, 공백을 넣어준다. (scanf 상에서 공백은 무시된다.)

 

반응형