Adventure of 빠타박스
article thumbnail
728x90
728x90
SMALL

02_ 변수와 연산자

2.1 변수 사용하기

컴퓨터 본체에는 램(RAM. Random Access Memory ) 라 부품이 있다.

  • 운영체제나 프로그램이 실행되는 동안 여러 가지 정보를 저장해 놓는 것
  • C언어에서는 변수를 통해 메모리에 접근해서 정보를 저장 하거나 가져올 수 있다.

변수(variable)는 어떤 값을 담는 공간을 의미

  • 이 공간은 메모리의 어딘가에 알아서 할당 된다.
  • 변수에 담겨있는 값은 0과 1로 표현된다.

2.1.1 변수의 선언과 대입

변수에 여러 형태의 값을 담고, 정소를 저장해보자

int a; //변수 선언
  • a라는 이름의 변수가 만들어 진다.
  • a는 정수(int)를 저장하는 변수를 만들고, 그 이름을 a라 하겠다는 의미 이를 변수 선언 이라 한다.

3이라는 숫자를 집어 넣고 시파면, 등호(=) 대입 연산자를 이용해보자

a = 3;

C언어에서 등호(=)는 같다 라는 의미가 아니라. a 변수에 3을 집어 넣겠다는 의미

“대입”

#include <stdio.h>

int main()
{
	int a;  //선언
	a = 3;
	printf("%d\\n". a);
}

3

printf에서 %d를 사용해 a값을 출력할 수 있다.

%d에는 a에 값이 3이 들어간다.

변수에 들어 있는 값이 아닌 a라는 문자 자체를 출력한다면

printf("%c\\n", 'a');

변수는 변하는 수이기 때문에 몆 가지 예외를 제외하면 변수에 들어 있는 값은 언제든지 바꿀 수 있다.

#include <stdio.h>

int main()
{
		int a;
		a = 3; 
		printf("%d\\n", a); // 3 출력 
		a = 5; // a에 들어 있는 값을 5로 바꾼다.
		printf("%d\\n", a); // 5 출력
}

3

5

  1. a = 3;을 통해 a에 3이 들어 갔다.
  2. 대입 이후 printf를 통해 a를 출력 하면 3이 출력 된다.
  3. a = 5구문을 통해 a 에 5가 대입 3은 날아가고 새로운 값인 5가 a에 저장
  4. printf를 통해 다시 a값을 출력하면 5 가 출력됨

<aside> 👉🏻 int a; a[ ] a = 3; a [ 3 ] printf(”%d\n”, a); a[ 3 ] ⇒ 3 a = 5; a[ 5 ] → 3 printf(”%d\n”, a); a [ 5 ] ⇒ 5

</aside>


변수를 선언과 동시에 3를 대입할 수도 있다.

int a = 3;

이러한 과정을 초기화 라고 한다. (C++에서는 조금 다르다.)

변수 2개를 만들어 초기화 하고, 실행하기 전에 출력 결과를 에측해보자

2,1,2 변수의 초기화

#include <stdio.h>

int main()
{
		int a = 2; //a 를 2로 초기화 
		int b = 3; //b 를 3으로 초기화 

		printf("%d + %d = %d\\n", a, b, a + b);
}

2 + 3 = 5

a+b가 계산되어 sum에 들어가는 과정

 

 

 

2.1.3 변수의 이름

  • 변수의 이름은 원칙적으로 영어 대소문자, 숫자, 언더스코어(_)의 조합만 가능하다.
  • 이름의 맨 첫글자는 숫자이면 안된다.
  • Visual Studio 에서 파란색 표시되는 예약어(int, if, for등) 도 특수한 목적으로 “예약된” 단어 이므로 변수의 이름으로 사용할 수 없다.

사용 가능한 이름의 예 사용 가능하지 않은 이름의 예

int a; int my.name;
int my_name; int myName!;
int myName123; int int;(int는 예약어)
int_123abc; int 123myName;
  • 같은 이름의 변수를 2개 만들 수 없다.
int a = 2;
int a = 3; // 에러! 같은 이름의 변수를 이미 위에서 선언했다. 

 

 

2.2 자료형

자료의 형태

정수형, 실수형, 문자등

