C언어 기초: 연산자

김영채 (Kevin)·2020년 3월 5일
0

C언어

목록 보기
3/23
post-thumbnail

증가 감소 연산자 ++, —

int n=10;

printf("%d", n++); //출력:10
print("%d", n);  //출력:11

int n=10;

printf("%d", ++n);  //출력:11
print("%d", n);  //출력:11

int n=10;

printf("%d", n--); //출력:10
print("%d", n);  //출력:9

int n=10;

printf("%d", --n);  //출력:9
print("%d", n);  //출력:9

x = a++

  1. x = a —> value of expression is a
  2. a = a+1 —> value of a is incremented by 2

x = ++a

  1. a = a+1 —> value of a is incremented by 1
  2. x = a —> value of expression is a after incremented

잘못된 사용 예시

int a=10;
++300;   //상수에는 증감연산자 사용 불가
(a+1)--;   //일반 수식에는 증감연산자 사용 불가

//하나의 연산식에 동일한 변수의 증감연산자는 사용되도록이면 하지 않기
a = ++a * a--;

증가 감소 연산자

int main()
{
    int m = 10, n=5;
    int result;
    
    result = m++ + --n; 
    printf("m=%d n=%d result=%d\n", m,n,result);
    
    result = ++m - n--;  
    printf("m=%d n=%d result=%d\n", m,n,result);

    return 0;
}

출력:

n=4 result=14                                                                         
m=12 n=3 result=8

단축 평가 (Short Circuit Evaluation)

⇒ 논리연산자 &&와 ||는 피연산자 두 개 중에서 왼쪽 피연산자만으로 논리연산 결과가 결정된다면 오른쪽 피연산자는 평가하지 않는다. (연산의 효율을 up)

예를 들어, x&&y 연산식에서 x의 값이 0(거짓)이라면 y의 값을 평가하지 않고 x&&y 결과는 바로 0이 된다. && 연산에서는 피연산자 둘 다 참(true)이어야 하기 때문에 x가 참이면 더 볼 것도 없이 false.

예시

int main()
{
    int a=10, b=5, m=1;
    int result;
    
    result = (a<b) && (m++ == 1);  // a<b는 false이기 때문에 0이 결과값, m++ == 1은 참이기 때문에 1이 결과값. &&이기 때문에 0이 result에 대입.
    printf("m=%d result=%d\n", m,result);
    
    result = (a>b) || (--m==0);
    printf("m=%d result=%d\n", m,result);

    return 0;
}

출력값:

m=1 result=0                                                                               
m=1 result=1

조건 연산자

연산자 ? :

조건 연산자는 조건에 따라 주어진 피연산자가 결과값이 되는 삼항연산자이다.

예) 연산식 (x ? a : b)에서 피연산자는 x,a,b, 3 개이며, 첫 번째 피연산자인 x가 참이면(0이 아니면) 결과는 a이며, x가 0이면(거짓) 결과는 b이다. 즉, x에 따라 결과는 a또는 b이다.

조건연산자를 이용하면 두 수의 최대값최소값을 쉽게 구할 수 있다. 절대값도 쉽게 구할 수 있다.

예)

max = (a>b) ? a : b; //a가 b보다 크면 max = a
max = (a<b) ? b : a;
min = (a>b) ? b : a;
min = (a<b) ? a : b;

absolute = (a>0) ? a : -a; //절대값 반환 조건연산
absolute = (a<0) ? -a : a;

비트연산자

정수형에 대한 비트 중심 연산자로 비트 논리연산자이동연산자가 제공된다.

비트 논리 연산자

⇒ 피연산자 정수값을 비트 단위로 논리 연산을 수행하는 연산자로, &,|,^,~ 이 4 가지이다.

  • 비트 논리 연산자에 이용되는 피연산자의 자료형은 정수형에 해당하는 int, char, long, long long이면 가능하다.
  • 비트 연산은 각 피연산자를 int 형으로 변환하여 연산하며 결과도 int 형이다.

예) 3 & 5

3: 0011

5: 0101


3 & 5 = 1 0001

예) 3 | 4

3: 0011

4: 0100


3 | 4 = 7 0111

예) 3 ^ 4

3: 0011

4: 0100


3 ^ 4 = 7 0111


비트 이동 연산자 (bit shift operators)

⇒ >> 또는 <<는 연산자의 방향인 왼쪽이나 오른쪽으로, 비트 단위로 줄줄이 이동시키는 연산자이다.

예)

#include <stdio.h>

int main(void){
    unsigned char a = 4 << 1;  // 0000 0100
    unsigned char b = 8 << 2;  // 0000 1000
    
    printf("4 << 1 : %d\n", a);
    printf("8 << 2 : %d\n", b);
	
    a = 6 << 3;  // 0000 0110
    b = 10 << 4; // 0000 1010
  
    printf("6 << 3 : %d\n", a);
    printf("10 << 4 : %d\n", b);
	
}

