728x90
1. 변수 사용 영역 (지역/전역/정적 지역/레지스터 변수)
2. 함수의 데이터 공유
3. 다차원 배열
4. 포인터 배열
변수 사용 영역
- 지역 변수 (local)
- [auto] 자료형 변수명;
- auto 예약어와 함께 함수 안에 지역 변수를 선언하며 auto 예약어는 생략이 가능하다.
- 사용 범위는 블록 내부로 제한된다.
- 변수가 선언된 함수가 반환되면 할당된 저장공간을 자동으로 회수한다.
- 지역 변수 사용시 주의점
- 지역 변수는 같은 변수명이여도 선언된 함수가 다르면 독립된 저장 공간을 갖는다.
- 사용하는 변수가 여럿이면 가장 가까운 블록에 선언된 변수를 사용한다.
- 전역 변수 (global)
- 자료형 변수명;
- 함수 밖에 변수를 선언하며 예약어가 따로 없다.
- 사용범위가 함수나 블록에 제한되지 않고 프로그램이 실행될 때 메모리에 할당되고 종료될 때까지 존재한다.
- 0으로 자동 초기화된다.
- 전역 변수 vs 지역 변수
- 전역과 지역 변수명이 같을 경우, 지역변수를 먼저 사용한다.
- 정적 지역 변수 (static)
- static 자료형 변수명;
- 사용 범위는 블록 내부로 제한된다.
- 변수가 선언된 함수가 반환되더라도 그 저장 공간을 계속 유지한다. (함수가 여러번 호출되는 경우 같은 변수를 공유)
- 프로그램이 실행될 때 메모리에 할당되고 종료될 때까지 존재한다.
- 0으로 자동 초기화된다.
- 레지스터 변수(register)
- register 자료형 변수명;
- CPU 내의 저장 공간인 레지스터에 저장 공간이 할당되어 실행 시간을 줄일 수 있다.
- 레지스터는 데이터 처리 속도가 가장 빠른 저장 공간
- 일반 변수는 메인 메모리 -> 레지스터 -> 연산 장치에 사용
- 레지스터 변수는 레지스터 -> 연산 장치에 사용
- 레지스터 변수 사용 시 주의점
- 레지스터 사용 여부는 컴파일러가 결정한다. (register 변수를 선언했다고 적용되는건 아님)
- 저장 공간이 메모리에 있는 것이 아니므로 주소 연산자로 변수의 주소를 구할 수 없다.
- 전역 변수는 레지스터 변수로 선언할 수 없다. (CPU 자원을 잠깐 빌리므로)
함수의 데이터 공유
- 값을 복사하여 전달 (Pass by Value)
- 함수에 전달된 인자는 복사본이므로, 함수 내에서 값을 바꿔도 원본 변수에는 영향을 주지 않는다.
- 값을 복사해서 전달하는 방식을 기본적으로 사용한다.
int changeValue(int x) {
x = x + 10;
return x;
}
void main() {
int a = 5;
a = changeValue(a);
printf("함수 호출 후 a: %d\n", a);
}
- 주소를 전달
- 변수의 주소(포인터)를 함수에 전달해서, 함수 안에서 원본 변수 값을 직접 변경한다.
void changeValue(int *x) {
*x = *x + 10;
}
void main() {
int a = 5;
changeValue(&a); // a의 주소를 전달
printf("함수 호출 후 a: %d\n", a);
}
- 주소를 반환하는 함수
- 함수 내부에서 만든 데이터에 접근하거나 값을 변경 가능하다.
- 반환값의 자료형은 반환값을 저장할 포인터의 자료형과 같아야한다.
int* sum(int a, int b) {
static int res; // static 변수는 함수 종료 후에도 유지됨
res = a + b;
return &res;
}
void main() {
int *resp = sum(10, 20);
printf("두 정수의 합: %d\n", *resp);
}
다차원 배열과 포인터 배열
- 다차원 배열
- 자료형 배열명[row 행][column 열];
- 행 우선(row-major order) 방식으로 저장된다.
- 다차원 배열인 int a[3][4];는 메모리상에서 사실상 길이가 12인 일차원 배열과 동일하다.
- 배열 이름은 "행 단위 배열을 가리키는 포인터"로 동작한다. (ex. a[i][j] => *( *(a의 주소값+i)의 주소값 + j )와 같은 의미)
int a[3][4];
행 0 : a[0][0] a[0][1] a[0][2] a[0][3]
행 1 : a[1][0] a[1][1] a[1][2] a[1][3]
행 2 : a[2][0] a[2][1] a[2][2] a[2][3]
- 포인터 배열
- 포인터 배열은 “포인터들을 요소로 가진 배열”이다.
- int *p[3]; -> int* 3개가 들어가는 배열
- 포인터 배열은 int *p[3]처럼 주소(포인터)들이 연속으로 저장된다.
int a = 10, b = 20, c = 30;
int *p[3] = { &a, &b, &c }; // 포인터 3개를 요소로 갖는 배열
- 포인트 배열을 2차원 배열처럼 사용하기
- 자료형 *포인트_배열명[n] = ( 배열명 1, 배열명 2, ... }
int ary1[4] = {1, 2, 3, 4};
...
int *pary[3] = { ary1, ary2, ary3 };
pary[2][2] => *(pary[2] + 2) => *(pary + 2 + 2);
'C > C 문법' 카테고리의 다른 글
| 혼자 공부하는 C언어 (17강) (0) | 2025.09.07 |
|---|---|
| 혼자 공부하는 C언어 (15~16강) (0) | 2025.09.07 |
| 혼자 공부하는 C언어 (11~12강) (1) | 2025.09.07 |
| 혼자 공부하는 C언어 (9~10강) (0) | 2025.09.06 |
| 혼자 공부하는 C언어 (7~8강) (0) | 2025.09.05 |