자료의 형태 혹은 종류를 ‘자료형(data type), 또는 타입이라고 한다.

컴퓨터는 모든 데이터를 0과 1로 저장한다.

데이터를 저장하려면 데이터를 0과 1로 표현 할 수 있을지 에 대한 규칙이 약속되어 있어야 한다.

변수는 자료형에 따라 크기가 다를수 있고, 해석되는 방식도 다르다.

int는 크기가 32비트 지만, char라는 자료형은 크기가 8비트 이다.

01000000 01001001 00001111 11011011 이라는 값이라 하더라도 int로 해석했을 때는 1,078,530,011 이라는 값을,

float로 해석했을 때는 약 3.1415927의 값이 된다.

 

 

2.2.1 int 와 float

int에는 정수만 담을 수 있다.

+(덧셈)

-(뺄셈)

*(곱셈)

/(나눗셈 몫)

%(나눗셈 나머지)

#include <stdio.h>

int main()
{
		int a = 5;
		int b = 3;
		int add = a + b; // 덧셈
		int sub = a - b; // 뺄셈
		int mul = a * b; // 곱셈
	  int div = a / b; // 몫
		int mod = a % b; // 나머지

		printf("%d + %d = %d\\n", a, b, add);
		printf("%d - %d = %d\\n", a, b, sub);
		printf("%d * %d = %d\\n", a, b, mul);
		printf("%d / %d = %d\\n", a, b, div);
		printf("%d %% %d = %d\\n", a, b, mod);
}
  • printf에서 %d, %f 같이 % 로 시작하는 기호가 특별한 의미를 지니기 때문에 % 기호 자체를 출력하고 싶으면 %%로 입력해야한다.

https://replit.com/@JohnSik/HotBigIntegers#main.cpp

int 자료형을 사용해서 나누기 연산을 하면, 몫과 나머지가 따로 처리된다.

int를 사용한 사칙연산의 결과들 또한 모두 int이다.

float

#include <stdio.h>

int main()
{
		float a = 9.8;
		float b = 3.14;
		float add = a + b; // 덧셈
		float sub = a - b; // 뺄셈
		float mul = a * b; // 곱셈
	  float div = a / b; // 몫

		printf("%f + %f = %f\\n", a, b, add);
		printf("%f - %f = %f\\n", a, b, sub);
		printf("%f * %f = %f\\n", a, b, mul);
		printf("%f / %f = %f\\n", a, b, div);
}

https://replit.com/@JohnSik/Test#main.cpp

  • 실수연산은 정수와 달리 실제 나눗셈 결과가 실수로 표현된다.
  • 실제 계산 결과값이 0.000001정도의 오차가 난다. 이것을 부동 소수점 오차(floating point error)라고 한다.
  • 컴퓨터가 소수를 처리하는 방식상 불가피하게 이러한 오차가 발생한다.
  • 오차를 줄일기 위해 정밀도가 두 배인 double자료형을 쓰기도 한다.

 

2.2.2 비트와 바이트

0과 1을 사용해서 만들 수 있는 서로 다른 한 자리 수는 0, 1로 총 2가지 이다.

2자리의 수의 개수는 00, 01, 10, 11 총 4가지 이며,

3자리 수의 개수는 000, 001, 010, 011, 100, 101, 110, 111로 총 8가지

 

0과 1로 이뤄진 서로 다른 n자리 수는 2^n 개이다.

즉, 0과 1을 담을 수 있는 공간이 n개 가 있으면, 2^n가지 의 숫자를 표현 할 수 있다.

 

비트(bit) : 0 과 1 을 담을 수 있는 자리

바이트(byte) : 비트 8개를 묶은 것 (즉, 1바이트 = 8비트)

 

int (4byte) 자료형 ; 4 * 8 = 32 bit

int 변수에 0, 1 을 담을 수 있는 자리가 총 32개 있다는 것

int는 2^32가지의 정수를 표현할 수 있다.

 


 

2.2.3 이진법과 정수 자료형

일상속에서 보는 숫자는 십진법

심진법 : 0~ 9 까지의 숫자 를 사용 한다.

 

심진법 3762라고 쓰면, 3762가 실제로 의미하는 숫자는

 3  *  1000  +  7  *  100 +  6  * 10 +  2 * 1 

 