연산 설명: - a는 원래 4 (0000 0100) 이지만 << 1 을 했기 때문에 8 (0000 1000)이 된다.

       -  b는 원래 8 (0000 1000) 이지만 << 2 를 했기 때문에 32(0010 0000) 가 된다.

비트가 한 자리씩 왼쪽으로 이동할 때마다 정수의 값은 두 배가 된다.

2진수이기 때문에 2칸을 이동하면 4배가 되고, 3칸을 이동하면 8배가 된다. 즉, 2의 n승 만큼 곱하면 된다.

비트 연산은 비트 단위에서 직접 조작하기 때문에 일반 사칙 연산보다 더 빠르다.

추가 예시)

-16387: 0100 0000 0000 0011

16387 << 2 ⇒ 0000 0000 0000 1100 (=12)

(기존 가장 왼쪽에서 두 번째에 있던 1이 왼쪽으로 빠져버려서 없어짐)

16387 >> 2 ⇒ 0001 0000 0000 0000 (=4096)

(기존 가장 오른쪽에서 있던 1 두 개가 오른쪽으로 밀려나서 빠져버림)

signed의 경우: 부호비트(0 or 1) 값으로 채워진다.
unsigned의 경우: 0으로 채워짐.


형변환 연산자와 연산자 우선순위

자동 올림 변환

7 + 5.2 식에서 7이 7.0 (double)로 자동 올림 변환이 됨. ⇒ 7.0 + 5.2 = 12.2 (double) 이 된다.

다양한 올림변환의 예)

Untitled

보아하니 데이터 손실이 가장 적은 방안으로 자료형이 자동으로 올림변환 되는 것 같다.

자동 내림/올림

int a = 3.4; //자동으로 내림변환되어 변수 a에는 3이 저장된다.
double d = 3; // 자동으로 올림변환되어 변수 d에는 3.0이 저장된다.

*int a = 3.4; 라는 식을 작성하게 되면 컴파일 중 아래와 같은 오류 메시지가 나올 수 있음:

Warning C4244: ~~ 'double'에서 'int'로 변환하면서 데이터가 손실될 수 있습니다.

형변환 연산자

-강제 형변환 / 데이터 손실 우려 있음

(int) 30.525 //30으로 저장

//다양한 예시:
(int) 'A'  //65
(int) 3.14 //3
(double) 9 // 9.0
(double) 3.4F // 3.4
(double) 7/2 // 3.5

예)

double result = (double) 7/2;
// 7.0/2가 되어서 결과가 3.5가 되어 result에 대입됨.
// 형변환을 사용하지 않으면 7/2는 그냥 3이 되어 3.0이 result에 대입됨.

//다양한 예시:
(int) 3.8 + 5.7 // 8.7
3.8 + (int) 5.7 // 8.8
(int) 3.8 + (int) 5.7 // 8
(int) (3.8+5.7) // 9
7/2 // 3
7.0 / 2 //3.5
7 / (double) 2 // 3.5

연산자 sizeof

형식: sizeof (exp_or_keyword)

sizeof (int) //결과는 4
sizeof (3.14) // 결과는 8
sizeof a // 결과는 2 (short a;)

//비트 크기랑 연관 있나?

콤마 연산자 (,)

형식: exp1 , exp2

위 형식에서, 결과값은 나중에 계산된 exp2의 결과값이다.

콤마 연산자는 둘 이상의 변수를 동시에 선언하거나, 둘 이상의 문장을 한 행에 삽입하는 경우에 사용됨.

또한, 둘 이상의 인자를 함수로 전달할 때도 인자의 구분을 목적으로 사용되기도 함.

int main(void)
{
	int num1=1, num2=2;
	printf("Hello "), printf("world! \n");
	num1++, num2++;
	printf("%d ",num1), printf("%d ",num2), printf("\n");
	return 0;
}

이렇게 둘 이상의 함수 호출문이나 연산문이 하나의 문장 안에 삽입되어 있는 것을 볼 수 있음.

3+4, 5-10 이라는 식에서는 결과는 -5

3+4, 5-10, 2*3 이라는 식에서는 결과는 6

int main()
{
    int x;
    
    printf("%d", (x=3+4,2*3));
    
    return 0;
}


출력값: 6
//연산자 우선 순위가 작용하는 것

결합성

int n = 10, m =5;
n += m /= 3; 

우에서 좌(←)로 먼저 결합하는 축약 대입연산자

m /= 3 는 곧 m = m/3 —> 결과는 1 (5 / 3 = 1)

그러면 n += 1, 즉, n = n + 1 이 최종 식이 된다.

n은 10이기 때문에 결국 최종값은 11

profile
맛있는 iOS 프로그래밍

0개의 댓글