연산자란? 프로그래밍 언어를 이용해서 특정연산을 요구할 때 사용하는 약속된 기호를 가리킨다.
프로그램에서는 연산을 하고 그 결과를 메모리 공간에 저장한다. 그리고 메모리 공간에 저장된 값을 출력한다.
연산을 저장하는 방법에는 변수(variable)
를 사용하는 것이 있다.
변수란? 값을 저장할 수 있는 메모리 공간에 붙은 이름, 혹은 메모리 공간 자체를 가리켜 변수라 한다.
따라서, 변수라는 것을 하나 만들면(선언하면), 그 변수의 이름을 통해서 값의 저장 및 참조가 가능하고 또 저장된 값의 변경도 가능하다.
변수를 선언 하는데는 아래 두 가지가 필요하다. 예시와 함께 설명해보자면,
int num;
변수의 자료형 (int
)
: 정수의 저장이 가능한 메모리 공간을 할당한다.
변수의 이름 (num
)
: 메모리 공간의 이름이다.
변수를 선언한 이후 아래 예제와 같이 값을 저장하거나 참조할 수 있다.
int main(void)
{
int num; // num이라는 이름의 변수 선언
num=20; // 변수 num에 20 저장
printf("%d", num); // 변수 num의 값 참조
}
=
기호는 값의 대입을 뜻한다. '대입 연산자'라 하기도 하고 우리가 수학 기호에서 사용하는 '같다'는 의미는 아니다. (같다는 의미는 뒤에서 얘기하겠지만 다른 기호로 표현한다.)
선언된 변수에 처음 값을 저장하는 것을 가리켜 '초기화'라 한다.
초기화 이후에 저장된 값을 변경할 때는 그냥 '대입' 또는 '대입연산'을 진행한다.
변수를 '선언과 동시에 초기화'하는 것도 가능하며 아래 예시와 같다.
#include <stdio.h>
int main(void)
{
int num1, num2; // 변수 선언
int num3=30, num4=40; // 변수 선언 및 초기화
printf("num1: %d, num2: %d \n", num1, num2);
num1=10; // 변수 초기화
num2=20; // 변수 초기화
printf("num1: %d, num2: %d \n", num1, num2);
printf("num3: %d, num4: %d \n", num3, num4);
return 0;
}
vsc 최신것을 사용하다 보면 변수 선언만 하는 것이 안된다,,,,ㅎ
그래서 난 임의의 숫자를 넣었다.
변수를 선언 시 주의할 사항들이 있다.
중괄호 내에 변수를 선언할 경우, 변수의 선언문은 중괄호의 앞부분에 위치해야 한다.
: 중괄호는 함수의 시작과 끝을 구분하는 용도로 사용된다. 이러한 중괄호의 시작부분에 변수의 선언문이 위치해야 한다.
+) 1990년도에 발표된 C언어의 표준에서는 변수의 선언 위치에 아무런 제한을 두지 않고 있다.
변수의 이름을 지을 때 적용되는 규칙들이 있다.
1) 변수의 이름은 알파벳, 숫자, 언더바(_)로 구성된다. 특수문자는 사용될 수 없다.
2) 대소문자를 구분한다. Num과 num은 다른 변수다.
3) 변수의 이름은 숫자로 시작할 수 없고 키워드도 변수의 이름으로 사용할 수 없다.
4) 변수의 이름 사이에 공백이 삽입될 수 없다.
5) 변수의 이름을 정할 때에는 변수의 역할에 어울리는, 의미 있는 이름을 지어야 한다.
변수의 종류는 정수형 변수
와 실수형 변수
크게 두 가지로 나뉜다.
정수형 변수란, 정수의 저장을 목적으로 선언된 변수로, char/short/int/long형이 있다.
실수형 변수란, 소수점 이하의 값을 지니는 실수의 저장을 목적으로 선언된 변수로, float/double형이 있다.
이렇게 크게 두 가지로 나뉘는 이유는 정수냐, 실수냐에 따라서 값이 메모리 공간에 저장 및 참조되는 방식이 다르기 때문이다.
그럼 이러한 변수 선언을 가지고 간단한 덧셈 프로그램을 완성해보자.
#include <stdio.h>
int main(void)
{
int num1 = 3;
int num2 = 4;
int result = num1 + num2;
printf("덧셈 결과: %d \n", result);
printf("%d+%d=%d \n", num1, num2, result);
printf("%d와(과) %d의 합은 %d입니다. \n", num1, num2, result);
return 0;
}
*
, /, %)두 개의 피연산자를 요구하는 연산자를 가리켜 이항 연산자(binary operator)
라 하는데 대입 연산자와 산술 연산자는 모두 이항 이항 연산자들이다.
연산자 사용 예시는 아래와 같다.
#include <stdio.h>
int main()
{
int num1 = 9, num2 = 2;
printf("%d+%d=%d \n", num1, num2, num1 + num2);
printf("%d-%d=%d \n", num1, num2, num1 - num2);
printf("%dx%d=%d \n", num1, num2, num1 * num2);
printf("%d/%d의 몫=%d \n", num1, num2, num1 / num2);
printf("%d/%d의 나머지=%d \n\n", num1, num2, num1 % num2);
return 0;
}
다른 연산자와 합쳐진 형태의 대입 연산자도 존재하는데, 이를 가리켜 복합 대입 연산자라 한다.
#include <stdio.h>
int main()
{
int num1 = 2, num2 = 4, num3 = 6;
num1 += 3; // num1 = num1 + 3
num2 *= 4; // num2 = num2 x 4
num3 %= 5; // num3 = num3 % 5
printf("Result: %d, %d, %d \n\n", num1, num2, num3);
retrun 0;
}
+ 연산자
와 - 연산자
는 단항 연산자로 사용될 땐 부호를 의미한다.
#include <stdio.h>
int main()
{
int num6 = +2; // num6 양의 정수
int num7 = -4; // num7 음의 정수
num6 = -num6;
printf("num6: %d \n", num6);
num7 = -num7;
printf("num7: %d \n\n", num7);
retrun 0;
}
이처럼 단항 연산자로 사용될 경우 이항 연산자인지 복합 대입 연산자 인지 헷갈릴 수 있기 때문에 띄어쓰기가 중요한데, 현재 vsc에서는 이를 자동으로 해결해준다.
부호의 숫자에 따라 의미가 변경되므로 아래 예제의 출력결과를 유심히 살펴보자.
#include <stdio.h>
int main()
{
int num8 = 12;
int num9 = 12;
printf("num8: %d \n", num8);
printf("num8++: %d \n", num8++); // 후위증가
printf("num8: %d \n", num8); // 출력된 값에 증가된 값
printf("++num8: %d \n\n", ++num8); // 전위증가 → 바로 연산
printf("num9: %d \n", num9);
printf("--num9: %d \n", --num9); // 전위감소
printf("num9: %d \n", num9); // 감소된 값의 출력
printf("num9--: %d \n\n", num9--); // 후위감소 → 우선 출력
retrun 0;
}
전위, 후위 연산 관련해서 예제를 하나 들어보자면
#inlude <stdio.h>
int main()
{
int num10 = 10;
int num11 = (num10--) + 2; // 후위 감소 → num10을 우선 10으로 출력
printf("num10: %d \n", num10); // 위에서 선 출력 했으니 연산된 값인 9로 나타남.
printf("num11: %d \n\n", num11); // 위에서 num10을 10으로 인식했으니 그 연산 값인 12로 나타남.
return 0;
}
num10에 대해서 '선 연산, 후 감소'를 진행하고 있다.
c언어에서 소괄호도 연산자이다.
그렇다면 num11는 어떨까? 아무리 '선 연산, 후 감소'라 할지라도 괄호까지 해줬으니 num1의 값이 감소한 상태에서 덧셈연산이 진행되는 게 아닐까?
하지만 후위 증가(선 연산, 후 증가) 및 후위 감소(선 연산, 후 감소) 연산 시에는 '소괄호의 영향을 받지 않고, 다음 문장으로 넘어가야만 비로소 값의 증가 및 감소가 이루어진다.'
관계 연산자는 대소와 동등의 관계를 따지는 연산자이다.
비교 연산자라고도 하며 '조건을 만족하면 1을, 만족하지 않으면 0을 반환'한다. 여기서 1은 '참(true)'을, 0은 '거짓(false)'을 의미하는 대표적인 숫자다.
예제는 아래와 같다.
#include <stdio.h>
int main()
{
int num12 = 10;
int num13 = 12;
int result1, result2, result3;
result1 = (num12 == num13);
result2 = (num12 <= num13);
result3 = (num12 > num13);
printf("result1: %d \n", result1);
printf("result2: %d \n", result2);
printf("result3: %d \n\n", result3);
return 0;
}
> 예상 출력
0
1
0
논리 연산자란 AND(논리곱), OR(논리합), NOT(논리부정)을 표현하는 연산자다.
예제를 통해 알아보자.
#include <stdio.h>
int main()
{
int num14 = 10;
int num15 = 12;
int result4, result5, result6;
result4 = (num14 == 10 && num15 == 12);
result5 = (num14 < 12 || num15>12);
result6 = (!num14);
printf("result1: %d \n", result4);
printf("result2: %d \n", result5);
printf("result3: %d \n\n", result6);
return 0;
}
> 예상 출력
1
1
0
이 예제에서는 논리 연산의 순서가 논리 연산 양 옆에 있는 연산이 우선적으로 진행되고 논리 연산자가 실행됨을 알아야한다.
C언어에는 '연산자 우선순위'가 있으며 '결합 방향'도 있다.
그리고 C언어는 0이 아닌 모든 값을 '참(true)'으로 간주한다.
콤마 연산자는 둘 이상의 변수를 동시에 선언하거나, 둘 이상의 문장을 한 행에 삽입하는 경우에 사용되는 연산자다. 연산의 결과가 아닌 구분
을 목적으로 주로 사용된다.
콤마 연산자의 예시는 아래와 같다.
#include <stdio.h>
int main()
{
int num16 = 1, num17 = 2;
printf("Hello "), printf("world! \n");
num16++, num17++;
printf("%d ", num16), printf("%d ", num17), printf("\n");
return 0;
}
> 예상 출력
Hello world!
2 3
우리는 기본적으로 사칙연산의 순서를 알고 있다.
곱셈, 나눗셈을 덧셈, 뺄셈보다 먼저 한다!
이것이 바로 연산자의 우선순위
다.
그리고 동등한 우선 순위일 때 곱셈과 나눗셈은 왼쪽에 먼저 등장하는 것부터 순서대로 계산한다! 이것이 바로 결합방향
이다. 즉, 우선순위가 동일한 두 연산자가 하나의 수식에 존재하는 경우, 어떠한 순서대로 연산을 하느냐 결정해 놓은 것이다.
연산자의 우선순위와 결합방향을 정리하면 아래와 같다.
우리가 변수의 값을 초기화하지 않고 사용자로부터 입력 받는 방식을 하려면 어떻게 하면 좋을까?
※ 주의: 여기서 부터 나오는 예제는 Visual C++ 2022 콘솔의 특징에 따라 아래 중 하나의 방식을 채택하여 사용해야 오류가 발생하지 않는다.
1) scanf 함수 대신 scanf_s 함수를 사용
2) #include 이전에 #define CRT_SECURE_NO_WARNINGS
를 추가하여 사용
int main()
{
int num;
scanf_s("%d", &num);
...
}
위 예시를 보면 키보드로부터 데이터를 받기 위해 데이터의 종류에 맞게 메모리 공간을 미리 할당해야 한다.
따라서 위의 코드에서는 scanf 함수 호출에 앞서 변수 num을 선언하고 있다. 그리고 이어서 scanf 함수를 호출하면서, 두 번째 인자로 num을 넘겨주고 있다.
이때 변수 num 앞에 &
연산자가 붙어있다.
이는10진수 정수형태의 입력
을 뜻한다.
예제를 하나 보자.
#include <stdio.h>
int main()
{
int result1;
int num1, num2;
printf("정수 one: ");
scanf_s("%d", &num1); // 첫 번째 정수 입력
printf("정수 two: ");
scanf_s("%d", &num2); // 두 번째 정수 입력
result1 = num1 + num2;
printf("%d + %d = %d \n\n", num1, num2, result1);
return 0;
}
printf 함수에서 출력의 형태를 다양하게 지정하는 것이 가능했던 것과 동일하게 넘겨주는 변수 앞에 어떤 연산자가 붙느냐에 따라 입력형태를 다양하게 지정하는 것이 가능하다.
그리고 둘 이상의 데이터를 입력 받기 위해서는 아래 예제와 같이 작성하면 된다.
#include <stdio.h>
int main()
{
int result2;
int num3, num4, num5;
printf("세 개의 정수 입력: ");
scanf_s("%d %d %d", &num3, &num4, &num5);
result2 = num3 + num4 + num5;
printf("%d + %d + %d = %d \n\n", num3, num4, num5, result2);
return 0;
}
scanf 함수에서 입력을 받을 때 공백을 기준으로 데이터를 구분한다.
키워드란? int나 return과 같이 기능적 의미가 정해져서 C언어의 문법을 구성하는 단어들을 말한다.
키워드들은 아래와 같이 있다.
이 키워드들은 변수나 함수의 이름으로 사용할 수 업으며 프로그래머가 다른 용도로 사용할 수 없도록 제한되어 있다.
<Review>
오옹 이제 뭔가 그럴듯 하게 값도 입력 받고 할 수 있게 되었다!
처음에 scanf를 vsc로 사용할 때 계속 오류가 발생해서 화딱지가 났던 기억이 있는데
나의 첫 개발 오류 원인 및 해결 방법 찾아보기가 된거 같다 ㅎㅎㅎ
확실히 개발은 검색 잘하는 능력도 중요한듯!
오늘도 재밌게 C언어 공부 완!
(사실 오늘 스터디하기 전 닥쳐서 호다닥하기)
그럼 바로 Chapter 4로 궈궈~~