티스토리 뷰
2021.03.01.월
레지스터 변수
✔ 예약어 register과 함께 변수를 선언하면, 변수는 메모리 공간 대신 CPU 내부의 저장공간인 레지스터를 사용한다.
✔ 사용 횟수가 많은 변수의 경우 레지스터에 할당하면 실행 시간을 줄일 수 있다. (예) 반복문
#include <stdio.h>
int main() {
register int i;
int sum;
//레지스터 변수를 사용한 반복문
sum = 0;
for (i = 1; i <= 10000; i++){
sum += i;
}
return 0;
}
✔ 레지스터의 사용 여부는 컴파일러가 결정한다.
✔ 레지스터는 중요한 저장 공간이므로, 당장 연산할 필요가 없는 데이터를 레지스터에 보관하면 활용성이 떨어진다.
✔ 그렇기 때문에 컴파일러는 레지스터와 메모리 중 더 적합한 저장 공간을 선택한다.
✔ 레지스터의 공간은 크지 않으므로 2개까지만 선언할 수 있다.
✔ 레지스터 변수는 잠시 동안만 CPU 내부의 저장 공간을 빌릴 수 있다.
✔ 즉, 프로그램이 종료될 때까지 계속 공간을 확보할 수 없기 때문에 전역 변수로는 사용할 수 없다.
#include <stdio.h>
register int i; //오류 발생
int main() {
register int num = 10;
printf("%p", &num);
return 0;
}
✔ 레지스터 변수는 CPU 내부 공간인 레지스터를 사용하기 때문에 별도의 메모리 공간을 할당받지 않는다.
✔ 그렇기 때문에 메모리 공간 주소를 구하는 주소 연산자 &를 사용할 수 없다.
✔ 일부 컴파일러는 레지스터 변수를 auto 변수로 변환해서 해석해 주소연산자 &를 사용할 수 있다.
#include <stdio.h>
int main() {
register int num = 10;
printf("%p", &num); //오류 발생
return 0;
}
✔ 레지스터는 CPU 내부에 있어서 데이터 처리 속도가 매우 빠르다.
✔ 그래서 <time.h> 헤더 파일에 포함된 clock() 함수를 사용해 실행 시간을 확인해 보았다.
✔ 실행할 때마다 조금씩 달라지기는 했지만, 결과적으로 레지스터 변수가 더 빠르다는 것을 확인할 수 있었다.
#include <stdio.h>
#include <time.h>
int main() {
//시간 측정에 필요한 변수 선언
clock_t start1, end1, start2, end2;
double result1, result2;
//레지스터 변수와 지역 변수 선언
register int i;
int j;
int sum;
start1 = clock(); //시간 측정 시작
sum=0;
//레지스터 변수를 사용한 반복문
for (i = 1; i <= 10000; i++){
sum += i;
}
end1= clock(); //시간 측정 끝
start2 = clock(); //시간 측정 시작
sum=0;
//일반 지역 변수를 사용한 반복문
for (j = 1; j <= 10000; j++){
sum += j;
}
end2= clock(); //시간 측정 끝
//끝 시간 - 시작 시간 = 총 실행시간
result1 = (double)(end1 - start1);
result2 = (double)(end2 - start2);
//초 단위로 나오게하기위해 CLOCKS_PER_SEC로 나누어줌
printf("레지스터 변수 사용 시, 실행 시간 : %f\n", result1/CLOCKS_PER_SEC);
printf("일반 지역 변수 사용 시, 실행 시간 : %f\n", result2/CLOCKS_PER_SEC);
return 0;
}
값을 복사해서 전달하는 방법
✔ 함수를 호출하면서 인자를 전달하게 되면, 인자의 값이 복사되어 함수에 전달된다.
✔ 이러한 방식을 사용하면 실제 변수 값은 변하지 않는다.
✔ 원본 데이터를 보존할 수 있으므로 안정적이다.
#include <stdio.h>
void swap(int a, int b);
int main(void){
int a=10, b=20;
swap(a,b);
printf("a = %d, b = %d", a,b);
//a = 10, b = 20;
return 0;
}
void swap(int a, int b){
int temp=a;
a = b;
b = temp;
}
주소를 전달하는 방법
✔ 함수를 호출할 때 변수의 주소를 넘기면 호출한 함수에 있는 변수의 값에 접근해 수정이 가능하다.
✔ 다만 포인터 연산으로 값을 처리해야 하므로 조금 불편하다.
✔ 값을 복사해 사용하는 것이 아닌 값의 주소를 가져오는 것이기 때문에 같은 값을 공유한다.
✔ 원본 데이터에 접근할 수 있지만, 절대 바꾸면 안 되는 데이터를 다루는 경우 문제가 생길 수 있으니 주의하자.
#include <stdio.h>
void swap(int *a, int *b);
int main(void){
int a=10, b=20;
swap(&a,&b);
printf("a = %d, b = %d", a,b);
//a = 20, b = 10;
return 0;
}
void swap(int *a, int *b){
int temp=*a;
*a = *b;
*b = temp;
}
주소를 반환하는 함수
✔ 함수가 종료된 후에도 변수의 저장 공간이 계속 유지된다면, 주소를 반환함으로 해당 변수에 접근할 수 있다
✔ 만약 함수가 종료되어도 할당받은 공간이 해제되지 않는다면 주소를 알고 있을 때 계속 사용할 수 있다.
✔ 즉, 정적 지역 변수(static)이나 전역 변수를 사용하면 해당 변수의 주소를 알고 있는 경우 계속 접근할 수 있다.
#include <stdio.h>
int* sum(int a, int b);
int main(void){
int a=10, b=20;
printf("a + b = %d", *sum(a,b));
return 0;
}
int* sum(int a, int b){
static int sum;
sum = a+b;
return ∑
}
[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩 도장 / 위키백과
'BackEnd > C' 카테고리의 다른 글
[19일차] 2. 3차원 배열/포인터 배열 (0) | 2021.03.02 |
---|---|
[19일차] 1. 2차원 배열 (0) | 2021.03.02 |
[18일차] 1. 지역 변수와 전역 변수 (0) | 2021.03.01 |
[15일차] 문자열 관련 함수의 원형 (0) | 2021.02.25 |
[13-14일차] 문자/문자열 (0) | 2021.02.25 |