가장 마지막 자리이자 가장 작은 자리인 1의 자리부터 시작해 왼쪽으로 10의 자리 ,

100의 자리 등과 같이 자리의 값이 10배씩 커진다.

 

이진법은 0과 1만 을 쓰며, 1의 자리, 2의 자리 4의 자리 — 한 자리가 증가 할 때마다 2배가 된다.

1101 은 이진수를 십진법으로 바꾸면,

1 *  8  +  1  * 4  + 0  * 2 +  1 *  1 = 13 

 

2의 거듭제곱이라 생각하면 된다. 즉 아래처럼 이진법으로 0과 1이 있을 때에 1이 있는 구간만. 2의 승수로 나온 값을 더해서 십진법으로 만들어 낼 수 있다.

 

 2^3 +  2^2 +  2^1  +  2^0 

위 값은 1 1 1 1 일 경우의 내용을 다룬다.

 

 

아래 방법은 내가 보는 방식

십진법에서 이진법으로 풀때에도, 더한 값이 어떻게 나올지 유추해 내면된다.

예를들어 14 라면,

앞에 2^3 = 8 을 생각해 볼 수 있다.

그렇다면 1000 ⇒

8 을 더했을 때 14가 나올려면 6이 있을 것이다.

6은 4 + 2 이니까. 1 1 1 0 이 면 14가 될 것이다.

나의 방식에는 좀 바로바로 안나와서 어려울 수 있다

 

1     1      1      0 

  2^3+2^2+2^1 

 

표를 그냥 외우는 방식도 있을 테다

컴퓨터에 정수를 어떻게 저장하는지 보자

 

 

이진법 십진법

0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 8
1001 9

이진법 십진법

1010 10
1011 11
1100 12
1101 13
1110 14
1111 15

4비트를 사용하면 이렇게 0부터 15까지 총 16가지 정수를 표현 할 수 있다.

(비트가 총 4개 이므로 2^4 = 16 가지가 된다)

 

위 방식으로 음수를 저장할 수 없다.

보통 맨 앞 비트는 부호 비트라 해서 숫자의 부호를 저장하는데 쓴다.

 

부호 비트가 0일 때 양수(혹은 0) 를, 1일 때는 음수를 뜻한다.

맨 앞 비트가 0인 0000부터 0111까지는 그대로 0부터 7을 의미하고,

 

맨 앞 비트가 1인 1000 ~ 1111까지는 8부터 15에 해당한다.

 

 

각각 16만큼을 빼서, -8부터, -1 까지 정수를 저장하는데 쓸 것이다.

이러면 음수의 표현도 가능하다.

 

이진법 십진법

0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7

십진법

1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1

맨 앞의 비트를 부호 비트로 사용하느냐, 사용하지 않느냐에 따라 “부호 있는 정수” , “부호 없는 정수 “ 로 나뉜다.

8비트 char 자료형과 32비트 인 int형 자료형도 자릿수만 더 늘어날 뿐 기본적인 원리는 비슷하다.

 

 

2.2.4 여러가지 자료형

C언어에 정수는 이러한 자료형이 있다.

-정수형

이름 크기(바이트) 크기(비트) 표현 가능한 숫자의 가짓수 표현 가능한 숫자 범위

char 1 8 2^8 = 256 -128 ~ 127
short 2 16 2^16 = 65, 536 -32,768 ~ 32,767
long 4 32 2^32 = 4, 294, 967, 296 -2,147,483,648 ~ 2,147,483,647
int 4 32 2^32 = 4,294,967,296 -2,147,483,648 ~ 2,147,483,647
long long 8 64 2^64 =약 1.84*10^19 약 -9.2210^18 ~ 9.2210^18

음수를 저장하고 싶지 않다면, 각 이름 앞에 unsigned 단어를 붙이면 된다.

표현할 수 있는 최대 수가 2배로 늘어난다,

 

이러한 자료형을 부호 없는(unsigned) 정수 자료형 이라고 한다.

부호 없는 정수는 부호있는 정수에 비해 잘 사용하지 않는다.

 

이름                                     크기(바이트) 크기(비트)       표현 가능한 숫자의 가짓수         표현 가능한 숫자 범위

