1.리터럴 상수
2.심볼릭 상수
2가지 가 존재한다.
리터럴 상수란 'abc' 프로그래머가 직접 값을 하드코딩으로 값을 입력하는 것
심볼릭 상수란 const int num = 10 처럼 변수의 값을 상수화 시킨다.
형한정어(const)
변수에 적용되는 문법으로서 컴파일러 최적화와 매우 밀접하게 관련된다.
변수를 상수화하는 역할을 한다.
즉 메모리를 읽기 전용 메모리로 만드는 기능을 담당한다.
const는 중요한 정보가 들어 있는 메모리를 보호하기 위한 것
const는 변수를 선언 및 정의 할때 상수화 한다. 이유는 유지보수를 쉽게 하기 위해서 이다.
그리고 컴파일러의 입장에서는 줄어든 변수 만큼 번역도 유리하며 성능이 향상된다.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main() {
int Input = 0;
const int score = 70; // 심볼릭 상수(symbolic constant)
printf("점수를 입력하세요");
scanf_s("%d", &Input);
// score = 60;
if (Input >= score) puts("합격입니다.");
else puts("불합격입니다.");
return 0;
}
int main() {
// l-value : 변수 , r-value : 값
// 매개 변수가 상수형 포인터 이다. 따라서 함수에서 포인터가 가리키는
// 대상 메모리에 쓰기 시도 할수 없다.
char szBuffer[32] = { "I am a boy" };
int nData = 10;
const int* pnData = &nData; // 포인터가 가리키는 대상을 상수화
int* const pnNewData = &nData; // 포인터변수를 상수화
// r-value
// *pnData = 20;
// pnNewData = &nData+3;
return 0;
}
형한정어 volatile을 적용하면 변수와 관련된 모든 연산에 대해 컴파일러가 최적화 규칙을 적용하지 않는다.
(const와는 정반대 역할 - const는 컴파일러 최적화)
*주로 엠베디드 프로그래밍에서 활용
#include <stdio.h>
int main(void)
{
int nData = 10;
int i = 0;
for (int i = 0; i < 10; ++i)
{
nData = 10;
}
printf("%d\n", nData);
return 0;
}
// 어셈블리어 - debug mode
int nData = 10;
005D1875 mov dword ptr [nData],0Ah
int i = 0;
005D187C mov dword ptr [i],0
for (int i = 0; i < 10; ++i)
005D1883 mov dword ptr [ebp-20h],0
005D188A jmp __$EncStackInitStart+39h (05D1895h)
005D188C mov eax,dword ptr [ebp-20h]
005D188F add eax,1
005D1892 mov dword ptr [ebp-20h],eax
005D1895 cmp dword ptr [ebp-20h],0Ah
005D1899 jge __$EncStackInitStart+48h (05D18A4h)
{
nData = 10;
005D189B mov dword ptr [nData],0Ah
}
005D18A2 jmp __$EncStackInitStart+30h (05D188Ch)
printf("%d\n", nData);
005D18A4 mov eax,dword ptr [nData]
005D18A7 push eax
005D18A8 push offset string "%d\n" (05D7B30h)
005D18AD call _printf (05D10D2h)
005D18B2 add esp,8
return 0;
// Release 모드 최적화
int nData = 10;
int i = 0;
for (int i = 0; i < 10; ++i)
{
nData = 10;
}
printf("%d\n", nData);
00ED1040 push 0Ah
00ED1042 push offset string "%d\n" (0ED2100h)
00ED1047 call printf (0ED1010h)
00ED104C add esp,8
return 0;
00ED104F xor eax,eax
}
int main(void)
{
00F91040 push ebp
00F91041 mov ebp,esp
00F91043 push ecx
volatile int nData = 10;
00F91044 mov dword ptr [ebp-4],0Ah
int i = 0;
for (int i = 0; i < 10; ++i)
00F9104B mov eax,0Ah
{
nData = 10;
00F91050 mov dword ptr [nData],0Ah
00F91057 sub eax,1
00F9105A jne main+10h (0F91050h)
}
printf("%d\n", nData);
00F9105C mov eax,dword ptr [nData]
00F9105F push eax
00F91060 push offset string "%d\n" (0F92100h)
00F91065 call printf (0F91010h)
00F9106A add esp,8
return 0;
00F9106D xor eax,eax
}