我是Objective-C的新手,并且关于const
和预处理指令还有一些问题#define
。
首先,我发现无法使用定义常量的类型#define
。这是为什么?
其次,使用其中一个相对于另一个有什么优势吗?
最后,哪种方法更有效和/或更安全?
我是Objective-C的新手,并且关于const
和预处理指令还有一些问题#define
。
首先,我发现无法使用定义常量的类型#define
。这是为什么?
其次,使用其中一个相对于另一个有什么优势吗?
最后,哪种方法更有效和/或更安全?
Answers:
首先,我发现无法使用#define定义常量的类型,为什么呢?
为什么呢 这不是真的:
#define MY_INT_CONSTANT ((int) 12345)
其次,使用其中一个相对于另一个有什么优势吗?
是。 #define
定义一个宏,即使在编译开始之前,该宏也会被替换。 const
仅修改变量,以便在尝试更改变量时编译器将标记错误。在某些情况下,您可以使用a,#define
但不能使用a const
(尽管我正在努力使用最新的clang查找一个)。从理论上讲,const
占用可执行文件中的空间并需要引用内存,但实际上这并不重要,编译器可以对其进行优化。
const
与相比,#define
s对编译器和调试器更友好。在大多数情况下,这是您在决定使用哪一个时应该考虑的首要点。
只是想到了可以使用#define
但不能使用的上下文const
。如果您有一个常量要在大量.c
文件中使用,则#define
只需将其放在标头中即可。使用a,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
。但是,如果它在现代编译器中根本没有影响,我会感到非常惊讶。
重要的是要理解#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 ...
in而不使用宏?
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来执行我所显示的内容,并使用常量来声明需要在其上指定类型的常量变量。