본문 바로가기
Tech/Coding

C언어 고급] 13🚀변수의 영역과 데이터 공유

by redcubes 2024. 4. 4.

목차

변수의 사용 영역

지역변수 = 자동 변수

- 함수 내 사용. auto (=생략 가능). local variable은 storage class (변수를 사용 범위와 존재 기간에 따라 나눈 것) 중 하나. 

지역변수의 특징
  1. 다른 함수에서 사용 못함
  2. 이름이 같아도 선언된 함수가 다르면 각각 독립된 저장 공간을 가짐
장점
  1. 메모리 효율성
  2. 디버깅에 유리

 

블록 안에서 사용하는 지역 변수

  1. 특정 블록 안에 변수를 선언하면 범위가 블록 내부로 제한. 
  2. 블록이 중첩된 경우 사용 가능한 변수가 둘 이상이면 가장 가까운 블록에 선언된 변수를 사용.
    (안팎에 다 있으면 안의 것을 사용.)
#include <stdio.h>

void assign10(void);
void assign20(void);

int a;                   // 전역 변수 선언

int main(void)
{
	printf("함수 호출 전 a 값 : % d\n", a);  // 전역 변수 a 출력

	assign10();
	assign20();

	printf("함수 호출 후 a 값 : % d\n", a);  // 전역 변수 a 출력

	return 0;
}

void assign10(void)
{
	a = 10;              // 전역 변수 a에 10 대입
}

void assign20(void)
{
	int a;               // 전역 변수와 같은 이름의 지역 변수 선언

	a = 20;              // 지역 변수 a에 20 대입
}

전역 변수 global variable

- 함수 밖에서 선언 특정 함수의 블록에 미포함. 범위 제한 없음. 전역 변수는 자동으로 초기화.

- 전역 변수와 이름이 같은 지역 변수가 있으면 지역 변수를 먼저 사용.

- 문제점

  1. 이름을 바꾸면 그 변수를 사용하는 모든 함수를 찾아 수정.
  2. 값이 잘못된 경우 접근 가능한 모든 함수를 의심해야 함.
  3. 코드블록 내에 같은 이름의 지역변수를 선언하면 전역 변수를 사용하면 전역 변수 못 씀.
#include <stdio.h>

void assign10(void);
void assign20(void);

int a;                   // 전역 변수 선언

int main(void)
{
	printf("함수 호출 전 a 값 : % d\n", a);  // 전역 변수 a 출력

	assign10();
	assign20();

	printf("함수 호출 후 a 값 : % d\n", a);  // 전역 변수 a 출력

	return 0;
}

void assign10(void)
{
	a = 10;              // 전역 변수 a에 10 대입
}

void assign20(void)
{
	int a;               // 전역 변수와 같은 이름의 지역 변수 선언

	a = 20;              // 지역 변수 a에 20 대입
}

정적 지역 변수 static = 블록 안에서만 쓰이는 전역변수

- 사용 범위는 블록 내부로 제한되나 함수가 반환되어도 유지. 지역 변수와 메모리에 존재하는 기간이 다름.
저장 공간이 할당되어 유지되는 시점이 함수 호출과 무관해짐. 프로그램이 실행될 때 메모리에 할당. 끝날때까지 존재. 0으로 자동초기화.

레지스터 변수 resisiter

- 레지스터에 변수 저장.반복문에 쓰는 변수처럼 사용 횟수가 많은 경우 사용하면 실행 시간 줄임.

#include <stdio.h>

int main(void)
{
	register int i;                // 레지스터 변수
	auto int sum = 0;              // auto 지역 변수

	for (i = 1; i <= 10000; i++)   // 반복 과정에서 i를 계속 사용함
	{
		sum += i;                  // i 값을 반복하여 누적
	}

	printf("%d\n", sum);

	return 0;
}

주의사항!

  1. 전역 변수는 레지스터 변수로 선언 불가.
  2. 주소를 구할 수 없음(메모리가 아니므로)
  3. 사용 여부는 컴파일러가 결정. 레지스터로 선언해도 상황에 따라.

 

 

함수의 데이터 공유 방법

C 언어에서 call by value와 call by reference

  • call by value : 함수를 호출할 때 변수의 값을 복사해 인자로 주는 방식
  • call by reference(참조에 의한 호출): 함수 호출의 변수를 포인터를 활용해서 메모리상의 이름으로 직접 사용하는 방식 하나의 변수 공간을 서로 다른 함수에서 2개의 이름으로 함께 공유할 수 있다.

C 언어에서는 call by reference를 구현하는 명백한 형식이 없다.
대신, 포인터를 활용하여 인자로 주고 받으면서 간접적으로 call by reference의 효과를 낼 수 있다. 이 방법은 주소를 주고 받아서, 같은 변수에 대한 참조를 허용하므로 call by reference와 비슷한 효과를 볼 수 있다.

값 복사 전달

- 호출한 함수의 값을 복사해서 호출받은 함수가 조작해도 원본은 유지.

주소 전달

- 호출받은 함수에서 가공 시 원본이 변경됨.

주소 리턴

- 정적 지역 변수와 전역 변수는 주소를 반환할 수 있음.

#include <stdio.h>

int* sum(int a, int b);   // int형 변수의 주소를 반환하는 함수 선언

int main(void)
{
	int* resp;            // 반환값을 저장할 포인터 resp(result pointer)

	resp = sum(10, 20);   // 반환된 주소는 resp에 저장
	printf("두 정수의 합 : %d\n", *resp);   // resp가 가리키는 변숫값 출력

	return 0;
}

int* sum(int a, int b)    // int형 변수의 주소를 반환하는 함수
{
	static int res;       // 정적 지역 변수

	res = a + b;          // 두 정수의 합을 res(result)에 저장

	return &res;          // 정적 지역 변수의 주소 반환
}

주의사항

  • 반환값 지료형이 저장할 포인터 자료형과 같아야 함.
  • 지역 변수의 주소를 반환하면 안됨.

'Tech > Coding' 카테고리의 다른 글

백준20361🐨일우는 야바위꾼.py  (0) 2024.07.18
AtCoder🐨Beginner Contest 362 - C. Sum = 0  (0) 2024.07.14
C언어 고급] 12🚀문자열  (0) 2024.03.31
🐨BOJ쿼드트리  (0) 2024.03.30
C언어 고급]🚀문자  (1) 2024.03.29