unsigned char 1 8 2^8 = 256 0 ~ 255
unsigned short 2 16 2^16 = 65, 536 0 ~ 65,535
unsigned long 4 32 2^32 = 4, 294, 967, 296 0 ~ 4,294,967,295
unsigned int 4 32 2^32 = 4,294,967,296 0 ~ 4,294,967,295
unsigned long long 8 64 2^64 =약 1.84*10^19 0 ~ 약 1.84*10^19

🚫 졍수형의 크기 : 앞에 표기한 정수 자료형의 크기와 버뮈는 시스템에 따라 달라질 수 있다.

(현 시점에서는 일반적인 컴퓨터라면 그냥 위 표와 같다)

 

실수는 부동 소수점이라는 방식을 사용해 저장한다.

여러가지 방식이 있지만 보통 IEEE(전기전자기술자협회)에서 정한 규칙을 따른다.

 

부동 소수점을 사용하면 아주 작은 소수부터 정수형 보다 훨씬 더 큰 수까지 저장할 수 있지만,

유효 자릿수가 일정해, 숫자가 커질수록 오차도 커진다.

 

  1. 아주 작은 소수 부터 정수 보다 더 큰 수까지 저장이 가능하다
  2. 숫자가 커질 수록 오차도 커진다는 단점

이름 크기(바이트) 크기(비트) 유효 자릿수(10진법) 대략적인 표현 가능범위

float 4 32 7 ~ 8 10^-38 ~ 10^38
double 8 64 15 ~ 16 10^-300 ~ 10^300

그외 진리값(참, 거짓)을 담는 1바이트 짜리 자료형인 bool

자료형이 없다는 것을 나타내는 void

 

 

💡 bool 자료형: C++에서 새로 추가된 문법 C에서는 진리값 저장용 자료형이 기본 제공 되지 않지만.

1999년 _Bool 자료형이 추가되어 사용할 수 있게 됨

 

결과 :

a = 3, b = 10.000000

 

정수형 변수에 3.14를 집어넣었더니 소수점 이하를 버린 3 이 a에 들어갔다.

실수형 변수 b에 정수형인 10을 넣었더니 10이 들어갔는데, 형태는 부동 소수점 형태로 들어간다.

 

서로 다른 자료형 사이를 변환하는 것을

형변환(type conversion) 이라 한다.

💡 bool은 왜 8비트 인가? : 참 또는 거짓이라는 딱 두가지 값만 저장하려면 1비트만 사용해도 되는데 bool에서 굳이 8비트(1바이트)를 사용하는 이유 → 컴퓨터가 자료를 저장하고 불러올 수 있는 최소 단위가 바이트 이기 때문이다. 그래서 bool형을 써도 나머지 7비트는 어쩔 수 없이 낭비된다.

 


2.2.5 sizeof 연산자

  • 자료형 또는 변수의 크기를 알 수 있다.
#include <stdio.h>

int main() 
{
		printf("%d %d %d %d \\n", sizeof(int), sizeof(char), sizeof(float), sizeof(double));
		int a; char b; float c; double d;
		printf("%d %d %d %d\\n", sizeof(a), sizeof(b), sizeof(c), sizeof(d));
}

결과 :

4 1 4 8

4 1 4 8

  • int를 넣어준 것은 4, char 는 1 값이 출력되었다, int형 변수인 a를 sizeof(a)와 같이 입력했더니 4가 나머지 sizeof도 마찬가지

위처럼 sizeof 괄호 안에 크기를 알고 싶은 자료형이나 변수를 집어넣으면

그에 해당하는 크기를 돌려주는 것을 확인할 수 있다.

주로 메모리 할당과 같은 작업을 할 때 유용하다.


2.3 형변환

  • 변수에 서로 다른 자료형의 값을 대입하려고 하면 형변환이라는 현상이 일어난다.
#include <stdio.h>

int main() 
{
		int a = 3.14;
		int b = 10;
	
		printf("a = %d, b=%f\\n", a, b);
}
  • 정수형 변수 a에 실수형인 3.14를 집어 넣었더니 소수점 이하를 버린 3이라는 값이 a에 들어갔다
  • 실수형 변수 b에 정수형인 10을 집어넣었더니 10이 들어갔다. 물론 부동소수점 형태로 들어간다.

