[objective-c] Objective-C에서 #define 대 const

저는 Objective-C를 처음 사용하며 const및 전처리 지시문 에 대해 몇 가지 질문이 #define있습니다.

첫째,을 사용하여 상수의 유형을 정의 할 수 없음을 발견했습니다 #define. 왜 그런 겁니까?

둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?

마지막으로 어떤 방법이 더 효율적이고 더 안전합니까?



답변

첫째, #define을 사용하여 상수 유형을 정의 할 수 없다는 것을 발견했습니다. 그 이유는 무엇입니까?

왜? 그것은 사실이 아닙니다:

#define MY_INT_CONSTANT ((int) 12345)

둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?

예. #define컴파일이 시작되기 전에 교체되는 매크로를 정의합니다. const변수를 변경하려고하면 컴파일러가 오류를 표시하도록 변수를 수정하기 만합니다. a #define를 사용할 수 있지만 사용할 수없는 컨텍스트가 있습니다 const(최신 clang을 사용하여 찾는 데 어려움을 겪고 있지만). 이론적 const으로는 실행 파일에서 공간을 차지하고 메모리에 대한 참조가 필요하지만 실제로는 중요하지 않으며 컴파일러에 의해 최적화 될 수 있습니다.

consts는 s보다 훨씬 더 컴파일러 및 디버거 친화적 #define입니다. 대부분의 경우, 이것이 어떤 것을 사용할 것인지 결정할 때 고려해야 할 최우선 사항입니다.

사용할 수 #define있지만 사용할 수 없는 컨텍스트를 생각했습니다 const. 많은 .c파일 에서 사용하려는 상수가 #define있는 경우 헤더에 붙이면됩니다. 를 사용하면 constC 파일에 정의가 있어야하며

// in a C file
const int MY_INT_CONST = 12345;

// in a header
extern const int MY_INT_CONST;

헤더에. MY_INT_CONST정의 된 파일을 제외한 모든 C 파일에서 정적 또는 전역 범위 배열의 크기로 사용할 수 없습니다.

그러나 정수 상수의 경우 enum. 사실 그것은 애플이 거의 변함없이하는 일이다. 이것은 #defines와 consts 의 모든 장점을 가지고 있지만 정수 상수에 대해서만 작동합니다.

// In a header
enum
{
    MY_INT_CONST = 12345,
};

마지막으로 어떤 방법이 더 효율적이고 더 안전합니까?

#define내가 말했듯이 현대 컴파일러는 아마도 차이가 거의 없음을 보장하지만 이론적으로 더 효율적입니다. #define할당을 시도하는 것이 항상 컴파일러 오류라는 점에서 더 안전합니다.

#define FOO 5

// ....

FOO = 6;   // Always a syntax error

const컴파일러가 경고를 발행 할 수 있지만 s가 할당되도록 속일 수 있습니다.

const int FOO = 5;

// ...

(int) FOO = 6;     // Can make this compile

플랫폼에 따라 상수가 읽기 전용 세그먼트에 배치되고 C 표준에 따라 공식적으로 정의되지 않은 동작 인 경우 런타임에 할당이 여전히 실패 할 수 있습니다.

개인적으로 정수 상수 enum의 경우 다른 유형의 상수에는 항상 s를 사용 const합니다. 그럴 이유가없는 한 사용합니다.


답변

C 코더에서 :

A const는 내용을 변경할 수없는 변수입니다.

#define name value그러나,의 모든 인스턴스를 대체하는 전 처리기 명령입니다 name와 함께 value.

예를 들어,이면 컴파일 할 때 코드 #define defTest 5의 모든 인스턴스 defTest가로 대체됩니다 5.


답변

동일한 의미가 아닌 #define과 const 명령어의 차이점을 이해하는 것이 중요합니다.

const

const일단 초기화되면 상수가되는 요청 된 유형에서 객체를 생성하는 데 사용됩니다. 이는 프로그램 메모리의 객체이며 읽기 전용으로 사용할 수 있음을 의미합니다. 프로그램이 실행될 때마다 개체가 생성됩니다.

#define

