변수 (Variable)
변수는 어떤 관계나 범위에서 여러 값으로 변할 수 있는 수 입니다.
f(x) = x + 1 수식에서,
- x 가 변수 입니다.
- x 는 어떠한 값으로든 변할 수 있다는 사실을 의미합니다.
변수의 필요성
Computer 는 무엇인가를 계산하기 위한 장치이며, 프로그램은 어떠한 결과를 산출하기 위해 작성합니다.
산출물은 단순한 수치 값이 아닌 게임이나 영상물이 될 수도 있습니다.
변수가 없어도 우리는 프로그램을 작성할 수 있습니다.
1 + 1을 계산하는 프로그램을 만들었다고 하면, 이 프로그램은 항상 결과값 2를 도출합니다.
하지만 1 + 2를 계산할 필요가 생겼다면, 다시 새롭게 프로그램을 작성 해야만 합니다.
변수의 존재는 프로그램에 유연성을 가져다 줍니다. 입력되는 값에 의해 다른 결과를 도출해 낼 수 있습니다.
변수는 중간 데이터들을 보관하는 장소의 역할도 가지고 있습니다.
사람은 복잡한 식을 계산할 때, 종이를 펼처두고 그 중간 결과를 적어가며 계산을 할 수 있습니다. 이와 마찬가지로, CPU 가 기억할 수 있는 값들은 매우 한정적이며, 비싼 자원입니다. 따라서, 복잡한 프로그램일수록 메모리 상에 데이터들을 기록해 둘 필요가 있으며, 그 데이터를 기록해 둘 변수들의 필요성은 커진다고 할 수 있습니다.
변수의 선언법
#include <stdio.h>
int main(int argc, char** argv)
{
int variable;
printf("Hello World\n");
return 0;
}
기존에 작성했던 Hello World 에 'int variable;' 한줄을 추가했습니다.
키워드 | 이름 | 구두점 |
---|---|---|
int | variable | ; |
자료형 | 새 이름 | 세미콜론 |
컴파일러는 해당 자료형의 크기만큼 비어있는 공간을 만들고, 지정된 이름을 붙여줍니다.
위의 'int Variable;' 은 int 가 자료형, Variable 이 이름, 그리고 ;이 마침표에 해당합니다.
명칭은 다른 이름이나 키워드와 중복되지 않는다면 어떤 것을 사용해도 괜찮습니다.
프로그램 작성 초반에는 단순한 a, b, c등을 쓸 지도 모르지만, 변수의 쓰임새가 표현되는 이름을 짓는 것이 좋습니다.
예) 간단한 변수명
#include <stdio.h>
int main(int argc,char** argv)
{
int a = 1;
int b = 2;
printf("%d\n",a+b);
return 0;
}
예) 의미가 포함된 변수명
#include <stdio.h>
int main(int argc,char** argv)
{
int leftOperand = 1;
int rightOperand = 2;
printf("%d\n",leftOperand + rightOperand);
return 0;
}
나중에 다시 프로그램 코드를 살펴 볼 때, 이러한 작명은 큰 도움이 됩니다.
C 에서 변수의 선언은 함수 내에서 가장 처음에 등장해야 합니다.
- C++ 에서는 제약을 받지 않습니다. - 사용하기 전에만 선언하면 됩니다.
변수의 수명
#include <stdio.h>
int main(int argc,char** argv)
{
int Variable1 = 10;
{
int Variable2 = 20;
printf("%d %d\n",Variable1,Variable2);
}
printf("%d",Variable1);
// 다음 코드를 넣으면 에러가 발생합니다.
//printf("%d %d\n",Variable1,Variable2);
}
// 로 시작하는 코드는 주석문(Comment) 이라고 하며, 컴파일러는 해당 줄을 무시합니다. 에러가 발생하는 코드를 적어두기 위해 사용하였습니다.
Variable1 과 Variable2 변수가 선언되어 있습니다.
Variable1 은 main 함수의 {} 안에, Variable2 는 그 안에서도 {}로 한번 더 감싸고 있습니다.
C / C++ 에서 가장 기본적으로 범위 (Scope) 를 구분짓는 방법은 {}이며, 변수의 수명은 대부분 { } 에 의해 결정됩니다.
main 함수의 {} 범위안에 존재하는 변수 Variable1 은 main 함수가 소멸할때까지 그 수명이 유지됩니다.
그리고 main 함수 내에서 다시 { } 로 묶인 범위가 있습니다. 이 안에서는 Variable2 가 선언되어 있습니다.
이 범위 내에서는 자신의 상위 범위인 main 함수 범위 및 자기 자신범위 내에 있는 변수를 사용할 수 있습니다.
즉, 여기서는 Variable1과 Variable2를 전부 사용할 수 있습니다.
그리고 범위가 끝나면서 Variable2는 그 수명이 다 하게 됩니다. 다시 main 함수 범위로 돌아갑니다.
여기서는 이미 범위가 끝나버려 수명이 다한 Variable2 를 사용할 수 없습니다.
이렇게 단기적, 지역적으로 사용 되고 수명이 한정적인 변수를 "지역 변수" 라고 합니다.
Variable1 와 Variable2 는 모두 지역변수입니다.
#include <stdio.h>
int GlobalVariable;
int main(int argc,char** argv)
{
GlobalVariable = 20;
printf("%d",GlobalVariable);
}
위의 코드는 변수를 함수의 바깥에 선언해 본 모습이며, 어떠한 {} 로도 둘러싸여 있지 않습니다.
이를 "전역 변수"라 하며, 최상위 범위에 속하게 됩니다.
다시 말해, 이러한 변수는 같은 코드내의 모든 범위내에서 사용할 수 있습니다.
또한 프로그램이 종료될 때까지 수명이 유지됩니다. 그러나 이러한 방법은 되도록 사용하지 않는 것이 좋습니다.
이러한 전역변수들은 당장은 편리할 지 모르나, 코드의 유지보수를 어렵게 만듭니다.
지역 변수는 해당 지역내에서만 사용되므로, 사용 범위를 파악하기 쉽지만
전역 변수는 어디서든 사용할 수 있으므로 어디서 이 변수를 참조하고 있는지 파악하기 어렵습니다.
변수의 선언에 덧 붙일수 있는 키워드 - static
#include <stdio.h>
void Prints()
{
static int StaticVariable = 0;
StaticVariable = StaticVariable + 2;
printf("%d\n",StaticVariable);
}
int main(int argc,char** argv)
{
Prints();
Prints();
}
변수의 선언문법에 static 키워드를 덧 붙일 수 있습니다. 이 키워드는 해당하는 변수를 "정적 변수"로 만들어 줍니다.
- 선언문의 앞에 붙습니다
정적 변수의 수명은 전역 변수 처럼 프로그램이 종료될 때 까지 유지됩니다만,
사용할 수 있는 범위는 이 변수를 선언한 범위와 그 이하 범위들로 제한됩니다.
Print 함수를 두 번 호출했으며, 실행 시 값이 +2 되며 유지 되는 것을 확인할 수 있습니다.
변수의 선언에 덧 붙일수 있는 키워드 - register
#include <stdio.h>
int main(int argc,char** argv)
{
register int RegVar = 30;
printf("%d",RegVar);
}
변수의 선언문법에 register 키워드를 덧 붙일 수 있습니다. (선언문의 앞에 붙습니다)
이 키워드는 해당하는 변수를 "레지스터 변수"로 만들어 줍니다.
레지스터는 CPU 에 존재하고 있는 매우 빠르면서도 한정적인 메모리 공간입니다. 이러한 레지스터는 CPU 내에 상당한 크기가 포함되어 있지만, 우리가 직접적으로 프로그램으로 다룰 수 있는 범용 레지스터는 몇 개 되지 않습니다.
레지스터 변수는 명시적으로 컴파일러에게 레지스터를 사용하도록 지시하는 방법입니다.
자주 사용되는 변수를 레지스터에 할당되도록 지정하면 성능을 높일 수 있습니다.
그러나 컴파일러는 최적화 여부, 레지스터를 할당할 수 있는지에 대해서 판단한 뒤 이를 무시하고 메모리에 할당할 수도 있습니다.
일반적인 경우, register 키워드를 쓰지 않고 컴파일러의 최적화 작업을 통해 적당한 레지스터에 배치되도록 놔 두는게 바람직합니다.
- double 형은 64bit 으로, 32bit 레지스터에 할당할 수는 없습니다.
Auto (C++11)
#include <stdio.h>
int main(int argc,char** argv)
{
auto AutoVar1 = 30;
printf("%d %f",AutoVar1,AutoVar2);
}
여러분이 C++11을 지원하는 컴파일러를 사용하시고 계시다면 변수의 선언시에 자료형 대신 auto 키워드를 사용할 수 있습니다.
auto 키워드는 초기화 값 (위의 경우는 30)에 따라서 컴파일러가 자료형을 유추합니다.
위의 경우는 아마도 int 가 추정되겠지만, 어디까지나 '유추' 이므로 우리가 원하는 자료형이 아닐수도 있습니다.
30은 double 이나 float 으로도 표현할 수 있지만 int 가 추정되는 이유는 가장 합당하기 때문일 것입니다.
auto 는 런타임(프로그램 실행 중)상에서 결정되는 것이 아니라는 점에 주의하셔야 합니다. 어떤 프로그래밍 언어들은 자료형을 따로 구분하지 않거나, 런타임 중에 명칭에 대한 자료형을 변경하는것이 허용됩니다.
C/C++에서 auto 키워드는 컴파일시에 특정한 자료형으로 치환됩니다. 따라서 위 예제 코드 처럼 선언 후에 AutoVar1 = 0.1f를 대입하면 int 형에 실수형을 대입하는 상황이 되므로 문법적 에러 메세지가 발생합니다.