⇒ 위처럼 서로 다른 자료형 사이를 변환하는 것을 ‘형변환(type conversion)이라고 한다.

 

 

 

예제 ) 수학, 국어, 영어 성적을 각각 int형 변수에 저장한 후 평균 점수를 구하는 코드

  • 자료형이 같은 변수 끼리는 예제 처럼 쉼표로 구분해서 한 번에 묶어서 선언이 가능하다.
#include <stdio.h>

int main()
{
		int math = 90, koren = 95, english = 96;
		int sum = math + korean + english; // 세 점수의 합을 sum에 저장한다
		double avg = sum / 3; //sum을 3으로 나눠 평균을 구한다. 

		printf("평균 점수 : %f\\n", avg);
}

결과 :

평균 점수 : 93.000000

 

실제 평균점수는 93.66…으로 나와야 하지만, 93.00…으로 나오는 것은 sum 이 정수형 변수 이기 때문이다. 앞에서 정수 끼리의 사칙연산 결과는 정수라고 했다, 그래서 sum / 3 의 결과는 sum의 값인 281을 3으로 나눈 몫인 93이다.

93이 double avg에 대입되어 avg의 값이 93.00…으로 저장된 것이다..

 

 

int형인 sum의 값을 수동으로 double로 형변환 하면 된다.

sum 앞에 다음과 같이 (double)을 붙여주자.

#include <stdio.h>

int main()
{
		int math = 90, korean = 95, english = 96;
		int sum = math + korean + english;
		double avg = (double)sum / 3;

		printf("평균 점수 : %f\\n", avg);
}

결과 :

평균 점수 : 93.666667

 

형변환 하고 싶은 값 앞에 괄호를 쓰고 바꾸고 싶은 자료형을 넣으면 된다.

예제에서, int형 sum변수의 값이 실수형인 double로 바뀌게 된다.

정수 281 이 실수 281.00…으로 형변환 된다.

이 때 이 값을 3으로 나누면 결과값에도 실수인 93.66… 이 들어가게 된다.

 

 

정수와 실수의 나눗셈에 대해 4가지

  1. 정수/정수 → 정수
  2. 실수/정수 → 실수
  3. 정수/실수 → 실수
  4. 실수/실수 → 실수

실수가 하나라도 있으면 결과는 실수가 된다.


2.4 char형과 ASCII코드

2.4.1 문자끼리의 덧셈 : ‘2’ + ‘3’ = ‘e’

문자를 2개 더하면 ‘2’ + ‘3’ 의 결과값이 무엇인지

#include <stdio,h>

int main()
{
		printf("%c + %c = %c\\n", '2', '3', '2' + '3');
}

결과 :

2 + 3 = e

문자 ‘2’와 ‘3’ 을 더했더니 e가 출력이 되었다. C언어에서는 ‘문자’는 작은 따옴표 안에 들어가야 하고,

작은 따옴표 안에 들어갈 수 있는 문자로는 알파벳 대소문자, 숫자, 몇몇 기호 등이 있다.

a와 ‘a’가 다른 의미 이듯이 2 와 ‘2’도 다른 의미이다.

 

 

 

실제로 다르다는 것을 알아보자

#include <stdio.h>

int main()
{
		printf("%c %d\\n", '2', '2');
}

결과 :

2 50

 

문자 ‘2’를 %c로 출력시 = 2가 출력 되는 것은 당연하다

문자 ‘a’를 %c로 출력했을 때 a가 출력되는것과 같은 이치 이다.

이 문자를 %d를 사용해 출력했을 때 50이 출력이 되는 이유

C언어에서 ‘2'와 50은 같은 말이다.

‘3’ 과 51과 같은 말이고,

‘e’는 101과 같다.

 

 

미국의 표준화 단체 ANSI의 전신인 ASA에서 정보통신에 사용되는 문자 마다 고유한 번호를 부여 했다.

0번 부터 31번 까지는 실제 문자가 아닌 특수한 목적의 코드 이며,

32번 부터 127번 까지는 문자, 숫자, 기호 들이 정의되어 있다.

이목록은 ASCII(아스키) 코드표 를 통해 확인이 가능하다.

문자마다 대응되는 정숫값이 있고, 그 값을 ASCII값이라고 부른다.

