sizeof 연산자를 활용한 메모리 크기 계산
sizeof는 피연산자의 바이트 단위 저장 크기를 반환하는 단항 연산자입니다. 반환 타입은 size_t로, 이는 부호 없는 정수형입니다. 출력 시 %zu 서식 지정자를 사용합니다.
참고로 size_t의 실제 크기는 시스템 아키텍처에 따라 달라집니다. 32비트 환경에서는 unsigned int(4바이트)로 정의되며, 64비트 환경에서는 unsigned long(8바이트)로 정의됩니다.
활용 방식
#include <stdio.h>
int main() {
// 타입과 함께 사용
printf("double 크기: %zu\n", sizeof(double));
// 변수와 함께 사용 (괄호 생략 가능)
float pi = 3.14f;
printf("pi 변수 크기: %zu\n", sizeof pi);
// 리터럴 상수와 함께 사용
printf("문자 리터럴 크기: %zu\n", sizeof 'A');
// 결과를 변수에 저장
size_t int_size = sizeof(int);
printf("정수형 크기: %zu\n", int_size);
return 0;
}
변수나 상수에 적용할 때는 괄호를 생략할 수 있으나, 타입 키워드와 함께 사용할 때는 반드시 괄호가 필요합니다.
형 변환 메커니즘
묵시적 형 변환
컴파일러가 자동으로 수행하는 형 변환으로, 주로 다음 상황에서 발생합니다:
- 연산 과정: 서로 다른 타입이 연산될 때 값의 손실을 방지하기 위해 범위가 넓은 타입으로 변환됩니다.
char와short는 연산 전int로 승격됩니다. - 대입 과정: 우변의 값이 좌변 변수의 타입에 맞춰 변환됩니다. 이 과정에서 큰 타입에서 작은 타입으로 변환되면 데이터 손실이 발생할 수 있습니다.
unsigned char uc = 230;
printf("부호 있는 문자로: %d\n", (signed char)uc); // -26 출력
short s = 5000;
signed char sc = s;
printf("축소 변환 결과: %d\n", sc); // 하위 8비트만 저장
명시적 형 변환 (캐스팅)
개발자가 의도적으로 형 변환을 지정하는 방식입니다. 일반적인 산술 변환 규칙을 우회하거나, 포인터 타입을 변환할 때 활용됩니다.
int total = 7;
int count = 2;
double avg = (double)total / count; // 3.5가 아닌 3을 방지
연산자 분류 및 특성
산술 연산자
| 연산자 | 설명 | 특이사항 |
|---|---|---|
| +, - | 단항 부호 연산자 | 부작용 없음 |
| +, -, *, / | 이항 사칙연산 | 정수 나눗셈은 소수점 버림 |
| % | 나머지 연산 | 피연산자 모두 정수형 필요 |
| ++, -- | 증 연산자 | 전위/후위에 따라 표현식 값 상이 |
증감 연산자의 위치에 따른 동작 차이:
int x = 5, y = 5;
int a = ++x; // x를 6으로 증가시킨 후 6을 a에 대입
int b = y++; // b에 5를 대입한 후 y를 6으로 증가
// 동일 변수에 대한 다중 부작용은 미정의 동작
int r = (++x) + (x++); // 컴파일러별 결과 상이, 사용 금지
관계 연산자
비교 결과를 int 타입의 0(거짓) 또는 1(참)으로 반환합니다. 부동소수점 비교 시 주의가 필요하며, 부호 있는 값과 부호 없는 값 비교 시 암묵적 변환이 발생합니다.
논리 연산자
&&(논리곱): 첫 피연산자가 0이면 두 번째 평가 생략 (단축 평가)||(논리합): 첫 피연산자가 0이 아니면 두 번째 평가 생략!(논리부정): 0이면 1, 0이 아니면 0 반환
int p = 0, q = 10;
int result = p && (q = 20); // q = 20은 실행되지 않음
printf("q: %d\n", q); // 10 출력
비트 연산자
모든 비트 연산은 2의 보수 형태로 수행됩니다.
unsigned int flags = 0b10110011;
// 비트 마스킹
unsigned int masked = flags & 0x0F; // 하위 4비트 추출
// 비트 토글
flags ^= 0xFF; // 모든 비트 반전
// 시프트 연산
unsigned int shifted = flags << 3; // 2^3 배 증가 효과
unsigned int reduced = flags >> 2; // 2^2 로 나눈 효과 (정수)
시프트 연산 시 주의: 좌측 시프트는 값을 증가시키며, 우측 시프트는 부호 있는 타입의 경우 부호 비트가 복사될 수 있습니다(구현 정의).
컴파일러 경고 수준 설정
VS Code의 tasks.json에서 다음 플래그를 추가하여 잠재적 형 변환 문제를 조기에 발견할 수 있습니다:
"-Wall",
"-Wconversion",
"-Wextra",
"-Wshadow"