Sister Nosilv story

[쉽풀C] 5장 수식과 연산자_중간점검 도전문제 Exercise Programming 해설

by 노실언니

쉽게 풀어쓴 C언어 Express - 천인국 - 생능출판사 - 개정3판

Chapter 5. 수식과 연산자

 

p174. 중간점검

1️⃣. 식 Expression

  - Syntactic entity 구문요소

  - 다양한 자료형의 값 value ( ↔ Statement와의 차이; 얜 실행만 하고, return value 없을 수도)

  - (연산자operator), 피연산자operand의 조합 → 값 상수/변수 그 자체도 '식'

2️⃣. YES; Literal constant 10 is= Expression.

3️⃣. y피 =연 10피 +연 20피 ;

  ①   y피 =연 10피 +연 20피 ;

  ②   y피 =연 10피 (피)20피 ;

4️⃣. 피연산자operand의 수 → 1개 단항/ 2개 이항/ 3개 삼항

 

p180. 중간점검

1️⃣. x++ ① 변수값을 반환하고 ② ; 명령이 다 실행 된 후 해당 변수 1 증가

2️⃣. x++ 선 반환 後 증가 VS ++x 先 증가 후 반환 → ++의 위치가 다 알려주는 셈

3️⃣. 13

 ①선 반환 : printf( 1+x+2 ) 실행하여 13 출력

 ②후 증가 : x는 11이 되었으나 티가 안 남

   Point. 증감연산자 中 증감시, 무조건 ; 명령이 다 실행 된 후 증감 ∴ (1+x++)의 괄호무시

 

p185. 중간점검

1️⃣. '변수'가 대입 연산자에서 lvalue(left value)가 될 수 있다.

2️⃣. 수학에서의 등호(=)는 '같다'는 의미이다.

  컴퓨터언어에서의 등호(=)는 '우측의 값을 좌측의 변수에 대입/할당/저장한다'는 의미이다.

  = : Assignment operator

3️⃣. x *= y → x = x * y ; 복합대입연산자

4️⃣. 10 % 6 ; 나눈 나머지 ⇦ 10 ÷ 6 = 1(몫) * 6 + 4(나머지) ∴ 수식의 값 4