ASCII코드표 때문에 컴퓨터는 문자를 표현할 때 그 문자에 해당하는 ASCII 값을 사용한다.

‘a’라고 적으면 알파벳 ‘a’로 보이지만 컴퓨터 내부적으로는 a의 ASCII값인 97로 해석된다.

 

C언어에서 문자는 그에 해당하는 ASCII 값과 같은 의미

‘2’의 ASCII값은 50.

‘3’ = 51이므로

‘2’ + ‘3’ 을 하면 50 + 51 = 101 , 101에 해당하는 ASCII 문자는 ‘e’ 이므로 ‘2’ + ‘3’ 의 결과가 e가 되는 것이다.

 

예제) ‘2’와 ‘2’ 에 해당하는 ASCII값 50을 모두 %c 와 %d로 출력해보자

#include <stdio.h>

int main()
{
		printf("%c %d\\n", '2', '2');
		printf("%c %d\\n", 50, 50);
}

결과 :

2 50

2 50

 

‘2’든 50이든 컴퓨터 내부적으로는 같은 의미지만 , 출력할 때 %c 를 쓰느냐 %d 를 쓰느냐에 따라 문자 형태로 출력되는지 숫자 형태로 출력되는지 결정된다.


2.4.2 문자형으로서 char형

컴퓨터에서 문자를 저장할 때도 마찬가지로 문자 자체가 아닌 그 문자에 해당되는 ASCII 값을 저장한다.

문자를 저장할 때도 그냥 정수형 변수를 사용한다.

 

일반적으로 ACSII 코드는 127번까지만 있기에 특별한 이유가 없으면 문자는

-128 ~ 127까지 정수를 담을 수 있는 1바이트 짜리 char형에 저장한다.

 

예제)

#include <stdio.h>

int main()
{
		char a = 'A';
		
		printf("%c의 ASCII 값은 %d\\n", a, a);
}

결과 :

A의 ASCII 값은 65

 

main함수의 첫째 줄 char a = ‘A’; 에 실제 a 변수에 들어가는 값은 A의 ASCII 값인 65 이다.

즉 char a = 65;의 값도 말이 된다.

 

 

a를 출력할 때 %c 를 사용하면 A가, %d를 사용하면 65가 출력되는 것을 확인 할 수 있다.


 

 

2.5 변수로 연산하기

2.5.1 대입 연산자와 복합 대입 연산자

변수에 어떤 수를 대입할 때 쓰는 ‘ = ‘ 기호 를 대입연산자라 한다.

예제)

#include <stdio.h>

int main()
{
		int a = 5;
		printf("원래 a의 값은 %d였다!\\n", a);

		a = a + 3;
		printf("a에 3을 더했더니 %d이 되었다!!!\\n", a);
}

결과 :

원래 a의 값은 5였다!

a에 3을 더했더니 8이 되었다!!!

 

C언어는 등호는 같다는 의미가 아니다.

 

연산자 등호를 쓰면 등호 오른쪽에 있는 값이 계산된 후

  1. 그 값이 왼쪽에 대입된다.
  2. 원래 a의 값인 5인 상황에서 a+3을 계산하면 8이 나온다 그 뒤 8이 다시 a에 대입된다.

 

결론적으로 a에는 원래 값 5에서 3이 증가해 8이라는 새로운 값이 들어가게 된다.

 

a = 5;

a = a + 3 ⇒ 8

8 ⇒ a 에 저장

 

변수 이름을 두번 써야 하는 경우가 있는데,

 

C언어에서는 좀 더 간결하게 적을 수 있다.

a += 3;    // a = a + 3; 과 같은 의미

+=는 하나의 연산자 이기에 다음 처럼 띄어 쓰면 안된다.

a + = 3; //에러 

사칙연산자(+, -, *, /) 와 나머지 연산자(%)에 대해 공통으로 적용된다

a -= 3;   // a = a - 3;
a += 3;   // a = a + 3;
a /= 3;   // a = a / 3;
a %= 3;   // a = a % 3; 

이러한 연산자를 복합 대입 연산자 라고 부른다

각 연산을 수행했을 때 어떻게 변화하는지 중요


2.5.2 증감 연산자

