[아두이노] C 언어 비교문에서 == 사용 방법

C 언어 비교문에서 == 사용 방법

C 언어에서 '='는 assignment, 즉 변수에 값을 넣어줄 때 사용하고 '=='는 compare, 즉 앞과 뒤의 값이 같은가를 비교하기 위해 사용한다.

하지만 '=='는 코딩을 하다 보면 타이핑 실수로 '='를 하나 빼 먹는 실수를 범하기 쉬운데, 별거 아닌거 같은 실수가 아주 치명적인 결과를 가져올 수가 있다.

먼저 아래 코드를 보자.

void setup() {
  Serial.begin(115200);  
  pinMode(13, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    byte ch = Serial.read();
    if (ch == N'1') {
      digitalWrite(13, HIGH);
    } else {
      digitalWrite(13, LOW);
    }
  }
}


시리얼 포트로 글자를 입력 받아 '1'이면 아두이노에 있는 LED를 켜고, 그 이외 글자인 경우 LED를 꺼 주는 매우 단순한 코드이다.

sketch_jun20a___%25E1%2584%258B%25E1%258
이 부분에서 시리얼 포트에서 입력받은 글자가 '1'인지 비교하고 있다. 그런데 저기서 실수로 '='를 하나 빼 먹으면 어떻게 될까?

sketch_jun20a___%25E1%2584%258B%25E1%258

이렇게 해도 컴파일을 하면 아무 문제 없이 컴파일이 완료된다.

sketch_jun20a___%25E1%2584%258B%25E1%258

이 코드를 아두이노에 업로드해 실행을 하면 어떻게 될까?

원래대로라면 업로드가 완료되면 시리얼 모니터에서 '1'을 보내 줘야만 불이 켜지게 된다. 하지만 위의 코드가 업로드 되면 시리얼 모니터에서 어떤 글자를 보내건 무조건 불이 켜지고 그 이후에는 어떤 글자를 보내는가 상관 없이 불이 계속 켜저 있고 끌수가 없게 된다.

왜 이런 문제가 발생하는 것일까?

답은 맨 위에서 설명했던 것 처럼 '='와 '=='의 의미 차이 때문이다.

ch == N'1' 라고 하는 경우는 ch에 들어 있는 글자와 '1'라는 글자를 비교해 같으면 True, 다르면 False라는 값이 출력된다. 그래서 if 구문이 ch에 들어 있는 글자에 따라 불을 켜거나 끌 수 있게 된다.

그런데 ch = N'1' 의 경우는 ch에 어떤 글자가 들어 있는가는 상관 없이 ch에 '1'이라는 글자를 새로 넣어주라는 의미가 된다. 즉 시리얼 포트에서 어떤 글자가 들어왔는가는 그냥 무시되어 버리는 것이다. 게다가 C 언어에서 '=' (assignment)의 경우 무조건 결과값으로 True가 나오게 되기 때문에

if (ch = N'1') {
  digitalWrite(13, HIGH); 
} else {
  digitalWrite(13, LOW);
}

저 코드에서 시리얼 포트에서 받은 값과 상관 없이 항상 digitalWrite(13, HIGH); 만 실행되게 된다.

게다가 바둑이나 장기를 둘 때 자기는 못보지만 훈수를 두는 사람은 쉽게 묘수를 볼 수 있는것처럼 저런 실수는 코딩을 한 당사사는 찾지 못하는 경우가 많다. 실제 코드가 길어지면 심한 경우 디버깅을 한다고 몇일, 몇달동안 코드를 한줄 한줄 뒤져보면서도 저 실수가 눈에 안 들어온다.

sketch_jun20a___%25E1%2584%258B%25E1%258

이것이 원하는 동작을 하는 코드인데 두개를 보고 한눈에 차이점을 찾을 수 있는가?? 지금까지 구구절절히 설명을 했으니 쉽게 찾겠지만 만일 따로 설명 없이 두개의 스크린샷만 놓고 차이점을 찾으라고 한다면 쉽지 않을 것이다.

그래서 비교문을 쓸 때 순서를 바꿔 쓰라고 권장하는 것이다.