5️⃣. ' int / int ' 이므로 int 형을 반환한다. 즉, 몫인 1을 반환한다. (dynamic인 python은 // 연산자가 몫반환)

6️⃣. x += y ; x = x + y  ⇎  x =+ y ; x = +y ; y값의 부호를 변형하지 않고 그대로 변수x에 할당

  * +(음수) ≠ 양수 : (+1) , (-1)을 곱한다고 생각하면 편함

 

비슷하지만 다른 등호씨

p187. 중간점검

1️⃣. 1 과 0 ; True를 뜻하는 1, False를 뜻하는 0 (* python은 bool형 datatype이 따로있지만)

2️⃣. 6 ; (3>=2) = 1, (1) + 5 = 6

 

p192. 중간점검

1️⃣. (age >= 25) && (salary >= 35000000)

2️⃣. 참(1) ; 0이 아닌 다른 값은 모두 참

3️⃣. 0 ; NOT(TRUE) = FALSE

4️⃣. AND(&&):All True / 하나라도 False면, 무조건 False → False가 나오는 즉시 조건체크 종료해버림

  OR(||):All False / 하나라도 True면, 무조건 True → True가 나오는 즉시 조건체크 종료해버림

 

p193. 도전문제

result = (year % 2 == 0);
printf("Even-Odd >> %d\n", result);

 

p194. 중간점검

printf("Even-Odd? >> _\b");
scanf("%d", &x);
printf("Even-Odd? >> %s", (x % 2 == 0) ? "Even" : "Odd");

* 이게 되네

 

p200. 중간점검

1️⃣. 비트를 지정된 숫자만큼 왼쪽으로 이동시키는 연산자는 >> 이다.

2️⃣. 비트의 값을 0에서 1로, 1에서 0으로 바꾸는데 사용하는 연산자는 ~ (NOT) 이다.

3️⃣. 변수 x의 값을 2배로 하려면 쪽으로 비트를 이동시키면 된다. ( x << 1 )

4️⃣. 변수 x의 값을 ½배로 하려면 오른쪽으로 비트를 이동시키면 된다. ( x >> 1 )

 

p200. LAB

mask의 역할을 이해하는데 한참 걸렸네 ㅜㅜ

unsigned char number, i , mask;		// 1byte = 8bit____ ____
mask = 1 << 7;						// 0000 0001 → 1000 0000
printf("Decimal(≤ 255) >> _\b");	// ____ ____
scanf("%hhu", &number);				// using char to 1byte integer

printf("Binary >> ");
for (i = 0; i < 8; i++)
{
	printf("%d", (number & mask) == 0 ? 0 : 1);
	mask = mask >> 1;
}

Line 9. ((number & mask) == 0) ? printf("0") : printf("1); 효율면에서 차이가 날까?

* 새롭게 알게 된 것 *

1byte의 data type을 사용하고 싶은 경우, (unsigned) char을 사용하여야 함.

문자로 사용하고 싶으면, 형식지정자(format specifiers) → %c

정수로 사용하고 싶으면, 형식지정자(format specifiers) → %hhd(-128~127) %hhu(0~255)

+ short는 %hd, %hu 

 

p202. LAB

^(XOR) : 달라? (비트단위의 !=)

#include <stdio.h>

int main(void)
{
	char data = 'a';	// 0110 0001 (97)
	char key = 0xff;	// 1111 1111 (255)
	char encrpted_data = data ^ key;

	unsigned char number, i, mask;		// 1byte = 8bit____ ____
	mask = 1 << 7;		// 0000 0001 → 1000 0000

	printf("Data Char >> \t\t%c\n", data);
	number = (unsigned char)data;
	printf("Data Binary >> \t\t");
	for (i = 0; i < 8; i++)
	{
		printf("%d", (number & mask) == 0 ? 0 : 1);
		mask = mask >> 1;
	}
	printf("\n");

	printf("Key Char >> \t\t%c\n", key);
	mask = 1 << 7;		// 0000 0001 → 1000 0000
	number = (unsigned char)key;
	printf("Key Binary >> \t\t");
	for (i = 0; i < 8; i++)
	{
		printf("%d", (number & mask) == 0 ? 0 : 1);
		mask = mask >> 1;
	}
	printf("\n");

	printf("Encrpted Char >> \t%c\n", encrpted_data);
	mask = 1 << 7;		// 0000 0001 → 1000 0000
	number = (unsigned char)encrpted_data;
	printf("Encrpted Binary >> \t");
	for (i = 0; i < 8; i++)
	{
		printf("%d", (number & mask) == 0 ? 0 : 1);
		mask = mask >> 1;
	}
	printf("\n");

	printf("Key Char >> \t\t%c\n", key);
	mask = 1 << 7;		// 0000 0001 → 1000 0000
	number = (unsigned char)key;
	printf("Key Binary >> \t\t");
	for (i = 0; i < 8; i++)
	{
		printf("%d", (number & mask) == 0 ? 0 : 1);
		mask = mask >> 1;
	}
	printf("\n");

	char orig_data = encrpted_data ^ key;
	printf("Orig Char >> \t\t%c\n", orig_data);
	mask = 1 << 7;		// 0000 0001 → 1000 0000
	number = (unsigned char)orig_data;
	printf("Orig Binary >> \t\t");
	for (i = 0; i < 8; i++)
	{
		printf("%d", (number & mask) == 0 ? 0 : 1);
		mask = mask >> 1;
	}
	printf("\n");

	return 0;
}

 

p208. 중간점검

1️⃣. 내림 변환과 올림 변환을 설명하라.

 대입연산(=)시 두 피연산자의 자료형이 서로 다른 경우 rvalue가 lvalue의 자료형으로 자동 형변환된다.

 lvalue(변수)가 더 높은 등급의 자료형인 경우를 올림변환, 더 낮은 경우를 내림 변환이라고 한다.

 내림 변환의 경우, 데이터 손실이 발생하므로 warning message를 출력한다.

 int < unsigned int < long < unsigned long (정수)<<<(실수) float < double < long double

 

2️⃣. int형 변수 x를 double형으로 형변환하는 문장을 써보라.

 (double) x

3️⃣. 하나의 수식에 정수와 부동소수점수가 섞여 있으면 어떻게 되는가?

 정수가 double형으로 자동 승격된다.

 

단항 > NOT(! ~) > 산술 > 비트이동 > 관계(비교) > 비트(&|^) > 논리(&&||) > 대입 > ,

 

p214. 중간점검

1️⃣. 연산자 중에서 가장 우선 순위가 낮은 연산자는 무엇인가?

 ,

2️⃣. 논리 연산자인 &&과 || 중에서 우선 순위가 더 높은 연산자는 무엇인가?

 && (AND) ; NOT! > AND&& > OR||

3️⃣. 단항 연산자와 이항 연산자 중에서 어떤 연산자가 더 우선 순위가 높은가?

 단항 연산자

4️⃣. 관계 연산자와 산술 연산자 중에서 어떤 연산자가 더 우선 순위가 높은가?

 산술 연산자

 

p215. 중간점검

1️⃣. ((double)5 / (double)9) * (f_temp - 32);

 됨; double - (int) → (double) 

2️⃣. ((double)5 / 9) * (f_temp - 32);

 됨; double / (int) → (double)


p218. Exercise

1️⃣. 다음 중 우선 순위가 가장 높은 연산자는?

 ②증감연산자

 ; ②증감 > ③산술 > ①대입 > ④콤마

 단항 > NOT > 산술 > 비트이동 > 비교 > 비트 > 논리 > 대입 >  , 

2️⃣. 수식에서 어떤 연산자들이 먼저 계산되는지를 결정하는 것을 무엇이라고 하는가?

 ③우선순위

 ; ①피연산자Operand: 연산의 대상

  ②결과값Return value: Expression은 무조건 '값'을 낸다, 변수(x) 변수의 값(o)

  ④연산의부작용Side-effect: '부'정적(x) '부'수적(o)

3️⃣. 두 개의 피연산자가 모두 참인 경우에만 참이 되는 논리 연산자는?

 ①&& : AND 하나라도 거짓이면 결과값도 거짓

 ; ②|| : OR 하나라도 참이면 결과값도 참

  ③! : NOT(논리값) 참/거짓 반전

  ④>, ⑤< : 크기비교 크니? 작니?

4️⃣. 다음 중 올바른 대입식이 아닌 것은?

 ② 5 = x + y ; 해당 식은 좌변에 변수가 아닌 상수가 있음 

 POINT - lvalue must be 'variable'

5️⃣. 다음 수식의 값을 적으시오.

 ⒜ 1.500000 ; (double1.0 / double2.0 = double0.5) → (double1.0 + double0.5 = double1.5)

 ⒝ 1.000000 ; (int 1 / int 2 = int 0) → (double1.0 + int-double0 = double1.0)

 ⒞ 1.500000 ; (double1.0 / int-double2 = double0.5) → (double1.0 + double0.5 = double1.5)

 ⒟ 1.500000 ; (int-double1 / int-double2 = double0.5) → (double1.0 + double0.5 = double1.5)

   * 우선순위 : 형변환연산자 >> 산술연산자

6️⃣. 다음 중에서 조건 연산자를 올바르게 사용한 것은?

 ③

  ① a>b ? a : b

  ② a>b ? c=30 : □

  ③ max = a>b ? (a>c ? a : c) : b

   ; a가 b보다 크면, a와 c중에 큰 변수의 값을 max에 대입(assign)하기

    a가 b보다 작거나 같으면, b의 값을 max에 대입(assign)하기

    이중조건연산자? 무섭게 생겼지만, 말 됨 !

  ④ (a>b) ? ( a : b )

   ; (a>b) ? (a : b)는 a : b가 뭐선 말인지 컴파일러가 이해하지 못함 

7️⃣. 다음 프로그램의 출력은?

 -2, 3, 1, 1 + 개행

  ; i, j, k는 선증가 후 연산참여

   m = 1; m = ✔️-2 && ✔️3 && ✔️1 = ✔️참 = 1

8️⃣. 다음 프로그램의 출력은?

 2, 3, 3 + 개행

  ; 선감소 ( x = x - 1) x = 3 → (y = x) y = 3

   후감소 (z = x) z = 3 → (x = x - 1) x = 2 

9️⃣. 다음 수식의 결과는? 단 x는 16bit 정수이고 초기값은 0x1111이라고 가정한다.

 ⒜ 0x0; x AND (NOT x) 원래 비트와 반전된 비트 둘 다 1일 수는 없다.

 ⒝ 0xffff; x OR (NOT x) 원래 비트와 반전된 비트 둘 중에 하나는 무조건 1이다.

 ⒞ 0xffff; x XOR (NOT x) 원래 비트와 반전된 비트는 무조건 다르다.

 ⒟ 0xeeee; x XOR (0xffff) 0xffff는 모든 자리가 1이다, x의 비트가 1이면 0, 0이면 1이 된다

             ∴ 비트반전 ~x와 같다.

   16진수의 1자리 = 2진수의 4자리(4bit)

  ∴ x = 0x1111 = binary 0001 0001 0001 0001

  ~ x = 0xeeee = binary 1110 1110 1110 1110

short a = 0x1111;	// sizeof(short) = 2 (byte)
printf("%hx\n", a & ~a);
printf("%hx\n", a | ~a);
printf("%hx\n", a ^ ~a);
printf("%hx\n", a ^ 0xffff);

🔟. 아래의 수식이 계산되는 순서를 올바르게 나타낸 것은?

 ① ; (y * z / 8 % 2) → [ x + ( ) - 3 ] → z = [  ]

1️⃣1️⃣. 다음 프로그램의 출력은?

 80 + 개행

 ; 0002 0000 → 0200 0000 = 0x80 (0x20 × 4)

1️⃣2️⃣. 다음 프로그램의 출력은?

 1 + 개행

 ; c = 1 || ? = 1 (무조건 1)

1️⃣3️⃣. 다음 조건에 해당하는 논리 연산식을 만들어 보시오. 필요한 변수는 적절하게 선언하라.

 ⒜ 무주택 기간 3년이상이고 가구주의 연령이 40세 이상이고 가족의 수가 3명 이상이어야 한다.

  result = (year_homeless >= 3) && (age >= 40) && (people >= 3);

 ⒝ 놀이 기구를 타려면 나이는 6세이상, 키는 150cm 이상이어야 한다. 만약 150mm 미만이면 보호자 동반

  result = (age >= 6) && (height >= 150 || parent == 1);

  ; 일단 6살 이상이어야 함 && (키가 150이상이거나(1) ∪ 부모동반하에 탈 수 있음(1))

 ⒞ 평균 학점 3.0 이상이어야 한다. 또 토플 점수 300점 이상이거나 토익 700점 이상이어야 한다.

  result = (grade_avg >= 3.0) && (toefl>=300 || toeic>=700);


# 연산자 우선순위

# 자동형변환을 포함한 side-effect

p.220 Programming

1️⃣. 사용자로부터 2개의 정수를 입력받아서 첫 번째 정수를 두 번째 정수로 나누었을 때 얻게 되는 몫과 나머지를 출력하는 프로그램을 작성하라.

// 1. divide
int x, y;
printf("num1 ÷ num2 >>");
scanf("%d %d", &x, &y);
printf("result >> %d = %d * %d + %d\n", x, x / y, y, x % y);

2️⃣. 2개의 double형의 실수를 읽어서 합, 차, 곱, 몫을 구하는 프로그램을 작성하라.

// 2. + - * /		notice. double - %lf
double a, b;
printf("num1, num2 >>");
scanf("%lf %lf", &a, &b);
printf("sum %lf, sub %lf, mul %lf, div %lf\n", a + b, a - b, a * b, a / b);

3️⃣. 3개의 정수 값을 입력받아서, 3개의 정수 값 중에서 최대값을 출력하는 프로그램을 작성하라.

// 3. Max
int x, y, z;
printf("num1, num2, num3 >> ");
scanf("%d %d %d", &x, &y, &z);
printf("MAX: %d\n", (x>y ? (x>z ? x : z) : (y>z ? y : z)));

4️⃣. cm로 표현된 키를 입력하여 피트와 인치로 변환하는 프로그램을 작성하라.

// 4. cm > in, ft
const double CM_PER_IN = 2.54;
const double IN_PER_FT = 12;
double cm, ft, in;

printf("cm >> ");
scanf("%lf", &cm);
in = cm / CM_PER_IN;
ft = in / IN_PER_FT;
printf("%lfft, %lfin\n", ft, in);
// 책에 오타가 났네, 163 cm = 64.173228in = 5.347769ft

5️⃣. 100보다 작은 정수를 입력받아서 이것을 십의 자리, 일의 자리로 분리하여 출력하는 프로그램을 작성하라.

// 5. digit		* 자동형변환 이용
int x;
printf("num >> ");
scanf("%d", &x);
printf("%d0 + %d\n", x / 10, x % 10);

6️⃣. int형의 정수를 비트 연산자를 사용하여서 2의 보수(2's complement)로 변환하는 프로그램을 작성하여 보자.

// 6. decimal > binary
int x;
printf("num >> ");
scanf("%d", &x);
printf("%d\n", (~x)+1);

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

// 7. power?
int x, y;
printf("num * (2 ^ num2) >> ");
scanf("%d %d", &x, &y);
printf("%d * (2 ^ %d) = %d\n", x, y, x << y);

8️⃣. 구의 표면적과 체적을 구하는 프로그램을 작성하라.

// 8. volume, area of sphere
double radius, volume, area;
const double PI = 3.141592;
printf("radius: ");
scanf("%lf", &radius);
area = 4 * PI * radius * radius;
volume = 4 / 3.0 * PI * radius * radius * radius;
printf("area: %lf, volume: %lf\n", area, volume);

9️⃣. 그리스 최초의 수학자이자 천문학자인 탈레스(Thaies)는 지팡이 하나로 피라미드의 높이를 재었다고 한다. 탈레스는 지팡이를 똑바로 땅에 세우고 지팡이를 움직여서 지팡이의 그림자와 피라미드의 그림자를 일치시켰다. 삼각형 ABC와 삼각형ADE는 닮음꼴이므로 다음의 수식이 성립한다. 따라서 AC와 AE, BC를 안다면 DE를 계산할 수 있다. AC와 AE, BC를 입력하여서 DE를 구하는 프로그램을 작성하라. 입력되는 수치는 모두 실수로 한다.

// 9. height ?
double cane_height, cane_shade, pyramid_height, pyramid_shade;
printf("cane_height, cane_shade, pyramid_shade? _ _ _\b\b\b\b\b");
scanf("%lf %lf %lf", &cane_height, &cane_shade, &pyramid_shade);
pyramid_height = cane_height / cane_shade * pyramid_shade;
printf("pyramid_shade: %lf\n", pyramid_height);

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

// 10. cartesian coordinate system, which quadrant is it ?
double a, b;
printf("(x, y): ");
scanf("%lf", &a);
scanf("%lf", &b);
printf(" >> ");
(a == 0 && b == 0) ? printf("Line\n") : printf("");
(a > 0 && b > 0) ? printf("1st quadrant\n") : printf("");
(a < 0 && b > 0) ? printf("2nd quadrant\n") : printf("");
(a < 0 && b < 0) ? printf("3rd quadrant\n") : printf("");
(a > 0 && b < 0) ? printf("4th quadrant\n") : printf("");

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

// 11. radius of earth
double arc, angle, circumference_earth, radius_earth;
printf("arc(km), angle(˚): ");
scanf("%lf %lf", &arc, &angle);
circumference_earth = (360 / angle) * arc;
radius_earth = circumference_earth * 0.5 / 3.141592;
printf("radius_earth(km): %lf\n", radius_earth);

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

// 12. 4char > 1int
char a, b, c, d;
unsigned int result;
printf("_ _ _ _ ?");
scanf(" %c %c %c %c", &a, &b, &c, &d);
result = a;
result = b<<8 | result;
result = c<<16 | result;
result = d<<24 | result;
printf("result: %x\n", result);

 

 

 

반응형

블로그의 정보

노력하는 실버티어

노실언니

활동하기