#include <stdio.h>
int main() {
int a, b;
printf("두 정수를 공백으로 구분해 입력하세요: ");
scanf("%d %d", &a, &b);
printf("%d, %d를 입력했네요.\n", a, b);
}
저번 시간에는 간단한 입출력 하는 법을 배워보았다 그렇지만 입력 받은 대로만 출력하는 것으로는 상당한 애로 사항이 발생할 수밖에 없다 따라서 변수의 값을 조작하거나 분기를 나누는 등 변화를 만들 필요가 있다 앞서 간단히 살펴본 것처럼 이러한 기능을 수행하는 것 중 하나에는 연산자가 있다 고로 연산자를 다뤄보겠다
연산자에는 산술 연산자, 대입 연산자, 논리 연산자, 관계 연산자, 비트 연산자가 있다
산술 연산자에는 +, -, *, /, %, ++, --가 있다
앞의 4가지는 알다시피 사칙연산을 하는 연산자이고 %는 나머지 연산자라 해서 말 그대로 나머지를 구하는 연산자다 ++과 --는 각각 변수의 값을 1씩 증가시키거나 감소시키는 역할을 한다 또, / 연산자는 정수형끼리 연산하면 정수형으로 반환하며 소수점 아래로 버리고 % 연산자는 피연산자로 정수만 요구한다
대입 연산자는 =이라는 단순 대입 연산자와 다른 연산자와 =을 조합한 복합 대입 연산자가 있다 =은 등호 왼쪽의 변수에 등호 오른쪽의 값을 대입하는 역할을 한다 복합 대입 연산자는 우선 예시를 들어보겠다 int 형 변수 a가 있다고 할 때, a+=2;는 a=a+2;와 사실상 같은 구문으로 인식하면 된다 즉 등호 왼쪽의 변수에 값을 대입하는 것은 동일하나 등호 왼쪽의 변수와 오른쪽의 값에 대해 등호가 아닌 연산자를 이용해 연산한 결과를 대입한다고 설명할 수 있겠다
논리 연산자에는 &&, ||, !가 있음 각각 순서대로 and, or, not을 의미한다 and는 말 그대로 양 쪽이 모두 참일 때만 참을 반환하고, or은 하나라도 참이면 참을 반환하며 not은 참과 거짓을 바꾸어 반환한다 이때, and 연산자는 양 쪽이 참이어야만 참을 반환하므로 한 쪽이 거짓이라면 남은 한 쪽은 확인하지 않는다 가령 값이 10인 변수 a에 대하여 (a==1)&&(++a)==11과 같은 조건식이 있다면 a는 1이 아니므로 거짓을 반환할 것이고, a에 1을 더하는 연산인 ++a는 수행되지 않는다 따라서 a는 11이 아니라 10으로 남아있게 된다
관계 연산자는 <, >, ==, >=, <=가 있음 그냥 우리가 아는 일반적인 등호, 부등호로 생각하면 된다 여기서 유의할 점은 =와 ==는 다른 연산자라는 것이다 조건식에서 == 대신 =를 사용해 문제가 생기는 경우가 간혹 있는데, =가 쓰인 식도 일단 값을 반환하기는 하여 오류를 컴파일러가 잡아내지 못할 수도 있어 버그를 유발시키기도 하니 주의하는 것이 좋다
비트 연산자에 대해 이해하기 위해서는 2진법을 우선 이해할 필요가 있다 2진법이란 말 그대로 0, 1이라는 두 개의 숫자만을 이용해 수를 나타내는 방법이다 가령 7(10)=111(2)와 같이 나타낼 수 있다(소괄호를 이용해 몇 진법이 쓰였는지 나타낼 수 있다) 비트 연산자에는 &, |, ~, ^, <<, >>가 있다 &, |는 &&, ||와 유사한 역할을 한다 다만 각 자리별 비트에 대해 and, or 연산을 수행하는 것이다 가령 1011(2)와 0001(2)에 대해 &, | 연산자를 사용하면 각각 0001(2)와 1011(2)을 얻을 수 있다 ~은 not 연산을 수행해 1과 0을 서로 뒤바꾼다 ^은 XOR 연산자로 두 비트가 서로 다르면 1, 같으면 0을 할당한다 아까 저 두 숫자에 ^을 사용하면 1010(2)를 얻을 것이다 <<, >>는 쉬프트 연산자로, 비트들을 미는 역할을 한다 a=1011(2);에 대해 a<<1은 0110(2)가 되고 a>>1은 1101(2)이 된다
곧 배울 if-else문을 일부 대체할 수 있는 연산자로, 대개 간단한 if-else문을 대체할 때 사용한다 (조건)?a:b와 같은 형태를 갖추고 조건이 참이면 a, 거짓이면 b를 반환한다
연산에는 우선 순위라는 게 있다 사칙 연산을 배울 때 곱셈, 나눗셈을 덧셈, 뺄셈보다 먼저 하는 것과 비슷하다 또, 결합 순서라는 게 있는데 곱셈, 나눗셈 같은 특수한 경우가 아니고서야 왼쪽에서 오른쪽으로 연산하는 것과 비슷하다
다음은 연산자 우선 순위와 결합 순서를 나타낸 표이다
| 연산자 | 유형 | 결합 순서 |
| [ ] ( ) . -> ++ -- (후위) | 표현식 | 왼쪽에서 오른쪽으로 |
| sizeof
& * +(부호) -(부호) ~ ! ++ -- (전위) | 단항 | 오른쪽에서 왼쪽으로 |
| ( typecast ) | 형변환 | 오른쪽에서 왼쪽으로 |
| * / % | 곱꼴 | 왼쪽에서 오른쪽으로 |
| + - | 합차 | 왼쪽에서 오른쪽으로 |
| << >> | 비트 시프트 | 왼쪽에서 오른쪽으로 |
| < > <= >= | 부등호(대소 관계) | 왼쪽에서 오른쪽으로 |
| == != | 등호, 부등호(같지 않음) | 왼쪽에서 오른쪽으로 |
| & | 비트 단위 AND | 왼쪽에서 오른쪽으로 |
| ^ | 비트 단위 XOR | 왼쪽에서 오른쪽으로 |
| | | 비트 단위 OR | 왼쪽에서 오른쪽으로 |
| && | 논리 AND(논리곱) | 왼쪽에서 오른쪽으로 |
| || | 논리 OR(논리합) | 왼쪽에서 오른쪽으로 |
| ? : | 조건식(삼항 연산자) | 오른쪽에서 왼쪽으로 |
| = *= /= %= += -= <<= >>= &= ^= |= | 단순 및 복합 할당 | 오른쪽에서 왼쪽으로 |
| , | 순차적 평가 | 왼쪽에서 오른쪽으로 |
#include <stdio.h>
int main() {
int score=0;
printf("점수를 입력하세요.");
scanf("%d", &score);
printf("당신의 등급은 %c입니다.",(score>=90)?'A':(score>80)?'B':(score>70)?'C':(score>60)?'D':'F');
return 0;
}
위와 같은 코드를 작성하여 이전에 비해 상당히 역동적인 프로그램을 제작할 수 있다
이전 시간에 변수를 선언하는 법에 대해 다뤄봤고, 대입 연산자를 통해 값을 입력하는 법을 배웠다 따라서 변수의 선언과 대입 대신 초기화와 작명법에 대해서만 다뤄보겠다
변수(variable)란 변할 수 있는 수라는 말뜻처럼 변하는 값을 저장하기 위해 사용한다 문자는 수가 아니지 않냐고 한다면 문자도 결국 이진수 등으로 변환해 비트로 저장하니 변수란 명칭이 문제가 되진 않는다 그리고 변수에 값을 담는 공간 을 메모리 라고 한다 램 또는 주기억 장치라고도 부를 순 있지만 굳이 컴퓨터 구조를 얘기할 때가 아니고서는 메모리라고 통칭한다
나중에 포인터를 다룰 때 자세히 얘기하겠지만 메모리에 저장한 값을 가져오거나 변경하려 할 때 메모리의 시작 주소와 자료형을 이용해 메모리에 값이 저장된 위치를 파악한다 따라서 선언한 적 없는 변수를 사용한다면 값을 가져올 위치를 알 수 없으니 에러를 띄우고 자료형을 잘못 사용한다면 자료형에 따라 바이트 수가 달라지기도 해 값을 잘못 가져올 수 있고, 바이트 수가 같더라도 해석 방식이 달라 전혀 다른 값이 나올 수가 있다 그러니 선언된 변수를 사용하고, 알맞은 자료형을 사용하는 걸 잊지 말자 printf나 scanf 등을 사용할 때 이 부분을 실수하면 문제가 생길 수 있다
변수의 선언과 대입을 동시에 할 때, 변수를 초기화한다고 부른다
변수를 선언한다는 것은 메모리 상에서 값을 저장하기 위해 공간을 할당하는 것이고 대입은 그 공간에 값을 넣는 것이다
변수를 초기화하면 변수를 선언만 하고 대입을 하지 않아 변수에 쓰레기 값이 들어가는 것을 방지할 수 있고, 코드를 간결하게 작성할 수 있다
변수의 선언 위치에 따라 0이 들어가기도 하지만,scanf 등을 사용해 입력을 받지 않는다면 그냥 대입이나 초기화로 값을 확실히 정해두도록 하자
참고로 이전에 메모리에 저장되었던 값이 남아 있어 의도하지 않은 값이 들어가 있을 때, 그 값을 쓰레기 값이라 부른다
...(중략)
int a=10;
...(후략)
위와 같이 작성할 수 있다
변수를 작명할 때 지켜야 할 규칙이 있다
컴파일러에 따라 이러한 규칙을 어겨도 작동하는 경우도 있지만 위의 규칙을 다 지킨다면 컴파일러가 달라지더라도 작동하는 데는 문제가 없을 것이다
또 이러한 필수적인 규칙 외에도 관습적으로 지키는 규칙들도 있다 다음은 주로 지키는 규칙들이다
여기서 _를 사용하는 방법을 스네이크 표기법, 대문자를 사용하는 방식(ex: myScore, userInputValue)을 카멜 표기법이라 하는데, 각각 _로 연결된 모습이 뱀 같아서, 대문자가 올라온 모습이 낙타의 봉 같아서 이러한 이름이 붙게 되었다
상수, 클래스명과 같은 경우에는 대문자를 사용하기도 하지만 현재 배우고 사용하는 변수들의 경우에는 두 표기법 중 하나를 사용한다고 보면 된다
3 과목의 점수를 입력받고 평균이 70점 이상이면 합격이라 말하고 아니면 불합격이라 말하는 코드를 작성해라.
예시와 개념을 잘 참고해서 과제를 수행해보기 바람 참고로 A, B 같은 문자가 아니라 "합격", "불합격" 같은 문자열을 사용하기 위해서는 %s와 큰 따옴표를 사용하면 된다
