profile image

L o a d i n g . . .

반응형

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

연산자 종류 및 우선순위
https://ko.wikipedia.org/wiki/C%EC%99%80_C%2B%2B%EC%9D%98_%EC%97%B0%EC%82%B0%EC%9E%90

 

C와 C++의 연산자 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 둘러보기로 가기 검색하러 가기 이것은 C와 C++ 프로그래밍 언어의 연산자의 목록이다. 나열된 모든 연산자는 C++에 존재한다. 네번째 열("C에 포함됨")은 해당 연산자가 C에 존재하는지를 표시한다. C는 연산자 오버로딩을 지원하지 않는다. 연산자가 오버로드되지 않았다면, &&, ||, ,(쉼표 연산자) 연산자는 첫 번째 피연산자(operand)가 평가된 시점이 시퀀스 포인트이다. C++는 형 변환 연산자인 const_

ko.wikipedia.org

#include <iostream>
#include <cmath>

int main()
{
	using namespace std;

	// 수식이 들어오면 어느 쪽을 먼저 계산할지 결정한다.
	// 필요한 경우 괄호를 사용해서 우선순위를 명확하게 남기자.
	int x = 4 + 2 * 3;	// * 먼저
	int y = 3 * 4 / 2;	// *와 /는 우선순위가 같음, Associativity

	int z = std::pow(2, 3);	// 2의 세제곱
	cout << z << endl;

	return 0;
}
#include <iostream>

int main()
{
	using namespace std;
/*
    r = 1 + 2 + 3 * 4;
1.              3 * 4
2.          2 + 12
3.      1 + 14
4.  r = 15

    a = b = c;
1.      b = c
2.  a = b

    t /= --w + 5;
1.       --w
2.         w + 5
3.  t /= (w + 5)

    a || b && c || d;
1.       b && c
2.  a ||
3.              || d
*/
	return 0;
}

 

 

산술 연산자 arithmetic operators

#include <iostream>

int main()
{
	using namespace std;

	int x = 7;
	int y = -x;	// -x: x의 sign 변경
	int a = 4;
	int z = x % a;	// %: 나머지 계산

	// 정수 나머지와 실수 나머지, 둘 중 하나만 실수여도 결과는 실수!
	cout << x / a << endl;	// 1
	cout << float(x) / a << endl;	// 1.75
	cout << x / float(a) << endl;	// 1.75
	cout << float(x) / float(a) << endl;	// 1.75

	
	cout << -5 / 2 << endl;	// c++ 11부터는 뒤를 버림, -2.5 => -2 출력
	cout << -5 % 2 << endl;	// 나머지의 경우 왼쪽의 부호를 따라감

	int b = x;	// 대입 연산자
	b += a;	// == b = b + a;
	b -= a;	// == b = b - a;
	b *= a;	// == b = b * a;
	b /= a;	// == b = b / a;
	b %= a;	// == b = b % a;

	return 0;
}

 

 

증감 연산자 increment decrement operators

#include <iostream>

int add(int a, int b)
{
	return a + b;
}

int main()
{
	using namespace std;

	int x = 5;
	int y = --x;
	int z = x--;

	cout << y << endl;	// 4
	cout << z << endl;	// 4

	// ++a의 경우, a에 먼저 1을 더하고 출력
	// a++의 경우, a를 먼저 출력하고 1을 더함
	int a = 6, b = 6;
	cout << a << " " << b << endl;		// 6 6
	cout << ++a << " " << --b << endl;	// 7 5
	cout << a << " " << b << endl;		// 7 5
	cout << a++ << " " << b-- << endl;	// 7 5
	cout << a << " " << b << endl;		// 8 4


	int e = 1;
	int v = add(e, ++e);	// do not use
	int f = 2;
	int v2 = add(e, ++f);

	cout << v << " " << v2 << endl;


	int g = 1;
	//g = g++;	do not use
	++g;

	return 0;
}

 

 

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

#include <iostream>

