본문 바로가기
C++/뇌를 자극하는 C++

[C++] 챕터 6 - 연산자 : 정보를 가공하는 법

by Minkyu Lee 2023. 4. 21.

// 6-1 : 사칙연산

int 타입의 +, -, *, /, %에 대해 알아본다.
연산자의 대상이 되는 애들을 피연산자라고 한다.

 

// 6-2 : 대입 연산자

int main()
{
	int a, b, c;
	a = b = c = 100;
	return 0;
}
/*
c = 100이 제일 먼저 실행된다.
a,b,c 모두 100이 된다.
*/

 

// 6-3 : 관계 연산자

#include <iostream>
using namespace std;

int main()
{
	int a = 3;
	int b = 5;

	bool b1, b2, b3, b4, b5, b6;
	b1 = a > b;
	b2 = a >= b;
	// ... 생략
	b6 = a != b;

	cout << boolalpha; // true, false로 출력하게 만듬
	cout << b1 << "\n";
	cout << b6;

	return 0;
}

/*
관계연산자 총 6가지
>, >=, <, <=, ==, !=
*/

 

// 6-4 : AND 연산자

#include <iostream>
using namespace std;

int main()
{
	bool b1, b2, b3, b4;
	b1 = false && false;
	b2 = false && true;
	b3 = true && false;
	b4 = true && true;

	cout << boolalpha;

	cout << b1 << "\n";
	cout << b2 << "\n";
	cout << b3 << "\n";
	cout << b4 << "\n";

	return 0;
}
/*
논리 연산자
and or not이 있다.
&&, ||, !

b4만 true가 된다.
*/

 

// 6-5 : 관계 연산자, 논리 연산자 함께 사용

#include <iostream>
using namespace std;

int main()
{
	int age;
	bool male;

	age = 20;
	male = true;

	bool ok;
	ok = age > 19 && male == true;
	cout << boolalpha;
	cout << ok;
	return 0;
}
/*
결과는 true

&&는 ||보다 우선순위가 높다.
한 문장에 함께 사용시 주의 필요.
*/

 

// 6-6 : AND, OR 연산자 함께 사용

#include <iostream>
using namespace std;

int main()
{
	int height;
	float eyesight;

	height = 175;
	eyesight = 0.8f;

	bool ok;
	ok = height >= 160 && height <= 180 ||
		eyesight >= 1.0f && eyesight <= 2.0f;
	cout << boolalpha << ok;
	return 0;
}
/*
키가 160이상이고 180이하이거나
시력이 1.0이상이고 2.0이하인 경우 참

키나 시력 중 하나라도 만족하면 참이다.

*/

 

// 6-7 : NOT 연산자

!true는 false가 된다.
!false는 true가 된다.

 

// 6-8 : 정수를 2진수로 출력

#include <bitset> // 2진수로 출력하기 위해서 bitset 클래스 사용
#include <iostream>
using namespace std;

int main()
{
	char c = 1;
	short int si = 2;
	int i = 4;

	cout << bitset<8>(c) << "\t" << (int)c << "\n";
	cout << bitset<16>(si) << "\t" << si << "\n";
	cout << bitset<32>(i) << "\t" << i << "\n";
	return 0;
}

/*
bitset 사용시 변수의 크기를 적어주어야함
char은 8비트라서 <8>
short int는 16비트라서 <16>
...
*/

 

// 6-9 : 비트 단위 논리 연산자

#include <bitset> // 2진수로 출력하기 위해서 bitset 클래스 사용
#include <iostream>
using namespace std;

int main()
{
	unsigned char a, b;
	a = 178;
	b = 113;

	// 비트 단위 논리 연산 수행
	unsigned char c1, c2, c3, c4;
	c1 = a & b; // AND
	c2 = a | b; // OR
	c3 = a ^ b; // XOR, 베타적 논리합. 같으면 0 다르면 1
	c4 = ~a; // NOT

	// 출력
	cout << bitset<8>(a) << "\t" << (unsigned int)a << "\n";
	cout << bitset<8>(b) << "\t" << (unsigned int)b << "\n";

	cout << bitset<8>(c1) << "\t" << (unsigned int)c1 << "\n";
	cout << bitset<8>(c2) << "\t" << (unsigned int)c2 << "\n";
	cout << bitset<8>(c3) << "\t" << (unsigned int)c3 << "\n";
	cout << bitset<8>(c4) << "\t" << (unsigned int)c4 << "\n";
	return 0;
}
/*
비트 단위 논리 연산자의 사용
어디에 써먹나? 16비트의 unsigned short 변수에 색상 중, 파란색만 추출할 때 등.

10진수 출력 결과를 보면 의미없음
2진수 결과를 보고 비교해보면 됨

--- 결과 ---
10110010        178
01110001        113

00110000        48		(&, AND)
11110011        243		(|, OR)
11000011        195		(^, XOR)
01001101        77		(~, NOT)

*/

 

// 6-10 : 파란색 값 추출

#include <bitset>
#include <iostream>
using namespace std;

