Objective c MacOSX/iPhone上的C预处理器,使用'#';钥匙

Objective c MacOSX/iPhone上的C预处理器,使用'#';钥匙,objective-c,cocoa,cocoa-touch,c-preprocessor,stringification,Objective C,Cocoa,Cocoa Touch,C Preprocessor,Stringification,我正在看一些开源项目,我看到了以下内容: NSLog(@"%s w=%f, h=%f", #size, size.width, size.height) 尺寸符号前面的“#”的确切含义是什么?这是C字符串的某种前缀吗?这是宏定义的主体吗?然后可以使用#字符串化以下标识符,即打印“string”(不带代码)。要详细说明Dirkgente的答案,这看起来像是一个宏的实现,它接受NSSize(或类似)参数,并打印变量的名称(这就是#所做的;将变量名称转换为包含变量名称的字符串)然后转换其值。因此:

我正在看一些开源项目,我看到了以下内容:

NSLog(@"%s w=%f, h=%f", #size, size.width, size.height)

尺寸符号前面的“#”的确切含义是什么?这是C字符串的某种前缀吗?

这是宏定义的主体吗?然后可以使用
#
字符串化以下标识符,即打印“string”(不带代码)。

要详细说明Dirkgente的答案,这看起来像是一个宏的实现,它接受NSSize(或类似)参数,并打印变量的名称(这就是#所做的;将变量名称转换为包含变量名称的字符串)然后转换其值。因此:

NSSize fooSize = NSMakeSize(2, 3);
MACRO_NAME_HERE(fooSize);
宏将扩展到:

NSLog(@"%s w=%f h=%f", "fooSize", fooSize.width, fooSize.height);
并打印:

fooSize w=2.0 h=3.0

(与NSStringFromSize类似,但具有变量名)

字符串化运算符是
#
的正式名称。它接受其参数并用引号将其包围,使C字符串成为常量,根据需要转义任何嵌入的引号或反斜杠。它只允许在宏定义内使用,在常规代码中不允许使用。例如:

// This is not legal C
const char *str = #test

// This is ok
#define STRINGIZE(x) #x
const char *str1 = STRINGIZE(test);      // equivalent to str1 = "test";
const char *str2 = STRINGIZE(test2"a\"");  // equivalent to str2 = "test2\"a\\\"";
一个相关的预处理器操作符是标记粘贴操作符
##
。它需要两个标记并将它们粘贴在一起以获得一个标记。与字符串化操作符一样,它只允许在宏定义中使用,而不允许在常规代码中使用

// This is not legal C
int foobar = 3;
int x = foo ## bar;

// This is ok
#define TOKENPASTE(x, y) x ## y
int foobar = 3;
int x = TOKENPASTE(foo, bar);  // equivalent to x = foobar;

好奇…你不会碰巧手头有实际项目的名称和代码的位置,是吗?正如Dirkgente所说,肯定还有其他事情在进行,因为这甚至没有为我编译。它实际上来自Joe Hewitt的Three20项目。定义看起来像这样:#define TTLOGRECT(rect)\TTLOG(@%s x=%f,y=%f,w=%f,h=%f“,#rect,rect.origin.x,rect.origin.y,\rect.size.width,rect.size.height)