#define코드 가독성과 향후 수정을 용이하게하기 위해 사용됩니다. 정의를 사용할 때 이름 뒤에있는 값만 마스킹합니다. 따라서 직사각형으로 작업 할 때 해당 값으로 너비와 높이를 정의 할 수 있습니다. 그러면 코드에서 숫자 대신 이름이 있기 때문에 읽기가 더 쉽습니다.

나중에 너비 값을 변경하기로 결정하면 전체 파일에서 지루하고 위험한 찾기 / 바꾸기 대신 정의에서만 변경하면됩니다. 컴파일 할 때 전처리 기는 정의 된 모든 이름을 코드의 값으로 대체합니다. 따라서 시간 낭비가 없습니다.


답변

다른 사람들의 의견 외에도 #define전처리 기가 컴파일러보다 먼저 오류를 잡기 때문에 사용 하는 오류 는 디버그하기가 매우 어렵습니다.


답변

전 처리기 지시문이 눈살을 찌푸 리기 때문에 const. 전 처리기 지시문이 컴파일 전에 확인되기 때문에 전처리기로 유형을 지정할 수 없습니다. 글쎄, 할 수 있지만 다음과 같습니다.

#define DEFINE_INT(name,value) const int name = value;

그리고 그것을 사용하십시오

DEFINE_INT(x,42)

컴파일러에서 다음과 같이 볼 수 있습니다.

const int x = 42;

첫째, #define을 사용하여 상수 유형을 정의 할 수 없다는 것을 발견했습니다. 그 이유는 무엇입니까?

내 첫 번째 스 니펫을 볼 수 있습니다.

둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?

일반적으로 const전 처리기 지시문 대신 사용하면 디버깅에 도움이되지만이 경우에는 그다지 도움이되지 않지만 여전히 그렇습니다.

마지막으로 어떤 방법이 더 효율적이고 더 안전합니까?

둘 다 효율적입니다. 매크로는 런타임 중에 변경할 수 없지만 변수는 변경할 수 있으므로 잠재적 으로 더 안전 할 수 있다고 말하고 싶습니다 .


답변

이전에 #define을 사용하여 한 가지 방법으로 더 많은 방법을 만들 수 있습니다.

 // This method takes up to 4 numbers, we don't care what the method does with these numbers.
 void doSomeCalculationWithMultipleNumbers:(NSNumber *)num1 Number2:(NSNumber *)num2 Number3:(NSNumber *)num23 Number3:(NSNumber *)num3;

그러나 나는 또한 3 개의 숫자와 2 개의 숫자만을 취하는 방법을 가질 수 있으므로 두 개의 새로운 방법을 작성하는 대신 #define을 사용하여 동일한 방법을 사용할 것입니다.

 #define doCalculationWithFourNumbers(num1, num2, num3, num4) \
         doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), (num4))

 #define doCalculationWithThreeNumbers(num1, num2, num3) \
         doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), nil)

 #define doCalculationWithTwoNumbers(num1, num2) \
         doSomeCalculationWithMultipleNumbers((num1), (num2), nil, nil)

제 생각에는 이것이 매우 멋진 일이라고 생각합니다. 바로 방법으로 이동하여 원하지 않는 공간에 nil을 넣을 수 있지만 라이브러리를 구축하는 경우 매우 유용합니다. 또한 이것은 방법입니다

     NSLocalizedString(<#key#>, <#comment#>)
     NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
     NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>)

완료되었습니다.

나는 당신이 상수로 이것을 할 수 있다고 믿지 않습니다. 그러나 상수는 컴파일 전에 해결되는 전 처리기 지시문이기 때문에 #define으로 유형을 지정할 수없는 것처럼 #define보다 이점이 있으며 #define으로 오류가 발생하면 디버그하기가 더 어렵습니다. 상수. 둘 다 장점과 단점이 있지만 모두 사용하기로 결정한 프로그래머에 따라 다릅니다. 내가 보여준 작업을 수행하기 위해 #define을 사용하고 유형을 지정해야하는 상수 변수를 선언하는 상수를 사용하여 둘 다 라이브러리를 작성했습니다.


답변