#在Objective-C中定义vs常量

#在Objective-C中定义vs常量,objective-c,constants,c-preprocessor,Objective C,Constants,C Preprocessor,我是Objective-C新手,我对const和预处理指令#define有一些问题 首先,我发现不可能使用#define定义常量的类型。为什么呢 第二,使用其中一种方法比使用另一种方法有什么好处 最后,哪种方法更有效和/或更安全?由于不支持预处理器指令,我建议使用常量。不能使用预处理器指定类型,因为预处理器指令在编译之前已解析。好吧,你可以,但有点像: #define DEFINE_INT(name,value) const int name = value; 并将其用作 DEFINE_INT

我是Objective-C新手,我对
const
和预处理指令
#define
有一些问题

首先,我发现不可能使用
#define
定义常量的类型。为什么呢

第二,使用其中一种方法比使用另一种方法有什么好处


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

由于不支持预处理器指令,我建议使用
常量。不能使用预处理器指定类型,因为预处理器指令在编译之前已解析。好吧,你可以,但有点像:

#define DEFINE_INT(name,value) const int name = value;
并将其用作

DEFINE_INT(x,42) 
编译器会将其视为

const int x = 42;
首先,我发现不可能使用#define定义常量的类型,为什么

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

第二,使用其中一种方法比使用另一种方法有什么好处

通常,使用
const
代替预处理器指令有助于调试,在这种情况下没有那么多(但仍然如此)

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

两者都同样有效。我想说,宏可能更安全,因为它在运行时不能更改,而变量可以更改。

来自C编码器:

const
只是一个内容无法更改的变量

#define name value
是一个预处理器命令,它将
name
的所有实例替换为
value


例如,如果您
#定义defTest 5
,则编译时代码中的所有
defTest
实例将替换为
5

除了其他人的注释,众所周知,使用
#define
的错误很难调试,因为预处理器在编译器之前就掌握了这些错误。

理解#define指令和const指令之间的区别是很重要的,这两条指令的意义不同

const
const
用于从请求的类型生成一个对象,一旦初始化,该对象将是常量。这意味着它是程序内存中的一个对象,可以用作只读。 每次启动程序时都会生成该对象

#定义
使用
#define
以简化代码可读性和将来的修改。使用定义时,仅在名称后面屏蔽一个值。因此,使用矩形时,可以使用相应的值定义宽度和高度。然后在代码中,它将更容易阅读,因为将有名称而不是数字

如果以后决定更改宽度的值,则只需在“定义”中进行更改,而不必在整个文件中进行枯燥而危险的查找/替换。 编译时,预处理器将用代码中的值替换所有定义的名称。因此,使用它们不会浪费时间

首先,我发现不可能使用#define定义常量的类型,为什么

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

#define MY_INT_CONSTANT ((int) 12345)
第二,使用其中一种方法比使用另一种方法有什么好处

#define
定义一个宏,该宏甚至在编译开始之前就被替换
const
只是修改一个变量,这样当您试图更改它时,编译器将标记一个错误。在某些上下文中,您可以使用
#define
,但不能使用
常量(尽管我正在努力使用最新的叮当声找到一个)。从理论上讲,
const
会占用可执行文件中的空间并需要对内存的引用,但实际上这并不重要,编译器可能会对此进行优化

const
s比
#define
s对编译器和调试器更友好。在大多数情况下,这是在决定使用哪一个时应该考虑的首要问题。

只需考虑一个可以使用
#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文件中静态或全局作用域数组的大小,在中定义的除外

但是,对于整数常量,可以使用
枚举
。事实上,苹果几乎总是这样做。这具有
#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
,除非我有很好的理由不这样做。

我以前使用过#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#>)