변수(variable)
: 데이터를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간
변수의 속성
: 이름, 타입, 크기, 값 + 범위, 생존 시간, 연결
- 범위(scope) : 변수가 사용 가능한 범위_가시성
- 생존 시간(lifetime) : 메모리에 존재하는 시간
- 연결(linkage) : 다른 연역에 있는 변수와의 연결 상태
💡 변수는 사용하는 위치와 가까운 곳에서 선언하는 것이 좋다.
지역 변수(Local Variable)
: 블록 안에 선언되는 변수
int sub(void)
{
int x = 0;
while(flag != 0){
int y;
...
} // 지역 변수 y가 사용가능한 범위 : 블록 내
y = 0; // Error) y가 선언된 블록을 벗어나서 사용
...
} // 지역 변수 x가 사용가능한 범위
💡 지역 변수의 선언 위치는 블록 맨 앞이 원칙이다!
(최신 버전의 C에서는 블록 어디에서나 선언 가능이지만 가독성을 위해 지역 변수는 블록 맨 앞에 선언한다.)
- 지역 변수가 쓰이는 블록만 다르면 이름은 같아도 된다.
int main(void)
{
int count = 0;
...
}
float func(void)
{
int count = 10;
...
}
- 지역 변수는 선언된 블록이 끝나면 자동으로 소멸된다.
- 초기화를 해주지않으면 쓰레기 값(dummy 값)을 갖는다.
- 함수의 매개 변수(파라미터)도 일종의 지역 변수이다.
전역 변수(Global Variable)
: 함수 외부에서 선언되는 변수
- 전역 변수의 범위는 소스 파일 전체이다.
- 전역변수는 컴파일러에 의해 자동으로 초기화된다.
└ 그러므로 사용자는 특별한 경우가 아니면 초기화하지 않아도 된다.
#include <stdio.h>
int A;
int B;
// 전역 변수의 초기값은 자동으로 0이 된다.
// 전역 변수의 범위는 파일 전체
int add() { return A + B; }
int main()
{
int answer;
A = 5;
B = 7;
answer = add();
printf("%d + %d = %d\n", A, B, answer);
return 0;
}
- 거의 모든 함수에서 사용하는 공통적인 데이터는 전역 변수로 한다.
- 일부 함수들만 사용하는 데이터는 함수의 인수로 전달한다.(Call by Vallue)
같은 이름의 전역 변수와 지역 변수
#include <stdio.h>
int sum = 1;
int main(void)
{
{
int sum = 0;
printf("1. sum = %d\n", sum);
}
printf("2. sum = %d\n", sum);
return 0;
}
└ 지역 변수가 선언된 블록이 앞에 있으므로 지역 변수가 먼저 출력되고 이후 전역 변수가 출력된다.
생존 기간
: 변수가 생존하는 시간
생존 시간에 따라 변수를 분류하면 정적 할당과 자동 할당으로 나눌 수 있다.
생존 기간을 결정하는 요인
- 변수가 선언된 위치
- 저장 유형 지정자
- auto (default)
- static (전역 변수)
- register (빠른 작업 효율)
- extern (파일 통합 관리)
: 컴퓨터의 프로세서 내에서 자료를 보관하는 아주 빠른 기억 장소
정적 할당(static allocation)
: 프로그램 실행 시간 동안 계속 유지
자동 할당(automatic allocation)
- 블록에 들어갈 때 생성
- 블록에서 나올 때 소멸
저장 유형 지정자
auto
: 변수를 선언한 위치에서 자동으로 만들어지고 블록을 벗어나게 되면 자동으로 소멸되는 저장 유형을 지정
- 지역 변수는 auto가 생략되어도 자동 변수로 지정
static
: 정적 지역 변수
- 기본적인 변수는 동적 변수로써 변수 선언과 동시에 메모리 할당, 지역 변수의 사용종료와 함꼐 메모리 해제가 이루어진다.
- 하지만 정적 변수는 컴파일 시 메모리에 할당되며 프로그램 종료 시 메모리가 해제된다.
💡 static을 지정하면 지역 변수가 정적 변수가 된다.
#include <stdio.h>
void sub() {
static int scount = 0;
int acount = 0;
printf("scount = %d\t", scount);
printf("acount = %d\n", acount);
scount++;
acount++;
}
int main(void) {
sub();
sub();
sub();
return 0;
}
register
: 레지스터(register)에 변수를 저장
- 작업량이 많은 프로그램의 경우 속도 향상을 위해 사용
volatile
: 하드웨어가 수시로 변수의 값을 변경하는 경우에 사용
- 컴퓨터 외부에서 데이터를 제공받거나 외부 데이터를 끌어다 사용해야할 때 사용한다.
- 보통 하드웨어 시스템 개발에서 사용한다.
- 외부 장치가 연결되어 특정 메모리를 공유하고 있을 때 그 메모리의 변동 상태를 수시로 확인하기 위해 사용한다.
volatile int io_port; // 하드웨어와 연결된 변수
void wait(void) {
io_port = 0;
while (io_port != 255)
;
}
연결(linkage)
: 외부에 선언된 변수를 불러서 사용하는 것
└ 전역 변수만 연결이 가능하다.
- 외부 연결
- 내부 연결
- 무 연결
외부 연결 - extern (외부 참조 변수)
- 전역 변수 extern을 이용하여 서로 연결한다.
- 여러 개의 파일로 이루어진 경우, 하나의 전역변수를 여러 소스 파일에서 공유해야하는 데, 이때 하나의 파일에서 전역변수를 선언하고 다른 파일에서는 extern 지정자를 이용하여 이 변수를 참조하게 한다.
내부 연결
- 전역 변수 앞에 static 이 붙으면 내부 연결이 된다.
- 즉 하나의 소스 파일 내에서만 사용 가능하다.
- 전역 변수 앞에 static 이 붙지 않으면 다른 소스 파일에서 이 전역 변수를 사용할 수 있다.
함수명 앞에 static이 붙는 경우
- 특정 소스 파일에 있는 함수명 앞에 static 이 붙어 있는 경우, 이 함수는 해당 소스 파일 내에서만 사용이 가능하다.
- 내부 연결 상태로, 이러한 함수를 정적함수라고 한다.
- 함수명 앞에 static 이 없으면 변수와 마찬가지로 다른 소스파일에서 extern 으로 선언하여 사용 가능하다.
💡 일반적으로 auto 사용 권장
가변 매개 변수
: 매개 변수의 개수가 가변적으로 변할 수 있는 기능
int sum(int num, ...) // num은 가변 인자의 개수
💡<stdarg.h> 헤더를 포함해야한다.
- 인자 수를 제한 없이 할 수 있도록 하는 함수를 허용한다.
#include <stdio.h>
#include <stdarg.h> // va_list, va_start, va_arg, va_end가 정의된 헤더 파일
void printNumbers(int args, ...) { // 가변 인자의 개수를 받음. ...로 가변 인자 설정
int N;
va_list ap; // 가변 인자 목록 포인터
va_start(ap, args); // 가변 인자 목록 포인터 설정
for (N = 0; N < args; N++) { // 가변 인자 개수만큼 반복
int num = va_arg(ap, int); // int 크기만큼 목록 포인터에서 값을 가져옴
printf("%d ", num);
}
va_end(ap); // 가변 인자 목록 포인터를 NULL로 초기화
printf("\n");
}
int main() {
printNumbers(1, 10); // 인수 개수 1개
printNumbers(2, 10, 20); // 인수 개수 2개
printNumbers(3, 10, 20, 30); // 인수 개수 3개
printNumbers(4, 10, 20, 30, 40); // 인수 개수 4개
return 0;
}
재귀(Recursion)
: 함수는 자기 자신을 호출할 수 있는데 이를 순환, 또는 재귀라고 한다.
팩토리얼(n!) 프로그래밍
int factorial(int n)
{
if (n <= 1)
return (1);
else
return (n * factorial(n-1));
}
- 팩토리얼 계산식으로 n! 을 정의
- 다음 식으로 다시 (n-1)! 사용 → 순환적 계산
- (n-1)! 계산을 위해 다시 (n-(n-1)!)! 계산 필요
- 현재 작성하고 있는 함수가 n! 계산 함수이므로 함수의 인수를 n-1로 변경하여 호출한다.
2진수 형식 출력 프로그램
#include <stdio.h>
void Dec_to_Bin(int x) {
if( x > 0 )
{
Dec_to_Bin (x / 2);
printf("%d", x % 2);
}
}
int main(void) {
int n;
printf("정수를 입력하시오:");
scanf("%d", &n);
printf("result =");
Dec_to_Bin (n);
printf("\n");
return 0;
}
아래 노션 페이지에 C 공부 내용에 대해 업로드 합니다!
수정사항이나 질문사항의 경우 노션 댓글로 남겨주세요!(*•̀ᴗ•́*)و ̑̑
개발 환경
작성 플랫폼
'🧑💻 Language > C·C++' 카테고리의 다른 글
[C 이론] 11. 포인터(1) (0) | 2021.06.01 |
---|---|
[C 이론] 10. 배열 (0) | 2021.05.26 |
[C 이론] 8. 함수 (0) | 2021.05.06 |
[C 이론] 7. 반복문 (0) | 2021.05.03 |
[C 이론] 6. 조건문 (0) | 2021.05.03 |