Skip to content

Instantly share code, notes, and snippets.

@sooop
Created March 26, 2014 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sooop/9783651 to your computer and use it in GitHub Desktop.
Save sooop/9783651 to your computer and use it in GitHub Desktop.

C Storage Class

C언어에서 함수나 변수의 범위와 유지시간(lifetime)은 그 저장소 클래스에 의해 결정된다. 각각의 변수는 유지시간 혹은 값이 저장되는 문맥을 가지고 있다. 함수는 변수처럼 특정한 스코프내에서만 존재하며, 보인다.

링커는 함수의 이름으로 각 함수를 구분하기 때문에, 우연히 이름을 맞춘다면(?) 함수가 실행될 수는 있다.

C에는 4가지 저장 클래스가 있다. auto, register, static, extern이 그것이다.

auto

이 키워드는 거의 본 일이 없을 것이다. 왜냐하면 모든 변수의 디폴트 저장타입이기 때문이다. 자동변수는 프로그램이 블럭에 들어설 때 자동으로 할당되고, 블럭을 빠져나올 때 자동으로 해제된다.

블럭은 중괄호({, }) 로 둘러싸인 영역을 말한다. 다음의 코드에서 a는 if 블럭 내에서 선언되었고, 블럭이 끝나면서 폐기된다. 따라서 블럭이 닫힌 이후에 참조하는 것은 오류가 된다.

#include <stdio.h>

int main(int argc, const char **argv){
    int i = 10;
    printf("i: %d\n", i);
    if(i == 10) {
        int a = 50;
    }
    printf("a: %d\n", a);
    return 0;
}

register

Objective-C 개발자들은 레지스터에 익숙치 않을 수 있는데, 이 타입은 auto와 동일하게 작동한다. 대신 스택이 아닌 레지스터에 생성된다는 차이만 있다. 레지스터는 보통 램에 비해 빠른 액세스를 지원하지만, 요즘 컴퓨터들의 메모리 관리 기술의 복잡성 때문에 항상 속도를 보장하지는 못한다. 또한 레지스터를 많이 사용하는 것은 CPU의 레지스터 활용폭을 제한하여 수행성능을 더 떨어뜨리는 결과를 낳기도 한다. 따라서 그냥 그런게 있다는 정도만 알아두자.

static

정적변수를 가리키는 static은 종종 보게되는 키워드이다. 사실 이 키워드는 사용되는 문맥에 따라서 조금씩 다른 의미로 다양하게 쓰이기 때문에 혼란을 주는 주범인데, 스토리지 타입을 가리킬 때는 다음 둘 중의 하나의 의미가 된다.

  1. 메소드나 함수 내부에서 선언된 정적변수는 함수/메소드의 호출이 끝난 후에도 값을 유지한다.
  2. 정적변수가 전역으로 선언되는 경우에는 같은 파일 내의 모든 함수, 메소드가 이를 참조할 수 있다. (같은 소스파일 내에서라는 점이 중요하다.) 그리고 이 원리는 함수에 대해서도 동일하게 적용된다.

static singleton

정적변수는 싱글톤 패턴을 구현할 때 등장하는 단골 손님이다.

+ (instancetype)sharedInstance {
    static id _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
    });
    return _sharedInstance;
}

이러한 싱글톤 패턴은 앱의 생명주기동안 단 한 번만 생성되는 객체로 주로 생성비용이 많이드는 객체를 이런식으로 만들어 재활용한다.

extern

static이 함수나 파일을 특정 파일 내에서 전역으로 만들어준다면, extern은 다른 파일에서도 전역으로 참조할 수 있는 변수를 만들어준다. 일반적으로 이런 전역변수는 좋은 아이디어가 아니다. 언제 어떻게 상태가 변할지 모른다는 점은 디버깅이 거의 불가능한 문제를 만들어내기도 한다. 따라서 변수보다는 공용함수나 상수를 정의할 때 사용한다.

전역 문자열 상수

공용 인터페이스에서 사용하는 문자열 상수를 정의하고 싶을 때, 공용헤더파일내에 이를 extern NSString * const로 선언한다.

프로젝트 전체에 대해 전역이며 (extern) 문자열 객체이다. 변수의 내용 자체가 바뀔 수 없는 상수이다.

이런 방식으로 선언된 상수는 다른 파일 어딘가에서 초기화될 수 있다.

AppDelegate.h

extern NSString * const kAppErrorDomain;

AppDelegate.m

NSString * const kAppErrorDomain = @"com.example.yourapp.error";

공용함수

몇몇 API는 편의용 함수 몇 개씩을 공개한다. 이러한 경우 역시 바로 앞과 같은 효과를 가진다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment