프로그래밍 언어 활용 2강. 변수·연산자·제어문
4과목에서 사람을 떨어뜨리는 것은 어려운 개념이 아니라 증감 연산자 하나입니다. i++와 ++i의 차이를 손으로 못 따라가면 그 문제는 못 풉니다.
풀고 시작
변수는 이름 붙은 상자입니다
변수는 값을 담아 두는 메모리 공간에 이름을 붙인 것입니다. 어디에 선언하느냐에 따라 살아 있는 범위가 달라지는데, 이를 유효 범위(scope)라고 합니다.
지역 변수는 함수나 블록 안에서 선언되어 그 안에서만 살아 있습니다. 함수가 끝나면 사라지죠. 전역 변수는 함수 바깥에 선언되어 프로그램 전체에서 접근할 수 있고 프로그램이 끝날 때까지 남습니다. 편해 보이지만 여러 곳에서 값을 바꾸면 추적이 어려워져서, 앞서 배운 공통 결합도의 원인이 됩니다.
C에는 저장 클래스가 넷 있습니다. 기본값인 auto는 지역 변수로 스택에 잡히고, static은 함수가 끝나도 값이 유지되며, register는 가능하면 레지스터에 두라는 권고이고, extern은 다른 파일에 선언된 변수를 가져다 쓴다는 표시입니다. static 지역 변수는 함수를 다시 불러도 이전 값이 남아 있다는 점이 특히 자주 나옵니다.
연산자에는 우선순위가 있습니다
한 줄에 연산자가 여럿 있으면 순서가 문제가 됩니다. 높은 쪽부터 정리하면 이렇습니다.
| 순위 | 연산자 |
|---|---|
| 1 | 증감(++, --), 논리 부정(!), 비트 부정(~) |
| 2 | 곱셈, 나눗셈, 나머지(%) |
| 3 | 덧셈, 뺄셈 |
| 4 | 시프트(왼쪽 이동, 오른쪽 이동) |
| 5 | 관계 연산자(<, >, <=, >=) |
| 6 | 등가 연산자(==, !=) |
| 7 | 비트 AND, 비트 XOR, 비트 OR 순 |
| 8 | 논리 AND, 그 다음 논리 OR |
| 9 | 삼항 조건 연산자 |
| 10 | 대입 연산자 |
외우기 어려우면 단항이 가장 세고 대입이 가장 약하다는 양 끝만 잡으셔도 됩니다. 그리고 시험에 정말 자주 나오는 것은 비트 연산자가 논리 연산자보다 우선순위가 높다는 사실입니다.
비트 연산도 정리해 두시죠. AND(&)는 둘 다 1일 때 1, OR(|)는 하나라도 1이면 1, XOR(^)는 서로 다를 때 1입니다. 왼쪽 시프트는 2를 곱하는 효과, 오른쪽 시프트는 2로 나누는 효과를 냅니다.
단축 평가(short circuit)도 함정입니다. 논리 AND에서 왼쪽이 거짓이면 오른쪽은 아예 실행되지 않습니다. 오른쪽에 증감 연산자가 있으면 그 증가가 일어나지 않죠. 코드 추적 문제에서 이 한 줄로 답이 갈립니다.
제어문은 세 가지 모양뿐입니다
구조적 프로그래밍의 정리에 따르면 어떤 프로그램이든 순차, 선택, 반복 세 구조로 표현할 수 있습니다.
선택문은 if와 switch입니다. switch에서 가장 흔한 함정은 break를 빠뜨렸을 때입니다. break가 없으면 조건이 맞는 case부터 아래로 계속 흘러 내려갑니다. 이를 폴스루(fall-through)라고 부르고, 시험은 정확히 이 지점을 노립니다.
반복문은 셋입니다. for는 초기식과 조건식과 증감식을 한 줄에 적고, while은 조건을 먼저 검사하며, do-while은 일단 한 번 실행한 뒤에 조건을 검사합니다. 그래서 조건이 처음부터 거짓이어도 do-while은 최소 한 번은 돕니다.
반복을 벗어나는 명령도 구분하셔야 합니다. break는 반복문을 완전히 빠져나가고, continue는 이번 회차만 건너뛰고 다음 회차로 갑니다.
간단한 예로 감을 잡아 보시죠.
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) continue;
sum += i;
}
짝수일 때 continue로 건너뛰므로 홀수만 더해집니다. 1부터 10까지의 홀수는 1, 3, 5, 7, 9이니 sum은 25가 되죠. 이 코드에서 continue를 break로 바꾸면 i가 2일 때 반복이 끝나므로 sum은 1이 됩니다. 한 낱말 차이로 답이 완전히 달라집니다.
다음 강에서는 4과목의 진짜 고비, 배열과 포인터와 문자열을 다룹니다.
인출 문제
생각해볼 질문 (정답 없음)
문법이 허용하는 코드와 사람이 이해할 수 있는 코드는 다릅니다. 폴스루처럼 컴파일러가 경고하지 않는 함정은, 언어가 막아야 할까요 사람이 조심해야 할까요.
이전: 1강 서버 프로그램 구현과 개발 환경 · 다음: 3강 배열·포인터·문자열