int main()
{
	using namespace std;

	// sizeof: 데이터형의 크기를 알고 싶을 때 사용한다. 단위-바이트
	// structure, class 등 사용자가 만든 자료형에도 사용 가능하다.
	// sizeof는 '연산자'
	float f;
	
	sizeof(float);
	sizeof(f);
	sizeof f;	// 변수명일 경우 괄호가 없어도 작동함
	

	// comma operator: 반복문(for문)에서 유용하게 사용함
	int x = 3;
	int y = 10;
	//int z = (++x, ++y);
	++x;
	++y;
	int z = y;

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


	// 선언에 사용된 콤마는 구분해 주는 기호 ex: sum(1, 2);
	int a = 1, b = 10;
	int c;

	// 콤마 연산자의 우선순위가 대입 연산자보다 낮기 때문에 대입이 먼저 진행된다.
	//c = a, b;
	c = (a, b);

	cout << a << " " << b << " " << c << endl;


	// 조건 연산자 conditional operator (arithmetic if)
	bool onSale = true;
	int price;

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

	cout << price << endl;

	// if문을 사용하려면 따로 함수를 만들어서 이용하면 됨
	// 조건이나 결과값이 복잡한 경우, if문으로 쪼개서 구현하는 게 읽기 쉽고 디버깅이 편함
	const int price2 = (onSale == true)? 10 : 100;
	
	cout << price2 << endl;


	// 연산자 우선순위 때문에 조건 연산자를 출력할 경우 괄호 처리해야 함
	int xx = 5;
	cout << ((xx % 2 == 0) ? "even" : "odd") << endl;


	return 0;
}

 

 

관계 연산자 relational operators

#include <iostream>
#include <cmath>

int main()
{
	using namespace std;

	/*while (true)
	{*/
		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.01
		double d2(10 - 9.99);	// 0.01

		cout << d1 << " " << d2 << endl;
		cout << d1 - d2 << endl;

		if (d1 == d2)
			cout << "equal" << endl;
		else 
		{
			cout << "not equal" << endl;
			if (d1 > d2) cout << "d1 > d2" << endl;
			else	// if(d1 < d2) 
				cout << "d1 < d2" << endl;	
		}

		cout << std::abs(d1 - d2) << endl;	// 아주 미세한 차이가 남

		// 오차의 차이를 미리 정의해 비교한다.
		// epsilon 결정: 그때그때 다르게 결정해야 한다...
		const double epsilon = 1e-10;

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


	return 0;
}

 

 

논리 연산자 logical operators

#include <iostream>

int main()
{
	using namespace std;

	// logical NOT !x
	bool x = true;

	cout << !x << endl;


	// logical AND &&
	bool a = true;
	bool b = false;

	cout << (a && b) << endl;


	bool hit = true;
	int health = 10;

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


	// logical OR ||
	cout << (a || b) << endl;


	return 0;
}
#include <iostream>

int main()
{
	using namespace std;

	int x = 5;
	int y = 7;

	if (x != y)	//!x == y => !x의 우선순위가 더 높음, !(x == y)
	{
		cout << "x does not equal y" << endl;
	}
	else
		cout << "x equals y" << endl;


	int v = 1;

	if (v == 0 || v == 1)
		cout << "v is 0 or 1" << endl;


	// short circuit evaluation
	int a = 1;
	int b = 2;

	// AND는 왼쪽을 먼저 계산한 후, false라면 오른쪽을 계산하지 않음
	// 따라서 a가 1이 아닌 경우, b에 ++ 처리가 되지 않아 결과적으로 2가 출력됨
	if (a == 1 && b++ == 2)
	{
		// do something
	}

	cout << b << endl;


	bool c = true;
	bool d = false;

	// De Morgan's Law
	!(c && d);	// == !c || !d;
	!c && !d;	// == !(c || d);

	// XOR: C++에 존재하지 않음
	// false false	> false
	// false true	> true
	// true false	> true
	// true true	> false

	if (c != d)	// c와 d가 bool 타입이어야 함
	{

	}


	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;

	return 0;
}
#include <iostream>

int main()
{
	using namespace std;

/*
    (true && true) || false
1.            true || false
2.                true

    (false && true) || true
1.            false || true
2.                 true

    (false && true) || false || true
1.            false || false || true
2.                     false || true
3.                          true

    (14 > 13 || 2 > 1) && (9 > 1)
1.     (true ||  true) && true
2.                true && true
3.                    true

    !(2314123 > 2 || 123123 > 2387)
1.         !(true || 123123 > 2387)
2.         !(true || true)
3.         !(    true    )
4.              false

*/

	return 0;
}

 

 

이진수 binary numbers

#include <iostream>

