연산자들

윤형찬·2020년 10월 26일
0

C++

목록 보기
3/10
post-thumbnail

연산자 우선순위와 결합 법칙

📍 C++에서는 제곱할 때 ^ 쓰면 안된다.(^는 XOR연산)
📍 cmath를 호출해서 pow 함수를 사용하면 된다.



산술연산자

  • 단항연산자는 붙여 쓰기!
int x = 1;
int y = 1 - -x;
  • 이항연산자 : "+", "-", "*"
  • "/"
    - 정수끼리 연산 : 몫을 출력한다
    - 실수끼리 연산 : 일반적으로 아는 대로 출력한다.
    - 연산결과가 x.5인경우는 절삭
cout << x / y << endl; 
cout << (float)x / y << endl;

1
1.75

  • %
    - 나눈 값의 몫을 제외한 나머지 값을 출력
  • z += y 랑 z = z + y 는 완벽히 같은 문장
    - +=, -=, *=, /- ...


증감 연산자

  • 증감 연산자가 앞에 쓰이면 선반영
  • 뒤에 쓰이면 라인이 마친 후 반영 (후반영)

예제1)

	int x(6), y(6);

	cout << x << " " << y << endl;
	cout << ++x << " " << --y << endl;

6 6
7 5

예제2)

	int x(6), y(6);

	cout << x << " " << y << endl;
	cout << x++ << " " << y-- << endl;
    	cout << x << " " << y << endl;

6 6
6 6
7 5

exer.cpp

	int x(6), y(6);

	cout << x << " " << y << endl;
	cout << x++ << " " << y-- << endl;
	cout << x << " " << y << endl;
	cout << x++ << " " << y-- << endl;
	cout << x << " " << y << endl;

6 6
6 6
7 5
7 5
8 4



sizeof, 쉼표 연산자, 조건부 연산자

  • sizeof : 자료형 byte 크기 알려준다.
    - sizeof(float);
    - sizeof a;

  • 쉼표 연산자
    - 일반적으로 for문에만 사용된다.
    - 단순한 구분기호로 사용될 때랑 구분을 할 수 있어야한다.
    - int z = (++x, ++y)++x; ++y; int z = y; 와 같다.

예제

	int x = 3;
	int y = 10;
	int z = (++x, ++y);

	cout << x << " " << y << " " << z << endl;

4 11 11

  • 조건부 연산자
    - if 문에서 상수를 사용하고 싶을 때 사용하기 좋다.

예제

const int price = (onSale == true) ? 10 : 100 ;

if (onSale)
	price = 10;
else
	price = 100;


관계 연산자

  • == : l-value와 r-value가 같은지 비교
  • != : l-value와 r-value가 다른지 비교
  • >= : l-value가 r-value보다 크거나 같은지 비교
  • <= 등등

부동소수점 비교 문제점 예제

	double d1(100 - 99.99);		// 0.01
	double d2(10 - 9.99);		// 0.01

	if (d1 == d2)
		cout << "equal" << endl;
	else
	{
		cout << "Not equal" << endl;

		if (d1 > d2) cout << "d1 > d2 " << endl;
		else //if(d1 < d2) because d1 != d2
			cout << "d1 < d2 " << endl;
	}
    	cout << d1 - d2 << endl;

Not equal
d1 > d2
5.32907e-15

✔ 미세하게 작게 차이가 나서 다르다고 나온다.
✔ 어느정도 차이까지 같다고 볼 지 정하고 코딩을 해야한다.



논리 연산자

  • ! : logical NOT
  • && : logical AND
  • || : logical OR
  • XOR 이 없어서 if(x != y) 로 대체하여 사용한다.

드모르간의 법칙

  • !(x || y); 와 !x && !y; 는 같다.

예제

bool hit = true;
int health = 10;

if (hit == true && health < 20)
{
	cout << "die " << endl;
}
else
	health -= 20;
logical AND 와 OR 의 우선순위 예제

	bool v1 = true;
	bool v2 = false;
	bool v3 = false;

	bool r1 = v1 || v2 && v3;
	bool r2 = (v1 || v2) && v3;
	bool r3 = v1 || (v2 && v3);

	cout << r1 << endl;
	cout << r2 << endl;
	cout << r3 << endl;

1
0
1

✔ AND연산자가 더 우선순위가 높다
✔ 괄호를 사용하여 헷갈리지 않도록 하자



비트단위 연산자

  • << : left shift
  • >> : right shift
  • ~ : NOT
  • & : AND
  • | : OR
  • ^ : XOR

예제 1)

#include <iostream>
#include <bitset>

int main()
{
	using namespace std;

	unsigned int a = 3;

	cout << std::bitset<8>(a) << " " << a << endl;
	cout << std::bitset<8>(a << 1) << " " << (a << 1) << endl;
	cout << std::bitset<8>(a << 2) << " " << (a << 2) << endl;
	cout << std::bitset<8>(a << 3) << " " << (a << 3) << endl;
	cout << std::bitset<8>(a << 4) << " " << (a << 4) << endl;

	return 0;
}

00000011 3
00000110 6
00001100 12
00011000 24
00110000 48

✔ a값 (3) * 2의 shift 횟수 제곱

예제 2)

#include <iostream>
#include <bitset>

