C언어 연산자

Minimal_user·2024년 5월 6일

c언어

목록 보기
6/17
연산자 종류연산자
산술 연산자+ - * / %
부호 연산자+ -
대입 연산자= 복합 대입 연산자(+=, -=, *=, /= , %=, [비트연산자도 가능 <<= >>= &= |= ^=])
관계 연산자-- != <= < >= >
증감 연산자++ --
포인터 연산자* & []
구조체 연산자. ->
논리 연산자|| && !
비트 연산자| & ~ >> <<
삼항 조건 연산자? :
쉼표 연산자,
sizeof 연산자sizeof(타입 또는 변수)
캐스트 연산자(type) type()
괄호 연산자()

1. 산술 연산자

  • 나눗셈 연산자 주의 사항
    • 이 연산자는 피연산자 타입에 따라 연산의 결과가 달라지는 특징이 있다.
    • 피연산자에 실수형이 있으면 연산의 결과가 실수형이다.
    • 정수형의 나눗셈의 경우 몫만 결과값으로 나온다.
  • 나머지 연산자는 피연산자로 정수만 취할 수 있다. (결과값도 정수형이다.)
6/3 // 결과 : 2
3.0/2.0 // 결과 : 1.5
3.0/2 // 결과 : 1.5
3/2. // 결과 : 1.5  #  참고 2. 은 오타가 아님
3/2 // 결과 : 1  #  주의할 것.

2. 대입 연산자

  • 대입 연산자의 우변에는 '상수, 변수와 연산자들로 구성된 계산할 수 있는 표현식'이 오며 '함수 호출문'도 올 수 있다.
    • 하나의 결과를 계산해 낼 수만 있다면 어떤 표현식이 와도 상관없다.
  • 대입 연산자의 좌변에는 '좌변값'만 올 수 있다.
    • 실제적인 메모리를 점유하고 있고 그 값을 바꿀 수 있는 대상을 의미한다.
    • char str[12]; str='STRING'; 과 같은 예는 실수하기 좋은 틀린 예다.
      • 문자 배열은 문자열을 저장할 수 있지만 이런 식으로 문자열을 대입할 수 없다.
        왜냐하면 배열의 이름인 str은 좌변값이 아니기 때문이다.
      • 배열 요소는 좌변값이지만 배열은 좌변값이 아니다.
      • 다차원 배열의 경우에도 최종 요소만 좌변값이며, 다차원 배열의 부분 배열은 요소이기는 하지만 좌변값은 아니다.
      • 포인터변수 ptr이 있을 때 *ptr은 좌변값이지만 &ptr은 좌변값이 아니다.
  • a=b=c=5 같은 코드도 사용 가능하다. c에 5가 대입되고 c변수의 값은 b에 대입된다. b변수가의 값은 a에 대입된다.

3. 증감 연산자

  • 전위형 : 증감연산자가 피연산자 앞에 위치. ++a, --a
  • 후위형 : 증감연산자가 피연산자 뒤에 위치. a++, a--
int i, j;
i=j=3;
printf("%d %d\n", ++i, j++); // 결과 : 4 3
printf("%d %d\n", i, j); // 결과 : 4 4
  • 참고
    • c언어는 함수의 인수를 뒤에서 부터 순서대로 전달하기 때문에 int i=3; printf("%d, %d\n", i, ++i);와 같은 코드의 결과는 4 4 다.

4. 논리 연산자

  • 좌변과 우변의 데이터 타입이 일치해야 한다.
  • 관계 연산자는 수식을 평가하여 그 결과가 참이면 1(true)을 리턴하고 거짓이면 0(false)을 리턴한다.
    • c언어에서는 0값은 항상 false 이므로 다음과 같이 활용할 수도 잇다.
      • if(c=a%b) 명령;if(c != 0) 명령; 과 동일하다.
      • while(a--) 명령;while(a!=0) {a--;명령;} 과 동일하다.
  • 쇼트서킷(Short Circuit) 참고.
    • 이 기능은 컴파일러 차원에서 지원한다.

5. 비트 연산자

연산자설명
~비트를 반전시킨다.
&대응되는 비트가 모두 1일 때 1이다.
|대응되는 비트가 모두 0일 때 0이다.
^두 개의 비트가 달라야 1이다. (xor 연산)
<<지정한 수만큼 왼쪽으로 비트들을 이동시킨다.
>>지정한 수만큼 오른쪽으로 비트들을 이동시킨다.
  • 쉬프트 연산의 피연산자는 주로 부호없는 정수형이다. 실수형은 당연히 안된다.
  • 쉬프트 연산은 곱셈과 나눗셈의 대용으로 사용할 수 있다. (설명 생략)
  • 회전 (Rotate)연산은 비트를 원형으로 이동시킨다.
    비트 이동에 의해 밀려나는 비트는 버려지지 않고 반대쪽으로도 다시 이동된다는 것이 특징이다.
    연산자 형태로는 제공되지 않으며 _rotl, _rotr 함수로 제공된다.
    • 쉬프트는 비트를 선형으로 이동시킨다.

