티스토리 뷰
형한정어(type qualifier)는 변수에 적용되는 문법으로서 <컴파일러의 최적화>와 매우 밀접하게 관련되어 있다.
15.1.1 const
형 한정어 const는 변수를 '상수화'하는 역할을 한다.
즉, 어떤 메모리를 '읽기 전용' 메모리로 만들어주는 기능을 제공한다.
변수가 선언 및 정의될 때부터 상수화를 해야하는 이유?
-> 유지보수를 쉽게하기 위함. / 줄어든 변수의 수만큼 번역도 유리하며 성능향상을 꾀하기 위함.
<심볼릭 함수(symbolic constant)>
특정 숫자와 변수의 이름을 조합하여 좀 더 의미가 명확해 보이는 상수
15.1.2 상수형 포인터
#include<stdio.h>
int main()
{
char szBuffer[32] = {"I am a boy."};
//가리키는 대상을 상수화한 포인터 변수 선언 및 정의
const char *pszBuffer = szBuffer;
//문자 배열의 내용은 변경할 수 있다.
szBuffer[0] = 'i';
//포인터가 가리키는 대상을 간접지정할 수는 있지만 l-value로
//사용할 수는 없다!
*pszBuffer = 'i';
return 0;
}
const가 수식하는 대상은 pszBuffer라는 포인터 자체가 아니라 포인터가 가리키는 대상입니다.
코드가 오류인 이유는 상수화된 대상에 쓰기를 시도했기 때문이다.
Call by reference 형식인 경우 피호출자 함수의 연산으로 인해 호출자의 메모리가 변경될 가능성이 없도록 문법적으로 강제화하는 노력이 필요할 수 있다.
#include<stdio.h>
//매개변수가 상수형 포인터이다. 따라서 함수에서 포인터가 가리키는
//대상 메모리에 쓰기를 시도할 수 없다.
void PrintString(const char *pszParam)
{
puts(pszParam);
}
int main()
{
char szBuffer[32] = {"I am a boy."};
//PrintString() 함수를 호출하더라도 szBuffer가 변경될 가능성은 없다.
PrintString(szBuffer);
PrintString("You are a girl.");
return 0;
}
지금까지는 포인터 변수가 '가리키는 대상'이 상수화되는 것을 봐왔다.
'포인터 변수 그 자체'를 상수화할 수 도 있다.
즉, 포인터가 가리키는 메모리는 수정할 수 있으나 포인터가 변해서 '다른 대상을 가리킬 수 없는 상태'가 된다.
#include<stdio.h>
int main()
{
int nData = 10;
//포인터가 가리키는 대상을 상수화한다.
const int *pnData = &nData;
//포인터 변수 자체를 상수화한다.
int * const pnNewData = &nData;
//아래 두 구문은 모두 에러
*pnData = 20;
pnNewData = NULL;
return 0;
}
15.1.3 심볼릭 상수를 만드는 또 다른 방법
1. 형한정어 const를 사용하는 방법
2. '#define 전처리기'를 이용하여 상수를 정의하는 방법
15.1.4 volatile
형한정어 volatile을 적용해 변수를 선언하면 변수와 관련된 모든 연산에 대해 컴파일러가 '최적화' 규칙을 적용하지 않는다.
15.2 extern 외부변수 선언
변수도 외부변수 선언과 정의로 구분할 수 있다.
//VariableExtern01.c file
#include<stdio.h>
//(다른 외부 파일에 정의된)함수의 원형 선언
void InitCounter(int nData);
void IncreaseCounter();
//(다른 외부 파일에 정의된)전역변수 선언(정의가 아님에 주의!)
extern int g_nCounter;
void main()
{
InitCounter(10);
printf("%d\n", g_nCounter);
IncreaseCounter();
printf("%d\n", g_nCounter);
}
//test.c file
#include<stdio.h>
int g_nCounter = 0;
void InitCounter(int nData)
{
g_nCounter = nData;
}
void IncreaseCounter()
{
g_nCounter++;
}
단, 오로지 한 파일에만 main()함수가 존재해야 한다.
또한 절대 초깃값을 명시하면 안된다.
15.3 형 재선언
#include<stdio.h>
//unsigned int형을 'UINT'형으로 다시 선언
typedef unsigned int UINT;
int main(void)
{
//UINT는 unsigned int 형식과 같다.
UINT uData = 10;
printf("%u\n", uData);
return 0;
}
#include<stdio.h>
//포인터 변수를 형 재선언 했다.
typedef const char* LPSTR;
int main(void)
{
//"*" 기호가 없지만 pszData는 포인터 변수이다!
LPSTR pszData = NULL;
pszData = "Helloworld";
printf("%s\n", pszData);
return 0;
}
15.4 열거형 상수
여러 개의 심볼릭 상수를 한꺼번에 정의하고 구조체 처럼 새로운 사용자 정의 자료형으로 활용하는 것도 가능하다
#include<stdio.h>
//열거형 상수 ACTION 선언 및 정의
//MOVE는 0(int), JUNP는 1, ATTACK은 2
enum ACTION {MOVE, JUMP, ATTACK};
//형 재선언을 포함하는 열거형 상수 선언 및 정의
//RED는 100, GREEN은 101, BLUE는 102
typedef enum COLOR { RED = 100, GREEN, BLUE } COLOR;
int main(void)
{
enum ACTION act = MOVE;
COLOR color = GREEN;
//열거형 상수는 int형식 상수이다.
printf("ACTION : %d, COLOR : %d\n", act, color);
return 0;
}
'언어 > C' 카테고리의 다른 글
함수 호출 규칙 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.31 |
---|---|
매크로 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.31 |
파일 시스템 기본 이론 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.23 |
비트필드, 공용체 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.04 |
구조체 - 독하게 시작하는 C프로그래밍 (0) | 2019.10.04 |
- Total
- Today
- Yesterday
- Algorithm
- timecomplexity
- 형승격
- 공간복잡도
- 종류
- 직접 지정
- 프로그래밍
- 비트필드
- 구조체
- 공부
- 재귀함수
- 자료구조
- 배열
- 간접 지정
- 알고리즘
- codeit
- 시간복잡도
- inflearn
- 파이썬
- call by value
- 포인터
- 공용체
- 회전리스트
- 1차원 배열
- 강의
- 3차원 배열
- C
- 2차원 배열
- call by reference
- 다차원 배열
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |