저는 Objective-C를 처음 사용하며 const
및 전처리 지시문 에 대해 몇 가지 질문이 #define
있습니다.
첫째,을 사용하여 상수의 유형을 정의 할 수 없음을 발견했습니다 #define
. 왜 그런 겁니까?
둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?
마지막으로 어떤 방법이 더 효율적이고 더 안전합니까?
저는 Objective-C를 처음 사용하며 const
및 전처리 지시문 에 대해 몇 가지 질문이 #define
있습니다.
첫째,을 사용하여 상수의 유형을 정의 할 수 없음을 발견했습니다 #define
. 왜 그런 겁니까?
둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?
마지막으로 어떤 방법이 더 효율적이고 더 안전합니까?
답변:
첫째, #define을 사용하여 상수 유형을 정의 할 수 없다는 것을 발견했습니다. 그 이유는 무엇입니까?
왜? 그것은 사실이 아닙니다:
#define MY_INT_CONSTANT ((int) 12345)
둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?
예. #define
컴파일이 시작되기 전에 교체되는 매크로를 정의합니다. const
변수를 변경하려고하면 컴파일러가 오류를 표시하도록 변수를 수정하기 만합니다. a #define
를 사용할 수 있지만 사용할 수없는 컨텍스트가 있습니다 const
(최신 clang을 사용하여 찾는 데 어려움을 겪고 있지만). 이론적 const
으로는 실행 파일에서 공간을 차지하고 메모리에 대한 참조가 필요하지만 실제로는 중요하지 않으며 컴파일러에 의해 최적화 될 수 있습니다.
const
s는 s보다 훨씬 더 컴파일러 및 디버거 친화적 #define
입니다. 대부분의 경우, 이것이 어떤 것을 사용할 것인지 결정할 때 고려해야 할 최우선 사항입니다.
사용할 수 #define
있지만 사용할 수 없는 컨텍스트를 생각했습니다 const
. 많은 .c
파일 에서 사용하려는 상수가 #define
있는 경우 헤더에 붙이면됩니다. 를 사용하면 const
C 파일에 정의가 있어야하며
// in a C file
const int MY_INT_CONST = 12345;
// in a header
extern const int MY_INT_CONST;
헤더에. MY_INT_CONST
정의 된 파일을 제외한 모든 C 파일에서 정적 또는 전역 범위 배열의 크기로 사용할 수 없습니다.
그러나 정수 상수의 경우 enum
. 사실 그것은 애플이 거의 변함없이하는 일이다. 이것은 #define
s와 const
s 의 모든 장점을 가지고 있지만 정수 상수에 대해서만 작동합니다.
// 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
합니다. 그럴 이유가없는 한 사용합니다.
int
. 그러나 현대 컴파일러에서 어떤 차이가 있다면 매우 놀랍습니다.
C 코더에서 :
A const
는 내용을 변경할 수없는 변수입니다.
#define name value
그러나,의 모든 인스턴스를 대체하는 전 처리기 명령입니다 name
와 함께 value
.
예를 들어,이면 컴파일 할 때 코드 #define defTest 5
의 모든 인스턴스 defTest
가로 대체됩니다 5
.
동일한 의미가 아닌 #define과 const 명령어의 차이점을 이해하는 것이 중요합니다.
const
const
일단 초기화되면 상수가되는 요청 된 유형에서 객체를 생성하는 데 사용됩니다. 이는 프로그램 메모리의 객체이며 읽기 전용으로 사용할 수 있음을 의미합니다. 프로그램이 실행될 때마다 개체가 생성됩니다.
#define
#define
코드 가독성과 향후 수정을 용이하게하기 위해 사용됩니다. 정의를 사용할 때 이름 뒤에있는 값만 마스킹합니다. 따라서 직사각형으로 작업 할 때 해당 값으로 너비와 높이를 정의 할 수 있습니다. 그러면 코드에서 숫자 대신 이름이 있기 때문에 읽기가 더 쉽습니다.
나중에 너비 값을 변경하기로 결정하면 전체 파일에서 지루하고 위험한 찾기 / 바꾸기 대신 정의에서만 변경하면됩니다. 컴파일 할 때 전처리 기는 정의 된 모든 이름을 코드의 값으로 대체합니다. 따라서 시간 낭비가 없습니다.
전 처리기 지시문이 눈살을 찌푸 리기 때문에 const
. 전 처리기 지시문이 컴파일 전에 확인되기 때문에 전처리기로 유형을 지정할 수 없습니다. 글쎄, 할 수 있지만 다음과 같습니다.
#define DEFINE_INT(name,value) const int name = value;
그리고 그것을 사용하십시오
DEFINE_INT(x,42)
컴파일러에서 다음과 같이 볼 수 있습니다.
const int x = 42;
첫째, #define을 사용하여 상수 유형을 정의 할 수 없다는 것을 발견했습니다. 그 이유는 무엇입니까?
내 첫 번째 스 니펫을 볼 수 있습니다.
둘째, 그중 하나를 다른 것보다 사용하면 어떤 이점이 있습니까?
일반적으로 const
전 처리기 지시문 대신 사용하면 디버깅에 도움이되지만이 경우에는 그다지 도움이되지 않지만 여전히 그렇습니다.
마지막으로 어떤 방법이 더 효율적이고 더 안전합니까?
둘 다 효율적입니다. 매크로는 런타임 중에 변경할 수 없지만 변수는 변경할 수 있으므로 잠재적 으로 더 안전 할 수 있다고 말하고 싶습니다 .
const ...
매크로를 사용하는 대신 입력 만하는 이유는 무엇 입니까?
pre-processor directives are frowned upon
[인용 필요]
이전에 #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을 사용하고 유형을 지정해야하는 상수 변수를 선언하는 상수를 사용하여 둘 다 라이브러리를 작성했습니다.