int main()
{
	unsigned short color = 0x1234; // 0x는 16진수를 의미. 한 점의 색상을 보관하는 변수. 임의의 값.

	// 파란색만 남김
	unsigned short blue;
	blue = color & 0x001f; // 파란색이 위치하는 오른쪽 다섯 개의 비트만 1이 됨

	// 출력
	cout << bitset<16>(color) << "\t" << color << "\n";
	cout << bitset<16>(blue) << "\t" << blue << "\n";

	return 0;
}

/*
0001001000110100        4660
0000000000010100        20

이런 용도의 비트 단위 AND 연산을 '마스킹'이라고 부른다.
*/

 

// 6-11 : 녹색 값 추출

#include <bitset>
#include <iostream>
using namespace std;

int main()
{
	unsigned short color = 0x1234;

	/* 녹색 제외 나머지 지움.
	0x07e0은 2진수로 0000 0111 1110 0000
	파란색은 끝에서 5자리면. 녹색은 중앙 6자리다. R G B 가 각각 5 6 5로 보통 할당.
	눈은 녹색에 가장 예민하다. */
	unsigned short green_temp;
	green_temp = color & 0x07e0;

	// 녹색 비트들을 오른쪽 끝으로 이동.
	unsigned short green;
	green = green_temp >> 5;

	// 출력
	cout << bitset<16>(color) << "\t" << color << "\n";
	cout << bitset<16>(green_temp) << "\t" << green_temp << "\n";
	cout << bitset<16>(green) << "\t" << green << "\n";

	return 0;
}

/*
0001 0010 0011 0100        4660
0000 0010 0010 0000        544
0000 0000 0001 0001        17

보기쉽게 임의로 4자리씩 띄움
마지막에 쉬프트한 결과보면, 오른쪽으로 5칸 이동해서 맨끝이 1이 된 것에 주목.
왼쪽 5칸은 0으로 채워짐.
*/

 

// 6-12 : 빨간색 값 변경

#include <bitset>
#include <iostream>
using namespace std;
int main()
{
	unsigned short color = 0x1234;

	// 빨간색 부분 비트를 0으로 만든다.
	unsigned short color_temp;
	color_temp = color & 0x07ff; // 2진수로 0000 0111 1111 1111 이다.

	// 새 빨간색 값을 준비하고 왼쪽 끝으로 옮긴다.
	unsigned short red = 30;
	unsigned short red_temp;
	red_temp = red << 11;

	// 값을 넣는다.
	unsigned short color_finished;
	color_finished = color_temp | red_temp;

	cout << bitset<16>(color) << "\n";
	cout << bitset<16>(color_temp) << "\n";
	cout << bitset<16>(red) << "\n";
	cout << bitset<16>(red_temp) << "\n";
	cout << bitset<16>(color_finished) << "\n";

	return 0;
}
/*
결과
0001001000110100
0000001000110100
0000000000011110
1111000000000000
1111001000110100
*/

 

// 6-13 : 부호 있는 값 쉬프트

#include <bitset>
#include <iostream>
using namespace std;

int main() 
{
	unsigned short us = 0xff00;
	short s = (short)0xff00;
	
	unsigned short us_shift = us >> 4;
	unsigned short s_shift = s >> 4;

	cout << bitset<16>(us) << "\t" << bitset<16>(us_shift) << "\n";
	cout << bitset<16>(s) << "\t" << bitset<16>(s_shift) << "\n";

	return 0;
}
/*
부호있는 값의 쉬프트

--- 결과 ---
1111111100000000        0000111111110000
1111111100000000        1111111111110000
*/

 

// 6-14 : ++, -- 연산자 사용

#include <iostream>
using namespace std;

int main()
{
	// 동일한
	int A, B, C, D;
	A = B = C = D = 3;

	int ppA, Bpp, mmC, Dmm;
	ppA = ++A;
	Bpp = B++;
	mmC = --C;
	Dmm = D--;

	cout << A << B << C << D << "\n";
	cout << ppA << Bpp << mmC << Dmm;

	return 0;
}

/*
--- 결과 ---
4422
4323

A,B,C,D 변수의 값이 바뀌었다.
모두 연산결과가 대입된 것을 볼 수 있다.

하지만 A,B,C,D를 바탕으로 만든 ppA, Bpp, mmC, Dmm의 값은 차이가 있다.
전치 연산은 대입됨
후치 연산은 대입되지 않음

따라서 실수를 막기 위해서,
의도적으로 대입되지 않는 상황이 아니라면
습관적으로 전치 연산 쓰는게 좋겠다.
*/

 

// 6-15 : 연산 중 발생하는 형변환

#include <iostream>
using namespace std;

int main()
{
	int i = 10;
	float f = 10.0f;

	float i_div_4, f_div_4;
	i_div_4 = i / 4;
	f_div_4 = f / 4;

	cout << i << "\t" << i_div_4 << "\n";
	cout << f << "\t" << f_div_4 << "\n";

	return 0;
}

/*
10      2
10      2.5

결과를 받는 변수의 타입은 무시되었다. (i_div_4)
피연산자 타입으로 결과가 대입된다. (i)
*/

댓글