[C++] 연산자 우선순위
크로아티아 알파벳 문제
크로아티아 알파벳 문제는 입력 받은 문자열에서 특정 문자열을 탐색하는 문제입니다.
처음 코드를 작성할 때, 아래 while()문 처럼 코드를 작성하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
vector<string> croatia_alphabet{"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
string str;
cin >> str;
for (auto alpha : croatia_alphabet)
{
while (int it = str.find(alpha) != std::string::npos)
{
str.replace(it, alpha.length(), "#");
}
}
cout << str.length();
while (int it = str.find(alpha) != std::string::npos)
위 코드에서 제가 생각한 동작은 다음과 같았습니다.
- str에서 alpha라는 문자열의 위치를 찾아 it 변수에 저장한다.
- it 변수에 저장된 값이 npos 가 아닐 경우 while문을 반복한다.
그러나 실행에서는 이와같이 동작하지 않았습니다.
문제를 파악하기 위해서 코드의 동작 순서를 변경해 보았습니다.
먼저 while() 문에 true를 넣어 무한 반복문으로 변경한 뒤 반복문 안에서 find() 메소드와 npos 를 비교하거나
it 변수를 외부에 선언 하였을 때는 원하는 결과가 출력되었습니다.
연산자 우선 순위
대입 연산자(=)와 비교 연산자(!=)의 우선순위는 비교 연산자가 더 우선됩니다.
따라서 문제의 코드에서 연산 순서는 다음과 같습니다.
- str.find(alpha) != std::string::npos 비교 연산을 먼저 실행합니다.
- 비교 연산의 실행 결과(true/false) 를 변수 it에 대입합니다.
따라서 연산자의 순서가 잘못되었음을 알게되었고 이 문제점을 해결하기 위해
아래와 같이 코드를 수정하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vector<string> croatia_alphabet{"c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z="};
string str;
cin >> str;
int it;
for (auto alpha : croatia_alphabet)
{
while ((it = str.find(alpha)) != std::string::npos)
{
str.replace(it, alpha.length(), "#");
}
}
cout << str.length();
조건문 안에서 변수 생성
문제의 코드처럼 제어문의 조건을 입력하는 부분에서 지역 변수를 생성할 수 있습니다.
하지만 생성한 지역 변수는 제어문의 생명 주기와 동일하며
대입 연산자의 우선순위가 낮음에 주의해서 사용해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
int stack = 5;
int get_stack()
{
return stack -= 1;
}
int main()
{
while(int curr = get_stack())
{
int temp = curr;
printf("curr: %d\n", curr);
}
// curr 변수는 while()문 안에서만 유효한 지역변수
// printf("%d\n", curr);
return 0;
}
C++ 연산자 우선순위 정리
우선순위 | 연산자 | 설명 |
---|---|---|
1순위 | x++ | 증가 연산자(뒤, 후위) |
x-- | 감소 연산자(뒤, 후위) | |
( ) | 함수 호출 | |
[ ] | 배열 첨자 | |
. | 구조체/공용체 멤버 접근 | |
-> | 포인터로 구조체/공용체 멤버 접근 | |
(자료형){값} | 복합 리터럴 | |
2순위 | ++x | 증가 연산자(앞, 전위) |
--x | 감소 연산자(앞, 전위) | |
+x | 단항 덧셈 | |
-x | 단항 뺼셈 | |
! | 논리 NOT | |
~ | 비트 NOT | |
(자료형) | 자료형 캐스팅(자료형 변환) | |
*x | 포인터 x역참조 | |
&x | x의 주소 | |
sizeof | 자료형의 크기 | |
3순위 | * | 곱셈 |
. | 나눗셈 | |
% | 나머지 | |
4순위 | + | 덧셈 |
- | 뺄셈 | |
5순위 | << | 왼쪽으로 비트를 시프트 |
>> | 오른쪽으로 비트를 시프트 | |
6순위 | < | 작음(논리) |
<= | 작거나 같음(논리) | |
> | 큼(논리) | |
>= | 크거나 같음(논리) | |
7순위 | == | 같음 |
!= | 다름 | |
8순위 | & | AND(비트) |
9순위 | ^ | XOR(비트) |
10순위 | | | OR(비트) |
11순위 | && | AND(논리) |
12순위 | || | OR(논리) |
13순위 | ?: | 삼항 연산자 |
14순위 | = | 할당 |
+= | 덧셈 후 할당 | |
-= | 뺼셈 후 할당 | |
*= | 곱셈 후 할당 | |
/= | 나눗셈 후 할당 | |
%= | 나머지 연산 후 할당 | |
<<= | 비트를 왼쪽으로 시프트 한 후 할당 | |
>>= | 비트를 오른쪽으로 시프트한 후 할당 | |
&= | 비트 AND 연산 후 할당 | |
^= | 비트 XOR 연산 후 할당 | |
|= | 비트 OR 연산 후 할당 | |
15순위 | , | 쉼표 연산자 |
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.