정수형 변수를 1증가 또는 감소시킬 때는 ++ 와 - - 라는 좀 더 특화된 연산자가 있다.

#incldue <stdio.h>
int main()
{
		int a = 5;
		printf("a는 원래 %d였다!\\n", a);
		a++;  // a += 1; 과 같다. 
		printf("1 증가 해서 %d이 됐다!!\\n", a);
		a--;
		printf("1 감소해서 %d가 됐다!!!\\n", a);
}

a는 원래 5였다!

1 증가해서 6이 됐다!!

1 감소해서 5가 됐다!!!

#include <stdio.h>

int main()
{
		int a = 5; 
		int b; 

		b = ++a;
		printf("=== 전치 증가 연산 ===\\n"):
		printf("a = %d\\n", a):
		printf("b = %d\\n", b):

		b = a++;
		printf("=== 후치 증가 연산 ===\\n"):
		printf("a = %d\\n", a):
		printf("b = %d\\n", b):
}

결과

=== 전치 증가 연산 ===

a = 6

b = 6

=== 후치 증가 연산 ===

a = 7

b = 6

 

 

전치 증가 연산은 ++a; 처럼 변수 앞에 연산자를 쓴다

이때 b = ++a;라 쓰면 a 가 1증가 한 후 , 증가된 값이 b에 들어간다.

대입 전에 증가가 이루어지므로 전치 증가 연산이다.

연산전 a의 값은 5이고, a가 1증가해서 6이 된 후 a의 값인 6이 b에 대입되어 b도 6이 된다.

 

 

후치 증가 연산은 ++a; 처럼 변수뒤에 연산자를 쓴다. b = a++;라고 쓰면 a의 값이 b에 대입된 후,

a가 1증가한다.

대입 후에 증가가 이루어지므로 후치 증가 연산이라고 불린다.

 

 

위 예제 에서 후치 연산 전 a의 값은 6이다.

(전치 연산에서 이미 1증가 했다)

이떄 b에 a의 값인 6이 먼저 들어간 후, a가 1증가 한다. 결론적으로 a 에는 7이 들어가고 b에는 6이 들어간다.

 

감소 연산도 마찬가지이다.


2.5.3 비교 연산자와 진리값

  • 비교 연산자는 두 값의 크기를 비교 할 때 사용

연산자 의미

== 같다
!= 다르다
> 크다
< 작다
>= 크거나 같다
<= 작거나 같다

비교 연산의 결과는 항상 참 또는 거짓이다.

컴퓨터는 참을 1, 거짓을 0으로 표현한다

이 값을 진리 값이라고 불린다.

 

진리 값도 1, 0으로 표현 되는 정수이기에 C에서 진리값은 일반 정수형 변수(int, char 등)에 담을 수 있다.

C++에서는 bool이라는 1바이트 짜리 자료형을 사용한다.

 

 

bool형을 직접 출력하는 일은 드물다. %d를 사용할 수 있다.

#include <stdio.h>

int main()
{
		int a = 30, b = 50;

		bool p = a > b;
		bool q = a < b;
		boll r = a == b;

		printf("%d은(는) %d 보다 크다: %d\\n", a, b, p);
		printf("%d은(는) %d 보다 작다: %d\\n", a, b, q);
		printf("%d은(는) %d과(와) 같다: %d\\n", a, b, r);
}

30은(는) 50보다 크다 : 0

30은(는) 50보다 작다 : 1

30은(는) 50과(와) 같다 : 0

 

💡 C에서는 bool자료형을 기본 제공하지 않는다고 하였다, C에서는 비교 연산의 결과도 bool이 아닌 int형이다. C++에서는 비교 연산의 결과가 bool이다. C++에서 참 거짓을 표현 할 때 true, false라는 키워드를 사용할 수 있다. true, false의 값도 1, 0 이지만 그냥 1, 0과의 차이점은 자료형이 bool이라는 것이다. 자료형만 다를 뿐, bool형 변수에 1, 0을 대입하거나 int형 변수에 true, false값을 대입해도 문제는 없다

 


2.5.4 논리 연산자

논리 연산자는 진리값을 연결하거나 부정하는 연산자

 

연산               의미                                                         결과값