int main()
{
	using namespace std;

	/*
	0
	1
	2
	3
	4
	5
	6
	7
	8
	9
	10 = 10^1 + 0
	11 = 10^1 + 1
	12
	...
	337 = 300 + 30 + 7 = 10^2 * 3 + 10^1 * 3 + 10^0 * 7


	0
	1
	10 = 2^1 * 1 + 2^0 * 0 = 2
	11 = 2^1 * 1 + 2^0 * 1 = 3
	
	  11
	+  1
	------
	 100


	 << 2진수 -> 10진수 >>
	 int(4바이트) => 2진수 자리수가 32개
	 편의상 1바이트 숫자로 계산함

	 7654 3210 [자리]
	 0101 1110

	   2^7 * 0 + 2^6 * 1 + 2^5 * 0 + 2^4 * 1
	  +2^3 * 1 + 2^2 * 1 + 2^1 * 1 + 2^0 * 0
	 = 128*0 + 64*1 + 32*0 + 16*1 + 8*1 + 4*1 + 2*1 + 1*0
	 = 64 + 16 + 8 + 4 + 2
	 = 94


	 << 10진수 -> 2진수 >>
	 148 (decimal to binary)

	 1.
	 148 / 2 = 74 r0 (r = remainder)
	 74  / 2 = 37 r0
	 37  / 2 = 18 r1
	 18  / 2 = 9  r0
	 9   / 2 = 4  r1
	 4   / 2 = 2  r0
	 2   / 2 = 1  r0
	 1   / 2 = 0  r1

	 1001 0100


	 2. 
	 1 2 4 8 16 32 64 128 256 512 1024 ...
	            148 >= 128 Yes -> 128=2^7, 8번째 자리가 1
	 148-128=20, 20 >= 64  No  -> 64 =2^6, 7번쨰 자리가 0
	             20 >= 32  No  -> 32 =2^5, 6번째 자리가 0
				 20 >= 16  Yes -> 16 =2^4, 5번째 자리가 1
	 20-16=4   ,  4 >= 8   No  -> 8  =2^3, 4번째 자리가 0
	              4 >= 4   Yes -> 4  =2^2, 3번째 자리가 1
	 4-4=0  <끝>

	 1001 0100



	 << 2진수끼리 덧셈 >>

	 11
	 0110 (6 in decimal)
	 0111 (7 in decimal)
	 ------
	 1101 = 13 in decimal



	 << 음의 정수 >>

	 -5

	 부호 생각하지 말고 2진수 변환
	 0000 0101

	 보수 complement
	 1111 1010

	 1 더하기
	 1111 1011

	 signed integer인 경우, 맨 앞 자리는 부호비트! (0: 양수, 1: 음수)
	 

	          0은 0000 0000
	 보수를 취하면 1111 1111 <= 0이 두 개 돼 버림
	 그래서 마지막에 1을 더함! 음의 정수로서 0을 구해도 똑같은 0000 0000이 나옴


	 음->양
	 signed integer
	 1001 1110
	 0110 0001 (보수)
	 0110 0010 (1을 더함) -> 98 -> -98(원래 부호)


	 signed vs unsigned
	 1001 1110(signed) -> 2^7*1 + 2^4*1 + 2^3*1 + 2^2*1 + 2^2*1
	                   = 128 + 16 + 8 + 4 + 2
	 같은 2진수라도 signed와 unsigned 차이가 크게 남!
	*/

	return 0;
}

 

 

비트단위 연산자 bitwise operators

1. 메모리를 아끼고(꽉꽉 채워 넣음) 의미 있게 사용하기 위해서, 2. 계산 속도

#include <iostream>
#include <bitset>

int main()
{
	using namespace std;

	// cout, cin에서 사용하는 >> <<와는 다르다! (연산자 오버로딩)
	// <<	left shift
	// >>	right shift
	// ~(NOT), &(AND), |(OR), ^(XOR)

	unsigned int a = 3;
	cout << a << "\t" << std::bitset<8>(a) << endl;	// 3 00000011

	unsigned int b = a << 1;
	cout << b << "\t" << std::bitset<8>(b) << endl;	// 6 00000110

	cout << (a << 2) << "\t" << std::bitset<8>(a << 2) << endl;	// 12 00001100
	cout << (a << 3) << "\t" << std::bitset<8>(a << 3) << endl;	// 24 00011000
	cout << (a << 4) << "\t" << std::bitset<8>(a << 4) << endl;	// 48 00110000
	cout << endl;

	unsigned int c = 1024;
	cout << c << "\t" << std::bitset<16>(c) << endl;

	cout << (c >> 1) << "\t" << std::bitset<16>(c >> 1) << endl;
	cout << (c >> 2) << "\t" << std::bitset<16>(c >> 2) << endl;
	cout << (c >> 3) << "\t" << std::bitset<16>(c >> 3) << endl;
	cout << (c >> 4) << "\t" << std::bitset<16>(c >> 4) << endl;
	cout << endl;


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


	unsigned int d = 0b1100;
	unsigned int e = 0b0110;

	cout << d << " " << e << endl;
	cout << std::bitset<4>(d & e) << endl;	// bitwise AND
	cout << std::bitset<4>(d | e) << endl;	// bitwise OR
	cout << std::bitset<4>(d ^ e) << endl;	// bitwise XOR

	d = d & e;
	d &= e;
	
	return 0;
}

 

 

 

비트 플래그, 비트 마스크 사용법 bit flags, bit masks

#include <iostream>
#include <bitset>

