Objective-C中的#define vs const

我是Objective-C的新手,我有几个关于const和预处理指令#define

首先,我发现使用#define定义常量的types是不可能的。 这是为什么?

其次,使用其中一个有什么好处?

最后,哪种方式更有效率和/或更安全?

首先,我发现它不可能使用#define定义常量的types,为什么呢?

为什么是什么? 这不是真的:

 #define MY_INT_CONSTANT ((int) 12345) 

其次,使用其中一个有什么好处?

是。 #define定义了一个在编译开始之前被replace的macros。 const只是修改一个variables,以便编译器会在你尝试修改的时候标记一个错误。 有些情况下你可以使用#define但是你不能使用const (虽然我正在努力寻找一个使用最新的clang)。 理论上, const在可执行文件中占用空间并需要对内存的引用,但实际上这并不重要,可能会被编译器优化掉。

const#define更适合编译器和debugging器。 在大多数情况下,在决定使用哪一个时,这是您应该考虑的重点。

只是想到你可以使用#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; 

在标题中。 除了定义的C文件外, 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 

虽然编译器可能会发出警告,但consts可以被诱骗分配给:

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

根据平台的不同,如果常量被放置在只读段中,那么赋值可能在运行时仍然失败,并且根据C标准它是正式的未定义行为。

就个人而言,对于整数常量,我总是使用enum的其他types的const ,我使用const除非我有一个非常好的理由不。

从C编码器:

const是一个简单的variables,其内容不能改变。

但是,# #define name value是一个预处理器命令,用valuereplacename所有实例。

例如,如果你#define defTest 5 ,那么你编译时,你的代码中所有的defTest实例将被replace为5

理解#define和const指令之间的区别是非常重要的。

const

const用于从被问询的types生成一个对象,一旦初始化,该对象将保持不变。 这意味着它是程序存储器中的一个对象,可以作为只读使用。 每次程序启动时都会生成该对象。

#define

#define用于简化代码的可读性和将来的修改。 当使用一个定义时,你只能掩盖一个名字后面的值。 因此,在使用矩形时,可以使用相应的值定义宽度和高度。 然后在代码中,它会更容易阅读,因为代替数字会有名字。

如果以后你决定改变宽度的值,你只需要在定义中改变它,而不是在你的整个文件中进行无聊和危险的查找/replace。 编译时,预处理器将用代码中的值replace所有定义的名称。 因此,没有时间使用它们。

除了其他人的评论之外,使用#define错误是非常难以debugging的,因为预处理器在编译器之前掌握了这些错误。

由于预处理器指令是皱眉,我build议使用const 。 您无法使用预处理器指定types,因为在编译之前会parsing预处理器指令。 那么,你可以,但是像这样:

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

并将其用作

 DEFINE_INT(x,42) 

这将被编译器看作

 const int x = 42; 

首先,我发现它不可能使用#define定义常量的types,为什么呢?

你可以看到我的第一个片段。

其次,使用其中一个有什么好处?

通常有一个const而不是预处理器指令有助于debugging,而不是在这种情况下(但仍然)。

最后,哪种方式更有效率和/或更安全?

两者都是有效的。 我会说macros可能会更安全,因为它不能在运行时更改,而variables可以。

我曾经使用过#define来帮助创build更多的方法,如果我有类似的东西。

  // 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) 

我认为这是一件非常酷的事情,我知道你可以直接使用这个方法,只在你不想要的空间中放入零,但是如果你正在build立一个库,它是非常有用的。 这也是如何

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

完成。

而我不相信你可以用常量做到这一点。 但是常量比#define有更多的好处,就像你不能用#define指定一个types一样,因为它是一个在编译之前解决的预处理器指令,如果你在#define中遇到错误,那么它们就很难debugging常量。 两者都有好处和坏处,但我要说这一切都取决于程序员你决定使用哪一个。 我已经写了一个库,他们在使用#define做我已经显示和常量声明常量variables,我需要指定一个types。