p && q p이면서 q이다(p and q) p와 q가 모두 참일 때만 참, 그 외에는 거 짓
p   q
!p p가 아니다(not p) p가 거짓이면 참, p가 참이면 거짓
#include<stdio.h>

int main() {
	int a = 3;

	bool p = a >= 1 && a <= 10; // a가 1이상이고 10 이하다
	bool q = a == 3 || a == 7; 	// a가 3이거나 7이다 
	bool r = !q; // q가 아니다 -> a가 3도 아니고 7도 아니다.

	printf("%d\\n", p);
	printf("%d\\n", q);
	printf("%d\\n", r);
}

결과 :

1

1

0


2.5.5 연산자 우선 순위

다음 시의 계산 결과는?

40 - 32 / 2 = ? 

답 : 24

사칙연산의 우선순위 대로 한다면, 곱셈과 나눗셈을 덧셈과 뺄셈보다 먼저해야한다는 것

C도 사칙연산과 그 외의 다양한 연산이 있다. 이 연산에는 우선순위가 있다.

 

우선순위를 나타내는 숫자가 작을수록 높은 우선순위 이다.

(예 : 우선순위가 3인 연산자가 우선순위가 4인 연산자 보다 먼저 계산된다.)

우선순위 연산자 설명 결합 순서

1 ++ ㅡㅡ 후위 증감 연산 좌 → 우
  ( ) 함수 호출  
  [ ] 배열 원소 접근  
  . -> 구조체 멤버 접근  
2 ++ ㅡㅡ 전위 증감 연산 우 → 좌
  + ㅡ 단항 +, -연산(덧셈 뺄셈 연산자와 다름)  
  ! ~ 논리 부정, 비트 NOT연산  
  (자료형) 형변환  
  * 포인터 역참조  
  & 주소  
  sizeof sizeof 연산  
3 * / % 곱셈, 나눗셈, 나머지 연산 좌 → 우
4 + ㅡ 덧셈, 뺄셈 연산자 좌 → 우
5 << >> 비트 시프트 연산자 좌 → 우
6 < <= 작다, 작거나 같다 좌 → 우
  > >= 크다, 크거나 같다  
7 == != 같다, 다르다 좌 → 우
8 & 비트 AND 연산 좌 → 우
9 ^ 비트 XOR 연산 좌 → 우
10   (₩) 비트 OR 연산
11 && 그리고 좌 → 우
12     (₩₩)
13 ?: 삼항 연산자 좌 → 우
14 = 단순 대입 좌 → 우
  += -= 복합 대입(덧셈, 뺄셈) 우 → 좌
  *= /= %= 복합 대입(곱셈, 나눗셈, 몫)  
  <<= >>= 복합 대입(비트 , 시프트)  
  &= ^= = 복합 대입(비트 AND, XOR, OR)
15 , 콤마 좌 → 우

💡 결합 순서란 우선순위가 같은 연산자 끼리 계산되는 순서를 말한다. 예 ) 뺄셈은 결합 순서가 좌 → 우 이므로 9 - 5 -2 를 계산 할때 왼쪽에 있는 9 - 5 부터 계산되어 4를 얻은 후, 그 뒤 4 - 2 가 계산된다

하지만 대입연산자는 결합 순서가 우 → 좌 이기에, a = b = c와 같이 쓰이면, b에 c가 먼저 대입 된 후 a에 b가 대입된다.

 

사칙 연산 중에서는 곱셈과 나눗셈, 그리고 나머지 연산이 먼저 계산되고, 다음으로 덧셈과 뺄셈 이 계산된다.

40 = 32 / 2

괄호를 사용하면 괄호 안이 반드시 먼저 계산된다. 다음 연산 결과는 4이다..

(40 - 32) / 2

가장 많이 쓰이는 연산인 사칙연산, 비교 연산, 논리 연산, 대입 연산은 이 순서대로 우선순위가 정해진다.

예를들어 다음과 같은 식이 있을 때, 1 + 5와 2 * 3이 제일 먼저 계산되고, 그 다음으로 == 와 <가, 그다음 &&가 계산되고, 마지막에 =로 대입이 이루어진다.

a = 1 + 5 == 2 * 3 && 2 < 5;

728x90
728x90
LIST
profile

Adventure of 빠타박스

@PPATABOX

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!