c언어 변수의 생존 시간, 변수 할당의 종류, 저장 유형 지정자 알아보기
네 안녕하세요, 이번 포스팅에서는 변수들의 생존 시간에 대하여 알아보겠습니다.
생존 시간을 알고 있으면 나중에 우리가 코드를 작성을 할 때 변수 지정 시에 좀 더 유동적으로 할 수가 있기 때문에 알아두셔야 합니다.
그럼 지금부터 시작해보도록 하겠습니다.
1. 변수의 할당
변수를 분류하는 기준 중에 생존 시간을 기준으로 하여 우리가 할당을 한다면, 크게 두 가지로 나눌 수 있습니다.
- 정적 할당 : 프로그램이 실행이 되는 동안에는 계속 변수에 저장 공간이 할당이 되어있음.
- 자동 할당 : 블록이 시작됨과 동시에 변수에 저장 공간이 할당되고, 블록 종료 시에 저장 공간이 회수가 됨.
1 - 1. 변수가 선언되는 위치
변수가 지정이 되는 위치에 따라서도 할당이 되는 방법이 갈립니다.
- 전역 변수 : 전역 변수는 정적 할당이 됩니다.
- 지역 변수 : 지역 변수는 기본적으로 자동 할당이 되지만, 지역 변수 앞에 '저장 유형 지정자'를 붙이면 정적 할당을 할 수도 있습니다.
2. 저장 유형 지정자
저장 유형 지정자는 변수 선언 시에 변수 앞에 저장 유형을 지정하는 수식어를 붙일 수 있습니다.
저장 유형 지정자에는 auto 지정자, static 지정자, register 지정자, extern 지정자, volatile 지정자 등이 있습니다.
그리고 이 중에서 보통 많이 쓰이는 지정자는 static, volatile, extern 지정자입니다.
이 중에서 extern은 나중에 제가 포스팅을 할 '연결'에 대하여 이야기를 할 때 쓰일 지정자이기 때문에, 다음 포스팅에서 제가 말씀을 드리도록 하겠습니다.
2 - 1. auto 지정자
auto 지정자는 자동 할당을 할 때 쓰는 지정자입니다.
그리고 함수나 블록 내에서는 사용되는 변수가 지역 변수이기 때문에 자동 할당이 되기에 굳이 사용을 하지 않으며,
전역 변수 역시도 프로그램이 돌아가는 동안에는 계속 살아있어야 하기 때문에 기본 할당 설정이 정적 할당인 것이기 때문에 쓰지 않습니다.
사용 방법은 이렇습니다.
auto int n;
2 - 2. static 지정자
static 지정자는 정적 변수를 할당할 때 쓰는 지정자입니다.
static 지정자는 지역 변수를 정적 할당을 해야 할 때, 다시 말하면 함수가 종료가 되어도 자동으로 제거가 되면 안 되는 상황이 있을 때 지정을 해줍니다,
이렇게 씁니다.
static int cnt = 0;
이런 식으로 변수의 자료형 앞에다가 선언을 같이 해줍니다,
그럼 제가 하나의 예제 코드를 예시로 들어서 한 번 이야기를 해보도록 하겠습니다.
#include <stdio.h>
int main()
{
sub();
sub();
sub();
sub();
return 0;
}
void sub()
{
static int cnt = 0;
int cnt2 = 0;
printf("cnt = %d\t", cnt);
printf("cnt2 = %d\n", cnt2);
cnt++;
cnt2++;
}
이렇게 각각의 변수가 누적이 될 수 있도록 하는 코드를 한 번 작성을 해봤습니다,
그러면 한 번 결과가 어떻게 나오는지 한 번 보도록 하겠습니다.
cnt = 0 cnt2 = 0
cnt = 1 cnt2 = 0
cnt = 2 cnt2 = 0
cnt = 3 cnt2 = 0
여기서 static 지정자로 선언을 한 cnt는 증가를 했고,
일반 변수로 지정을 한 cnt2는 초기값 그대로 값이 나온 것을 볼 수가 있습니다.
여기에서 정적 할당과 자동 할당이 차이가 나는 것입니다,
일단 정적 할당이 되면 함수가 종료가 된 후에도 값이 유지가 됩니다.
그래서 첫 결괏값은 당연히 컴퓨터는 0으로 세기 때문에 둘 다 0이 나오고,
두 번째 함수가 실행이 될 때부터 결과는 달라집니다.
일반 변수의 경우에는 for 루프나 while 루프를 돌려서 누적을 시켜야만 누적이 되지만,
static 지정자의 경우는 함수가 종료가 되어도 값이 계속 살아있기 때문에 누적이 됩니다.
그래서 두 번째 결과는 일반 변수의 경우는 종료가 되었다 다시 실행되었기 때문에 0이 나왔고,
static 지정자는 함수가 종료가 되었어도 값이 살아있기 때문에 1이 되었습니다.
그리고 이렇게 계속 값이 살아있다는 특성 때문에 static 지정자의 값은 초기화를 한 번만 실행을 할 수 있습니다.
또한, static 지정자로 선언된 변수 역시 개발자가 초기값을 선언하지 않으면 자동으로 0으로 선언이 됩니다.
2 - 3. register 지정자
register 지정자는 데이터를 읽고 쓰는 속도를 더 빠르게 하기 위해서 쓰는 지정자입니다.
종종 쓰기는 하지만, c언어 자체가 컴파일 언어이고, 가장 연산 처리 속도가 빠른 언어들 중 하나이기 때문에 잘 쓰지는 않습니다.
그래서 특징만 간단히 이야기를 하자면, 당연히 지역 변수에만 선언이 가능하며,
변수를 보통 메모리에 저장을 하지만,
register 지정자는 cpu에서 사용하는 레지스터에 저장을 하는 것이라, 사실상 cpu의 일부분을 쓰는 것입니다.
그렇기에 연산 시에 cpu를 쓰게 되어 연산 처리 속도가 매우 빠릅니다.
그래서 큰 범위의 수나 합성 함수 등을 미적분하여 계산을 한다던지 할 때 매우 유용해 쓸 수가 있습니다.
하지만 요즘 컴파일러는 적절한 상황에 맞춰서 수가 너무 크면 알아서 cpu로 연산을 하도록 최적화가 되어있기에,
굳이 register 지정자를 쓰지 않고도 쓸 수 있습니다.
사용법은 이러합니다.
register int n;
for(n = 0; n < 1000; n++)
{
sum += n;
}
이런 식의 누적 연산을 좀 크게 할 때 종종 씁니다.
2 - 4. volatile 지정자
volatile 지정자는 컴파일러가 volatile 변수와 관련이 되어있는 문장을 최적화하지 말라고 할 때 쓰는 지정자입니다.
이 지정자는 하드웨어가 수시로 값을 변경하는 경우에 사용이 됩니다.
그래서 그냥 소프트웨어만 만지는 프런트엔드 개발자, 백엔드 개발자, 서버 개발자는 사실 거의 쓰지 않습니다.
하지만 하드웨어, 다시 말해서 컴퓨터 부품들, 로봇 등을 다루는 사람들이라면 정말 자주 쓸 수 있습니다.
그 이유는 로봇들의 경우는 사실 메카닉이 설계한 것만 해서 상관은 없지만,
요즘은 인공지능이 탑재된 휴머노이드나 동물 로봇 등을 만들기도 하는데,
그럴 경우에는 연산장치에 저장되는 값이 몇 가지가 정해져 있다 할 지라도,
그 값이 수시로 바뀔 수가 있겠죠?
그리고 요즘은 하드웨어 개발자가 소프트웨어 개발도 같이 합니다.
그 이유는 하드웨어만 하는 사람과 소프트웨어만 하는 사람들이 서로가 코드가 안 맞아서 싸우는 경우가 정말 많기 때문입니다.
그래서 혼자 다 하기 때문에 이런 것을 알아야 합니다.
이런 식으로 쓸 수 있습니다.
volatile int io_port;
void wait()
{
io_port = 0;
while (io_port != 255)
{
문장;
}
}
이런 식으로 쓰일 수 있습니다.
그리고 io_port는 하드웨어 프로그래밍을 하는 개발자들이 많이 쓰는 선언 변수 이기도 합니다.
port는 전원을 연결시킬 때 쓰는 문과 같습니다.
그래서 이 말을 정말 많이 씁니다.
여기까지 변수의 생존 시간, 변수 할당의 종류, 저장 유형 지정자에 대하여 알아보았는데요,
다음 포스팅에서는 연결에 대하여 알아보도록 하겠습니다.
긴 글 읽어주신 독자분들께 진심으로 감사드립니다 ~
'c언어' 카테고리의 다른 글
c언어 적절한 저장 유형 사용방법 알아보기(static, register, extern) (0) | 2022.12.06 |
---|---|
c언어 연결 알아보기(외부 연결, 내부 연결, extern 지정자, static 지정자) (0) | 2022.12.06 |
c언어 전역 변수 알아보기 (0) | 2022.12.06 |
c언어 지역 변수 알아보기 (0) | 2022.12.06 |
c언어 사용자 정의 함수 이용하여 문제 풀기(생일 축하 메시지 보내기, 정수 입력 함수(get_integer()) 사용하기, 정수의 합 계산(add()) 함수 사용하기, 팩토리얼 계산하기, 온도 변환하기(화씨 -> 섭.. (0) | 2022.12.06 |
댓글