포스트

[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)

위 코드에서 제가 생각한 동작은 다음과 같았습니다.

  1. str에서 alpha라는 문자열의 위치를 찾아 it 변수에 저장한다.
  2. it 변수에 저장된 값이 npos 가 아닐 경우 while문을 반복한다.


그러나 실행에서는 이와같이 동작하지 않았습니다.
문제를 파악하기 위해서 코드의 동작 순서를 변경해 보았습니다.

먼저 while() 문에 true를 넣어 무한 반복문으로 변경한 뒤 반복문 안에서 find() 메소드와 npos 를 비교하거나
it 변수를 외부에 선언 하였을 때는 원하는 결과가 출력되었습니다.


연산자 우선 순위

대입 연산자(=)와 비교 연산자(!=)의 우선순위는 비교 연산자가 더 우선됩니다.
따라서 문제의 코드에서 연산 순서는 다음과 같습니다.

  1. str.find(alpha) != std::string::npos 비교 연산을 먼저 실행합니다.
  2. 비교 연산의 실행 결과(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역참조
&xx의 주소
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 라이센스를 따릅니다.