int main()
{
	using namespace std;

	/*
	bool item1_flag = false;
	bool item2_flag = false;
	bool item3_flag = false;
	bool item4_flag = false;

	// event!
	item1_flag = true;

	// die item2 lost
	item2_flag = false;

	if (item3_flag == true)
	{
		// event
	}

	if (item3_flag == true && item4_flag == false)
	{
		item3_flag = false;
		item4_flag = true;
	}

	invokeEvent(item1_flag, item2_flag, item3_flag...); ?!

	*/

	// 아이템 8개를 가지고 있는지를 1바이트로 알 수 있게끔!
	// bool 타입 8개를 선언할 필요가 없어진다!

	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

	cout << bitset<8>(opt0) << endl;	// 0000 0001
	cout << bitset<8>(opt1) << endl;	// 0000 0010
	cout << bitset<8>(opt2) << endl;	// 0000 0100
	cout << bitset<8>(opt3) << endl;	// 0000 1000


	unsigned char items_flag = 0;
	cout << "No item " << bitset<8>(items_flag) << endl;	// 0000 0000

	// 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 lost
	items_flag &= ~opt3;
	cout << "Item3 lost " << bitset<8>(items_flag) << endl;

	// has item1?
	// opt1 해당 자리 이진수 숫자가 1이면 true 반환
	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;

	// 2는 가지고 있고, 1은 가지고 있지 않을 경우
	if ((items_flag & opt2) && !(items_flag & opt1))
	{
		// 상태를 변경
		items_flag ^= opt2;
		items_flag ^= opt1;
		// 한꺼번에 처리~ items_flag ^= (opt2 | opt1);
	}

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

	return 0;
}

#include <iostream>
#include <bitset>

int main()
{
	using namespace std;

	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;

	// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	// 수많은 옵션을 파라미터로 전부 넣기는 힘들다...
	// 비트 연산자를 사용하면 간편함

	unsigned int pixel_color = 0xDAA520;

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

	unsigned char red = (pixel_color & red_mask) >> 16;
	unsigned char green = (pixel_color & green_mask) >> 8;
	unsigned char blue = pixel_color & blue_mask;

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

	return 0;
}

#include <iostream>
#include <bitset>
/*
기사를 봤을 때
기사의 좋아요를 클릭했을 때
기사의 좋아요를 다시 클릭했을 때
본 기사만 삭제할 때
*/
int main()
{
	using namespace std;

	unsigned char option_viewed	 = 0x01;
	unsigned char option_edited	 = 0x02;
	unsigned char option_liked	 = 0x04;
	unsigned char option_shared	 = 0x08;
	unsigned char option_deleted = 0x80;

	unsigned char my_article_flags = 0;
	cout << std::bitset<8>(my_article_flags) << endl;

	// code here

	// 기사를 봤을 때
	my_article_flags |= option_viewed;
	cout << "기사 보기: \t" << std::bitset<8>(my_article_flags) << endl;

	// 기사의 좋아요를 클릭했을 때
	my_article_flags |= option_liked;
	cout << "좋아요 클릭: \t" << std::bitset<8>(my_article_flags) << endl;

	// 좋아요가 이미 되어 있다면
	if (my_article_flags & option_liked)
	{
		my_article_flags ^= option_liked;
		cout << "좋아요 해제: \t" << std::bitset<8>(my_article_flags) << endl;
	}
	else
	{
		my_article_flags |= option_liked;
		cout << "좋아요 클릭: \t" << std::bitset<8>(my_article_flags) << endl;
	}

	// 본 기사만 삭제
	if (my_article_flags & option_viewed)
	{
		my_article_flags |= option_deleted;
		cout << "본 기사 삭제: \t" << std::bitset<8>(my_article_flags) << endl;
	}


	return 0;
}

 

 

해당 포스트는 '홍정모의 따라하며 배우는 C++' 강의를 수강하며 개인 백업용으로 메모하였습니다.

인프런: https://www.inflearn.com/course/following-c-plus

 

홍정모의 따라하며 배우는 C++ - 인프런

만약 C++를 쉽게 배울 수 있다면 배우지 않을 이유가 있을까요? 성공한 프로그래머로써의 경력을 꿈꾸지만 지금은 당장 하루하루 마음이 초조할 뿐인 입문자 분들을 돕기 위해 친절하고 자세하게 설명해드리는 강의입니다. 초보로 시작하더라도 중급을 넘어 고급 프로그래머로 가는 길목에 들어서고 싶으시다면 최고의 디딤돌이 되어드리겠습니다. 여러분의 꿈을 응원합니다! 초급 프로그래밍 언어 C++ 온라인 강의 C++

www.inflearn.com

 

반응형
복사했습니다!