int main()
{
	using namespace std;

	unsigned int a = 0b1100;
	unsigned int b = 0b0110;

	cout << std::bitset<4>(~a) << endl;		// bitwise NOT
	cout << std::bitset<4>(a & b) << endl;	// bitwise AND
	cout << std::bitset<4>(a | b) << endl;	// bitwise OR
	cout << std::bitset<4>(a ^ b) << endl;	// bitwise XOR

	return 0;
}

0011
0100
1110
1010



Bit flags, Bit masks 사용법

Bit flags

  • 예시)

    "아이템을 8개 소지 여부"를 표현하고 싶으면 변수를 8개 만들어도 되지만,
    1바이트 자료형에 true false로 구분하여 쉽게 표현 할 수 있다. (Bit flags 사용)
  • 적은 공간에 정보를 저장해야 하고, 빠른 속도가 필요할 때 사용합니다.

예제구성

  1. 8bit 자료형 char 로 items_flag 선언 및 0 으로 초기화
  2. 1은 소지, 0은 미소지
  3. 비트수에 맞게 opt0 ... opt7 초기화
  4. item N번 obtain, lost 시나리오 대로 예제 구성

예제

#include <iostream>
#include <bitset>

int main()
{
	const unsigned char opt0 = 1 << 0;
	const unsigned char opt1 = 1 << 1;
	const unsigned char opt2 = 1 << 2;
	const unsigned char opt3 = 1 << 3;
	// opt4, 5, 6, 7

	/*
	std::cout << std::bitset<8>(opt0) << std::endl;
	std::cout << std::bitset<8>(opt1) << std::endl;
	std::cout << std::bitset<8>(opt2) << std::endl;
	std::cout << std::bitset<8>(opt3) << std::endl;
	*/

	unsigned char items_flag = 0;
	std::cout << "NO item \t\t" << std::bitset<8>(items_flag) << std::endl;

	// item0 on
	items_flag |= opt0;
	std::cout << "Item0 obtained \t\t" << std::bitset<8>(items_flag) << std::endl;

	// item3 on
	items_flag |= opt3;
	std::cout << "Item3 obtained \t\t" << std::bitset<8>(items_flag) << std::endl;

	// item3 lost
	items_flag &= ~opt3;
	std::cout << "Item3 lost \t\t" << std::bitset<8>(items_flag) << std::endl;

	// has item1 ?
	if (items_flag & opt1) std::cout << "Has item1 \t\t" << std::endl;
	else std::cout << "Not have item1 \t\t" << std::endl;
	
	// obtain item 2, 3
	items_flag |= (opt2 | opt3);
	std::cout << "Item2, 3 Obtained \t" << std::bitset<8>(items_flag) << std::endl;

	// change item 2 to 1
	if ((items_flag & opt2) && !(items_flag & opt1))
	{
		/*items_flag ^= opt2;
		items_flag ^= opt1;*/
		items_flag ^= (opt1 | opt2);
	}
	std::cout << "change item 2 to 1 \t" << std::bitset<8>(items_flag) << std::endl;

	return 0;
}

NO item 00000000
Item0 obtained 00000001
Item3 obtained 00001001
Item3 lost 00000001
Not have item1
Item2, 3 Obtained 00001101
change item 2 to 1 00001011


Bit masks

  • 말을 뭐라써야하지
  • 설명이나 장점 써야함

예제 구성

  1. 16진수로 이루어진 수 3바이트 길이의 수를 1바이트씩 나눠서 의미를 두고 싶다.
  2. 0xFFFFFF를 예로 맨앞 2개는 Red, 중간 2개는 Green, 뒤 2개는 Blue로 구분짓고 싶다.
  3. 구분한 데이터는 1byte씩이므로 저장은 char자료형에 할 것이다.
  4. 24bit을 처리할 때 맨앞 2개와 중간 2개는 8bit을 초과한다.
  5. 중간인 Green을 예로 만약 0x115900이였으면 02가 Green의 값이 될 것인데 저장은 0101 1001 0000 0000으로 된다.
  6. Right Shift를 해주어서 필요한 8bit의 값만 남긴 후 char에 저장한다.

예제

#include <iostream>
#include <bitset>

int main()
{
	using namespace std;

	// 16진수 수 2개씩 끊어서 (8비트 = 1바이트) R G B 를 표현하려한다.
	const unsigned int red_mask = 0xFF0000;
	const unsigned int green_mask = 0x00FF00;
	const unsigned int blue_mask = 0x0000FF;

	unsigned int pixel_color = 0xDAA520;

	cout << std::bitset<32>(pixel_color) << endl;
	
	unsigned char red, green, blue;
	
	red = (pixel_color & red_mask) >> 16;
	green = (pixel_color & green_mask) >> 8;
	blue = pixel_color & blue_mask;

	cout << "red : \t" << bitset<8>(red) << " " << (int)red << endl;
	cout << "green : " << bitset<8>(green) << " " << (int)green << endl;
	cout << "blue : \t" << bitset<8>(blue) << " " << (int)blue << endl;

	return 0;
}

00000000110110101010010100100000
red : 11011010 218
green : 10100101 165
blue : 00100000 32

profile
https://github.com/velmash

0개의 댓글