본문 바로가기
C/C 문법

혼자 공부하는 C언어 (13~14강)

by Sein_ 2025. 9. 7.
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