즉 if (ch == N'1') 대신 if ('1' == ch) 이렇게 쓰는 습관을 들이는 것이 좋다.

그럼 단지 순서만 바뀌 쓰는 것인데 뭐가 좋다는 것일까?

만일 둘 다 '='를 하나 빼먹었다고 생각을 해 보자.

if (ch ='1') 는 문법상 틀린 부분이 없기 때문에 정상적으로 컴파일이 완료되고 실행된다. 물론 동작은 원하는것과 다르겠지만...
하지만 if ('1' = ch) 는 C언어 문법 자체가 틀렸기 때문에 컴파일을 하면

sketch_jun20a___%25E1%2584%258B%25E1%258

이렇게 에러가 발생하기 때문에 바로 실수를 바로잡아 줄 수가 있게 된다.

* C언어 문법에서 '='로 변수에 값을 넣어주는 경우 변수 이름은 '='의 왼쪽에, 변수에 넣어 줄 값은 '='의 오른쪽에 와야만 한다. "lvalue required as left operand of assignment" 이 문구가 그게 잘못되었다고 알려주는 것이다.

바로 잘못된 부분을 수정하고 컴파일 하면 이제 정상적으로 동작하게 된다.

sketch_jun20a___%25E1%2584%258B%25E1%258

프로그래밍을 할 때 컴파일러가 에러를 내 주는건 해결하기도 훨씬 쉽다. 하지만 위와 같이 실수를 했는데도 불구하고 컴파일은 정상적으로 되지만 생각하는것과 다르게 동작하는걸 찾는건 훨씬 힘들기 때문에 코딩할 때 부터 그 가능성을 없애줄 수 있는 습관을 들여 놓는 것이 좋다.
0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기

임베디드 보드

번호 제목 글쓴이 날짜 조회수
72 아두이노 ESP32 Analog Inputs (ADC) +4 icon 양재동메이커 02-12 12,149
71 아두이노 TIP : Serial의 Port가 Open 시점 확인 icon 양재동메이커 01-21 9,319
70 아두이노 ESP32 Boot Mode icon 양재동메이커 12-28 8,840
69 아두이노 아두이노 에러 리스트(Arduino Error list) icon 양재동메이커 11-24 13,487
68 아두이노 ESP32 main.cpp +1 icon 양재동메이커 11-19 9,432
67 아두이노 ESP32 EEPROM 와 IR Remote icon 양재동메이커 08-06 9,506
66 아두이노 Learn ESP32 icon 양재동메이커 06-25 8,989
65 아두이노 C 언어 비교문에서 == 사용 방법 icon 양재동메이커 04-12 9,573
64 아두이노 [아두이노 실습] 푸쉬버튼 long press, short press 판단하기 icon 양재동메이커 03-27 11,291
63 아두이노 [아두이노 실습] Push button 스위치로 FND 카운트 증가/감소 icon 양재동메이커 03-27 14,216
62 아두이노 Blynk를 사용해 아두이노에서 IoT 맛보기 icon 양재동메이커 03-27 11,809
61 아두이노 아두이노에서 u8glib로 0.96" OLED 사용하기 icon 양재동메이커 03-27 11,811
60 아두이노 아두이노에서 여러개의 스위치를 1개의 analog input핀으로 검사하기 icon 양재동메이커 03-27 10,896
59 아두이노 아두이노에서 RTOS 사용하기 (FreeRTOS in Arduino) icon 양재동메이커 03-27 13,751
58 아두이노 아두이노에서의 delay() 함수 icon 양재동메이커 03-27 10,064
57 아두이노 아두이노의 pinMode()에서 INPUT과 INPUT_PULLUP의 차이 icon 양재동메이커 03-27 12,182
56 아두이노 아두이노등의 임베디드 시스템의 변수 값 오버플로우 문제 icon 양재동메이커 03-27 8,803
55 아두이노 아두이노에서 외부 라이브러리 설치하기 (Install library in arduino) icon 양재동메이커 03-27 10,486
54 아두이노 WS2812 color LED 사용하기 icon 양재동메이커 03-27 9,639
53 아두이노 WS2812와 APA102의 차이 비교 (Comparison between WS2812 and APA102) icon 양재동메이커 03-27 11,241