목차
A. 산술 관계 논리 |
B. 그 외 |
C. |
A. 산술 관계 논리 연산자
- 연산자=명령어, 연산대상인 데이터=피연산자(상수-변수-수식). 피연산자 개수에 따라 단항 이항 삼항
____1. 산술&대입
- 산술 연산자 + - * / % 대입연산자 =
- 나누기 나머지 연산자
double apple = 5.0 / 2.0; // 실수와 실수의 나누기 연산은 2.5
int banana = 5 / 2; // 정수와 정수의 나누기 연산은 2
int mango = 5.0/2.0 //결과는 2
double mango = 5/2 //결과는 2.000000
- 증감 연산자 ++a와 a++는 차이가 있다. 쓰고 늘리냐 늘리고 쓰냐.
하나의 수식에서 같은 변수를 두 번 이상 쓸 때는 증감연산자 못 씀.
#include <stdio.h>
int main(void) {
int a = 0;
a = (++a) + a + (++a);
printf("%d", a);
return 0;
}
/*
Compiler warnings:
gcc-9 -std=gnu17 -Wall -Wno-unused-variable -Wno-unused-but-set-variable -Wno-main
In function 'main':
5:5: warning: operation on 'a' may be undefined [-Wsequence-point]
5 | a = (++a) + a + (++a);
| ~~^~~~~~~~~~~~~~~~~~~
5:5: warning: operation on 'a' may be undefined [-Wsequence-point]
*/
____2. 관계 연산자
- < > <= >= == != 이항. 결과는 0이나 1(사실 0이 아니면 다True로 인식)
-
____3. 논리 연산자
- &&(AND) ||(OR), !(NOT)
- 숏서킷 룰( && ||)적용: 알고리즘 속도에 중요한 영향이 있을 것 같음. 증감연산을 후항에 넣으면 증감연산이 안 될 수 있음.
연산 결과 바로 출력 안 하거나 변수에 저장하지 않으면 버려짐(레지스터가 다음 연산에 이용되므로). 컴파일러 경고: 결과가 사용되지 않습니다.
메모리의 값을 CPU 레지스터에 불러와서(LOAD) ALU에서 연산.
ALU (arithmetic and logical unit)는 덧셈, 뺄셈 같은 두 숫자의 산술연산과 배타적 논리합, 논리곱, 논리합 같은 논리연산을 계산하는 디지털 회로이다. 산술 논리 장치는 컴퓨터 중앙처리장치의 기본 설계 블록이다.
출처: 위키피디아
B. 그 외
____1. 형 변환
(자료형)피연산자, (int)는 소수점을 버림.
- 자동 형 변환(암시적 묵시적) 기본 규칙=큰쪽으로. 예상못한 일이 발생할 수 있으므로 가급적 피연산자의 형대를 같게 맞춰 연산
____2. sizeof 연산자
- sizeof(변수, 상수, 자료형 수식 등) : 데이터 크기 확인, 메모리의 동적 할당.
문자열 크기 확인에도 사용 가능(\0의 널 문자 하나가 더 붙음)
- 괄호: 연산자이므로 괄호를 안 써도 되지만...(함수아님)
뒤에 다른 연산자를 둔 수식이 온다면 예상과 다르게 동작할 수 있고 자료형을 괄호 없이 붙이면 선언으로 인식해 에러.
____3. 복합대입 콤마 조건 비트
+=, -=, *=, /=, %= 좌항 피연산자는 반드시 변수.
- 콤마 연산자는 대입 연산자보다 순위 낮음(대입 연산자와 함께 사용 시 괄호 필요)
res = ++a, ++b; //res는 ++a이고 b가1증가
res = (++a, ++b); //res는 ++b이고 a가1증가
- 조건 연산자: 유일한 삼항 연산자 ? 와 : 로 표현
첫째 피연산자가 참이면 두번째 피연산자가 결과값, 거짓이면 세번째 피연산자가 결과값 (if else로 번역함. 사실 컴파일러에겐 제어문임.)
(a > b) ? a : b;
(a > b) ? res=a : res=b; //대입식도 가능
- 비트 연산자: 비트 쉬트프는 곱셈 나눗셈 보다 빨라서 중요.(메모리에서 해결) 부호있을 때 >>사용 주의(음수일 때)
#include <stdio.h>
int main(void)
{
int a = 10; // 비트열 00000000 00000000 00000000 00001010
int b = 12; // 비트열 00000000 00000000 00000000 00001100
printf("a & b : %d\n", a & b);//논리곱 둘다 1이어야 1
printf("a ^ b : %d\n", a ^ b);//배타적 논리합: 둘이 달라야 1
printf("a | b : %d\n", a | b);//비트별 논리합: 하나라도 1이면 1
printf("~a : %d\n", ~a);//비트별 부정: 반전.
printf("a << 1 : %d\n", a << 1);//비트 이동 좌로 (2배)
printf("a >> 2 : %d\n", a >> 2);//비트 이동 우로 (/2)
return 0;
}
a & b : 8
a ^ b : 6
a | b : 14
~a : -11
a << 1 : 20
a >> 2 : 2
*비트 연산자도 복합대입 가능(~ 는 단항이라 제외) &=, ^=, |=, <<=, >>=
https://better-today.tistory.com/2
음수의 Bit Shift 연산시 주의사항
임베디드 환경에서는 연산속도가 중요하기 때문에 으로 나누는 연산의 경우 나눗셈보다는 right bit-shift 연산을 사용하게 된다. 하지만 음수의 경우에는 right bit-shift 연산을 사용할 때 주의할 점
better-today.tistory.com
연산자 우선 순위와 연산 방향
- 단항>이항>삼항
- 산술>(비트이동)>관계>논리
&주소 연산자 간접 참조 연산자*
.멤버접근 간접 멤버 접근 ->
C. 실전 예제
____1.
-
____2 .
-
____3.
-