일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- c++
- c#
- 문법
- 프로그래밍
- Kotlin
- 김성엽
- Tips강좌
- 지식나눔강좌
- Visual Studio
- Direct2D
- 알고리즘
- 리뷰
- 이지스퍼블리싱
- tipssoft
- Windows
- 함수
- 연산자
- c
- Javascript
- doit코틀린프로그래밍
- Win32
- Desktop
- 백준
- CS
- 티스토리
- VS ERROR
- Tips프로그래밍강좌
- 포인터
- 배열
- Programming
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
sizeof 연산자 본문
며칠 전 동기들이 작성한 코드를 보다가 잘못 작성한 코드가 다수 보이길래 이렇게 왔습니다. sizeof 연산자에 대한 문제였는데요. 오늘은, sizeof에 대한 연산자의 사용을 알아봅니다.
※ 이 포스트는 Visual Studio 2019 Community v16.1.2. 에서 테스트되었습니다.
기능
sizeof는 변수, 혹은 자료형, 상수의 크기를 반환하는 연산자입니다.
다음 코드를 실행하면 < 1 2 4 4 8 4 8 >이 나옵니다.
#include <stdio.h>
int main(void) {
char ch; short wch; int i; long l;
long long ll; float f; double dbl;
printf("%d ", sizeof(ch));
printf("%d ", sizeof(wch));
printf("%d ", sizeof(i));
printf("%d ", sizeof(l));
printf("%d ", sizeof(ll));
printf("%d ", sizeof(f));
printf("%d ", sizeof(dbl));
return 0;
}
여러분들이 생각했던 대로 나오나요? 여기에서는 설명하지 않았지만, 포인터의 경우 프로그램의 비트 수를 따라가는데요, 대부분 32비트 프로그래밍을 하니 sizeof로 크기를 확인해보면 4가 나올 겁니다.
그런데, 상수는 약간 다릅니다. 다음 소스만을 보고 무엇이 나올지 생각해보세요.
#include <stdio.h>
int main(void) {
printf("%d ", sizeof('a'));
printf("%d ", sizeof(1));
printf("%d ", sizeof(1LL));
printf("%d ", sizeof(12.0));
printf("%d ", sizeof(12.0f));
printf("%d ", sizeof(12.0L));
return 0;
}
일반적으로 문자 하나의 크기는 1바이트라고 합니다. 그러나 sizeof는 상수의 경우 상수의 기본 값으로 판단합니다. 위 코드는 실행하면 < 4 4 8 8 4 8 >이 결과로 나오게 됩니다. 이는 정수 자료형은 int, 실수 자료형은 double이 기본 타입이기 때문에 발생합니다. 그래서 3번째 1LL이나 5번째 12.0f는 상수 끝에 접미어를 붙여 각 상수의 자료형을 명확히 해주고 있습니다.
sizeof의 사용 예 [배열]
C언어를 조금 배우다 보면 포인터를 배우고, 포인터를 배우면 malloc() 함수와 같은 동적 할당 함수를 배우고 활용하게 됩니다. 이전까지는 동적 할당 함수를 배우지 않아 배열로 코드를 작성했죠. 우리가 동적 할당을 배우기 전에 작성하던 방식을 먼저 확인합니다.
#include <stdio.h>
#include <stdlib.h>
#define MAX_ARR_SIZE 10
int main(void) {
int arr[MAX_ARR_SIZE] = { 0, };
for (int i = 0; i < MAX_ARR_SIZE; ++i) {
arr[i] = i + 1;
}
for (int i = 0; i < MAX_ARR_SIZE; ++i) {
printf("%d ", arr[i]);
}
return 0;
}
길이 10인 배열에 1-10을 넣은 후 이를 그대로 출력하는 프로그램입니다. 전처리 상수를 선언했네요. 이 프로그램은 아래와 같이 sizeof를 이용할 수도 있습니다.
#include <stdio.h>
#include <stdlib.h>
#define MAX_ARR_SIZE 10
int main(void) {
int arr[MAX_ARR_SIZE] = { 0, };
for (int i = 0; i < sizeof(arr) / sizeof(int) ; ++i) {
arr[i] = i + 1;
}
for (int i = 0; i < sizeof(arr) / sizeof(int) ; ++i) {
printf("%d ", arr[i]);
}
return 0;
}
동적 할당을 배운 뒤부터는 malloc() 등의 함수를 통해 메모리 공간을 할당받아 배열처럼 사용합니다. sizeof연산자로 각 요소의 크기를 구한 뒤, 길이를 뒤에 상수로 작성하는 방식이 주를 이루며 권장되고 있습니다.
int *arr1 = (int *)malloc(sizeof(int) * 10); // 권장됩니다.
int *arr2 = (int *)malloc(40); // 권장하지않습니다.
이유는 길이의 변화가 왔을 때, 실수를 방지하기 위함입니다. 1번의 경우, 길이가 한눈에 10이라는 것을 알게 되지만, 2번의 경우 길이를 알기 위해서는 해당 크기로 나누어야 합니다. 작은 수는 어렵지 않겠지만, 큰 수의 경우에는 알아내는데 힘이 들겠죠. 둘째, 구조체의 경우 프로그램의 바이트 정렬로 인해 예상과 다른 크기가 나올 수 있습니다. 따라서 프로그램의 구조체 정렬에 맞게 크기를 구할 수 있는 sizeof 연산자를 사용하는 것이 올바르겠습니다.
읽을거리
참고
프로젝트에서 개발하는 내 프로그램이 32비트인지 64비트인지 확인하는 방법 (포스트)
구조체 정렬-포스트 내 1문단 (포스트)
# index
'DEV > C C++' 카테고리의 다른 글
C 스타일의 문자열 관리 방식 (0) | 2019.06.25 |
---|---|
sizeof 연산자의 오용 (0) | 2019.06.17 |
Snake with Windows API (0) | 2019.06.08 |
define VS typedef (0) | 2019.05.21 |
scanf_s 사용하기 (2) | 2019.04.28 |