본문 바로가기
Computer language

[Ch.03] 홍정모의 따라하며 배우는 C++ < 연산자들>

by IJustGo 2020. 9. 6.

CH.03 연산자들

3.1 연산자 우선순위와 결합 법칙(Operator Precedence and Associativity)

#include <iostream>
#include <cmath>

using namespace std;

int main()
{
	// 우선 순위가 같은 연산자들은 Left-to-right or Right-to-left 중에 알맞은 걸로 작동함.
	int x = 3 * 4 / 2;

	int y = std::pow(2, 3); //2의 3승
	cout << y << endl;
	
	return 0;
}

 

3.2 산술 연산자(arithmetic operators)

#include <iostream>
using namespace std;

int main()
{
	int x = 6;
	int y = 4;
	int z = x % y;
	
	cout << x / y << " " << z << endl;

	int x1 = 7;
	int y1 = 4;

	// 피연산자 두개 중 하나만 실수이면 결과값 실수 나옴.
	cout << x1 / y1 << endl;
	cout << float(x1) / y1 << endl;
	cout << x1 / float(y1) << endl;
	cout << float(x1) / float(y1) << endl;

	cout << -5 % 2 << endl; // 왼쪽 피연산자의 부호에 따라 결과값의 부호가 결정됨.

	int x2 = 7;
	int y2 = 4;
	int z2 = x2;
	z2 += y2; // z2 = z2 + y2; +=연산자는 코딩의 양도 줄고 그 덕에 보기도 편함.
			  // -=, /=, %=


	return 0;
}

 

 

 

 

 

 

 

 

 

3.3 증가/감소 연산자 (Increment/Decrement Operator)

#include <iostream>
using namespace std;

int add(int x, int y)
{
    return x + y;
}


int main()
{
    int x1 = 5;
    int y1 = ++x1;
    int z1 = x1++;
    
    cout << y1 << endl; // 6
    cout << z1 << endl; // 6

    // ++x, x++ 차이!!!! 중요@@
    // ++x는 더하고 다른 일 처리, x++는 다른 일 처리하고 더한다.
    int x = 6, y = 6;
    cout << x << " " << y << endl;
    cout << ++x << " " << --y << endl; // x에 1더하고 출력해서 7나옴
    cout << x << " " << y << endl; //x에 7 출력.
    cout << x++ << " " << y-- << endl; // x를 출력하고 1더함. 출력값은 7 x는 8.
    cout << x << " " << y << endl; // x에 8 출력.

    int x2 = 1, x3 = 1, y2 = 2;
    int v2 = add(x2, ++x2); //3이 나와야 하는데 4가 나옴. 이런 방식으로 코딩 X.
    int v3 = add(x3, ++y2); //이것은 문제 안생김. 두 개의 인자가 서로 영향을 안끼쳐서 그런듯.

    cout << v2 << endl;
    cout << v3 << endl;

    int x4 = 1;
    x4 = x4++; //이런식으로 코딩 X, 차라리 ++x4; x4++; 이용.


    return 0;
}

 

3.4 sizeof, 쉼표 연산자(Comma Operator), 조건(부) 연산자(Conditionnal Operator)

 

#include <iostream>
using namespace std;

// 굳이 아래의 conditional operator을 사용하지 않을려고 한다면 이런식으로 바로 const지정도 가능.
int getPrice(bool onSale)
{
    if (onSale)
        return 10;
    else
        return 100;
}