6. 삼항 조건 연산자

  • (조건식) ? 값1:값2
  • 값1 과 값2는 동일한 타입이어야 한다.
int i=3, j=4, k;
k=(i>j) ? i : j;

7. 쉼표 연산자

  • 피연산자로 양쪽에 두 개의 표현식을 취하면 좌변을 먼저 평가하고 우변을 평가한 후 우변의 연산 결과를 리턴한다.
int i, j;
//i=3;
//j=i+2;
// 위 두 줄의 코드는 아래와 동일하다.
j=(i=3, i-2);
// 아래와도 동일하다
//j=(i=3)+2;

// 주의 사항으로 j=i-3, i+2는 완전히 다른 의미이므로 괄호를 잘 이용해야 한다.

//활용 예
for (i=1, j=1; i<5; i++, j+=2){
    // ...
}

8. sizeof 연산자

  • 피연산자로 주어진 타입 또는 변수의 크기를 계산한다.
int i;
printf("%ld\n", sizeof(int)); // 결과 : 4
// 서식 주의 'l'을 추가하는 이유는 sizeof 의 리턴 값이 int 보다 클 수 있기 때문. %d는 int크기까지만 출력 가능.
printf("%ld\n", sizeof(double)); // 결과 : 8
printf("%ld\n", sizeof(i)); // 결과: 4
printf("%ld\n", sizeof("string")); // 결과 : 7  #  여섯 글자지만 Null 종료 문자도 고려

int j [10][2];
printf("%ld\n", sizeof(j)); // 결과 : 80  #  4*10*2
  • 코드상에서 예를 들어 배열의 크기가 바뀔 우려가 있다면 배열의 크기를 받는 함수 파라미터나 피연산자를 sizeof로 사용하면 좋을 것이다.
// j 배열의 한 요소 배열의 요소 갯수
printf("%ld\n", sizeof(j[0])/sizeof(j[0][0]));
// j 배열의 한 요소 갯수
printf("%ld\n", sizeof(j)/sizeof(j[0]));

9. 캐스트 연산자

  • 캐스트 연산자는 수식내에서 변수의 타입을 강제로 다른 타입으로 바꾼다.
    • c에서 지원 하는 캐스팅 연산자 : (타입)변수
    • c++에서 지원하는 캐스팅 연산자 타입(변수)
  • 정수와 정수의 나눗셈에 발생하는 소수점을 잃지 않기 위해서 아래와 같이 캐스팅하여 계산할 수 있다.
int i=3, j=4;
double r;
r= (double)i/j;

10. 연산 규칙

  • 연산 순위 및 결합 순서
순위연산자결합순서
1() [] -> .왼쪽 우선
2! ~ ++ -- + -(부호) *(포인터) & sizeof 캐스트오른쪽 우선
3*(곱셈) / %왼쪽 우선
4+ - (덧셈, 뺄셈)왼쪽 우선
5<< >>왼쪽 우선
6< <= > >=왼쪽 우선
7== !=왼쪽 우선
8&왼쪽 우선
9^왼쪽 우선
10|왼쪽 우선
11&&왼쪽 우선
12||왼쪽 우선
13? :오른쪽 우선
14= 복합 대입오른쪽 우선
15,왼쪽 우선
  • 산술 변환
    1. 이항 연산시 양변의 타입이 다르면 큰 쪽으로 상승 변환된다.
    2. 대입 연산시 좌변의 타입을 따른다.
    3. 함수 호출시 실인수와 형식인수의 타입이 다르면 형식인수의 타입을 따라간다.
      • 형식 인수는 함수의 정의를 할 때 정의한 값을 전달 받는 변수를, 실인수는 이 변수에 대입되는 값을 의미.
    4. 캐스트 연산자를 사용하면 강제로 타입을 변환할 수 있다.
    5. 수식 내에서 사용될 경우 char, unsigned char, enum형은 int형으로 자동 확장되며, float형은 double형으로 확장된다.
    6. 부호 확장의 경우, 양수의 경우 1바이트 값을 2바이트로 확장할 때 16진수로 계산할 때 앞 쪽 공간에 0을 추가한다.
      음수의 경우에는 f를 추가하여 확장되더라도 부호를 보존할 수 있도록한다.

출처 : 혼자 연구하는 C/C++ 1 / 김상형 저 / 와우북스

profile
White book for everything I need.

0개의 댓글