int main()
{
    using namespace std;

    float a1;
    
    // sizeof는 Operator이다. 
    sizeof(float); // 4Btyes = 32bits
    sizeof(a1); // sizeof a; 이것도 작동함(변수명만 가능). 아마 a는 피연산자로서의 역할이 가능한데 자료형은 불가능해서 안되는듯?

    // comma operator는 int z = (a,b)에서 a는 작동만하고 y가 대입됨. 평소엔 잘 안쓰고 복잡한 for문에서 자주 사용.
    int x = 3;
    int y = 10;
    // int z1 = (++x, ++y); 왼쪽의 comma operator 대신 아래 코드가 주로 사용.
    ++x;
    ++y;
    int z1 = y;

    cout << x << " " << y << " " << z1 << endl;

    int a2 = 1, b2 = 10;
    int z2;
    z2 = a2, b2;  // =의 Operator Precedence가 ,의 Operator Precedence보다 높아서 (z = a), b; 이런식을 처리 됨.

    cout << z2 << endl; // 1

    int a = 1, b = 10;
    int z;

    z = (++a, a + b);

    cout << z << endl; // 12
  
    
    bool onSale = true;

    // conditional operator (arithmetic if)
    // 만약 conditional operator를 이용하지 않고 일반적인 if else를 사용한다면 변수를 const로 바로 지정 못함.
    // 조건들이 복잡하다면 conditional operator를 사용하지 말자.
    const int price = (onSale == true) ? 10 : 100;

    /*if (onSale)
        price = 10;
    else
        price = 100;*/
    
    /* 굳이 conditional operator을 사용하지 않을려고 한다면 이런식으로 바로 const지정도 가능.
       const int price = int getPrice(onSale); */

    cout << price << endl;


    int x1 = 5;

    cout << ((x1 % 2 == 0) ? "even" : "odd") << endl; // conditional operator에서 : 양옆은 자료형이 같은걸 사용하자.

    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

3.5 관계 연산자(Relational Operators)

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

int main()
{
    int x, y;
    cin >> x >> y;
    cout << "Your input values are : " << x << " " << y << endl;

    if (x == y)
        cout << "equal" << endl;
    if (x != y)
        cout << "Not equal" << endl;
    if (x > y)
        cout << "x is greater than y" << endl;
    if (x > y)
        cout << "x is less than y" << endl;
    if (x >= y)
        cout << "x is greater than y or equal to y" << endl;
    if (x <= y)
        cout << "x is less than y or equal to y" << endl;

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

    cout << "d1 : " << d1 << " " << "d2 : " << d2 << endl;

    cout << std::abs(d1 - d2) << endl; //d1과 d2의 오차

    const double epsilon = 1e-10;

    if (std::abs(d1 - d2) < epsilon)
        cout << "Approximately equal" << endl;
    else
        cout << "Not equal" << endl;


    if (d1 == d2)
        cout << "equal" << endl;
    else
    {
        cout << "Not equal" << endl;
           
        if (d1 > d2) cout << "d1 > d2" << endl;
        else
            cout << "d1 < d2" << endl;
    }
    
    return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

3.6 논리 연산자(Logical Operators)

#include <iostream>
using namespace std;

int main()
{
	// logical NOT
	bool x1 = true;

	cout << !x1 << endl;


	// logical AND
	bool x2 = true;
	bool y2 = false;

	cout << (x2 && y2) << endl;


	// logical operater ex
	bool hit = true;
	int health = 10;

	if (hit == true && health < 20)
	{
		cout << "die " << endl;
	}
	else
		health -= 20;


	// logical OR
	bool x3 = true;
	bool y3 = false;

	cout << (x3 || y3) << endl;


	// 흔히 하는 실수
	// 대부분 (!x == y)는 (!(x == y))가 될거라고 생각
	// but ==보다 !가 operator precedence가 높아서 ((!x) == y)로 인식됨.
	/*
		int x = 4;
		int y = 7;
		
		if (!x == y)
		{
			cout << " x dose not equal y" << endl;
		}
		else
			cout << "x equals y " << endl;
	*/


	// logial OR ex
	// 이렇게 logical operator를 사용하면 표현이 더욱 간결해짐.
	// 그리고 logical operator를 더 많이 사용할 수는 있지만 보기 불편해서 잘 사용은 안함.
	int v = 1;
	
	if (v == 0 || v == 1)
		cout << "v is 0 or 1" << endl;

	// short circuit evaluation
	// logical AND operator은 왼쪽 항이 false면 오른쪽 항은 쳐다도 안봄.
	// x가 2이기때문에 if 조건문 안의 x == 1만 실행되고 y++ == 2는 실행 안됨.
	// x가 1이라면 y++ == 2가 실행돼서 y값이 3으로 변함.
	int x4 = 2;
	int y4 = 2;

	if (x4 == 1 && y4++ == 2)
	{
		// do something
	}

	cout << y4 << endl;


	// De Morgan`s Law
	bool x5 = true;
	bool y5 = false;

	!(x5 && y5); // !x || !y; 두개가 같음.

	// XOR(exclusive OR) 둘이 배타적(다르면) true, 둘이 배타적이지 않으면(같으면) false
	// cpp에선 XOP operator 존재 X, 그래서 (x != y)로 대체
	// false false false
	// false ture true
	// ture false true
	// true true flase


	// 흔히 1번과 2번은 같다고 생각하는데 출력값이 다르다.
	// 왜냐하면 OR연산자보다 AND연산자가 PRECEDENCE가 높기 때문에 1번은 3번과 같은게 된다.
	bool v1 = true;
	bool v2 = false;
	bool v3 = false;

	// 1.
	bool r1 = v1 || v2 && v3;
	// 2.
	bool r2 = (v1 || v2) && v3;
	// 3.
	bool r3 = v1 || (v2 && v3);

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

	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

3.8 비트단위 연산자(Bitwise Operators)

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

int main()
{

    // left shift를 한번 할 때마다 정수값이 2배씩 증가.
    // 1번은 a * 2^1, 2번은 a * 2^2, 3번은 a * 2^3, ....
    unsigned int a = 3;

    cout << std::bitset<4>(a) << endl;
    
    unsigned int b = a << 1;

    cout << std::bitset<4>(b) << " " << b << endl;

    cout << std::bitset<8>(a) << endl;

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


    // Right shift를 한번 할 때마다 정수값이 2배씩 감소.
    // 1번은 a * 2^-1, 2번은 a * 2^-2, 3번은 a * 2^-3, ....
    unsigned int a1 = 1024;

    cout << std::bitset<16>(a1) << endl;

    cout << std::bitset<16>(a1 >> 1) << " " << (a1 >> 1) << endl; // 1
    cout << std::bitset<16>(a1 >> 2) << " " << (a1 >> 2) << endl; // 2
    cout << std::bitset<16>(a1 >> 3) << " " << (a1 >> 3) << endl; // 3
    cout << std::bitset<16>(a1 >> 4) << " " << (a1 >> 4) << endl; // 4


    // Bitwise not
    unsigned int a2 = 1024;

    cout << std::bitset<16>(a2) << endl;
    cout << std::bitset<16>(~a2) << " " << endl;

   
    /******************************************************/
    unsigned int a3 = 0b1100;
    unsigned int b3 = 0b0110;

    cout << std::bitset<4>(a3 & b3) << endl;   // Bitwise AND
    cout << std::bitset<4>(a3 | b3) << endl;   // Bitwise OR
    cout << std::bitset<4>(a3 ^ b3) << endl;   // Bitwise XOR

    a3 &= b3;

    cout << std::bitset<4>(a3) << endl;

    return 0;
}

<<, left shift

>>, right shift

~, not 

&, and

|, or

^, xor

 

3.9 비트 플래그(Flag), 비트 마스크(Mask)

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

int main()
{

	// ************ Bit Flag ***************

	//item 8개를 표현할려면 bool type 8개를 만들고 변수값을 계속 변경해야함.
	//but 아래 방법을 이용하면 char type 1개의 변수값만 계속 변경함.
	/*bool item1_flag = false;
	bool item2_flag = false;
	bool item3_flag = false;
	bool item4_flag = false;*/

	const unsigned char opt0 = 1 << 0;
	const unsigned char opt1 = 1 << 1;
	const unsigned char opt2 = 1 << 2;
	const unsigned char opt3 = 1 << 3;

	cout << bitset<8>(opt0) << endl;
	cout << bitset<8>(opt1) << endl;
	cout << bitset<8>(opt2) << endl;
	cout << bitset<8>(opt3) << endl;

	unsigned char items_flag = 0;

	cout << "No item " << bitset<8>(items_flag) << endl;

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

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

	// item3 off
	items_flag &= ~opt3;
	cout << "Item3 lost " << bitset<8>(items_flag) << endl;

	// has item1 ?
	if (items_flag & opt1) { cout << "Has item1" << endl; }
	else { cout << "Not have item1" << endl; }
	 
	// has item0 ?
	if (items_flag & opt0) { cout << "Has item0" << endl; }
	else { cout << "Not have item0" << endl; }

	// obtain item 2, 3
	items_flag |= (opt2 | opt3);

	cout << bitset<8>(opt2 | opt3) << endl;
	cout << "Item2, 3 obtained " << bitset<8>(items_flag) << endl;

	if ((items_flag & opt2) && !(items_flag & opt1))
	{
		items_flag ^= (opt2 | opt1);
	}

	cout << bitset<8>(items_flag) << endl;


	// ************ Bit Mask ***************
	
	const unsigned int red_mask = 0xFF0000;
	const unsigned int green_mask = 0x00FF00;
	const unsigned int blue_mask = 0x0000FF;

	cout << std::bitset<32>(red_mask) << endl;
	cout << std::bitset<32>(green_mask) << endl;
	cout << std::bitset<32>(blue_mask) << endl;

	unsigned int pixel_color = 0xDAA520;

	cout << std::bitset<32>(pixel_color) << endl;

	unsigned char red, green, blue;

	blue = pixel_color & blue_mask;

	cout << "blue " << std::bitset<8>(blue) << " " << int(blue) << endl;

	green = (pixel_color & green_mask) >> 8;

	cout << "green " << std::bitset<8>(green) << " " << int(green) << endl;

	red = (pixel_color & red_mask) >> 16;

	cout << "red " << std::bitset<8>(red) << " " << int(red) << endl;

	return 0;
}

 

practice