Препроцессор C на Mac OSX / iPhone, использование ключа"#"?


Я смотрю на некоторые проекты с открытым исходным кодом и вижу следующее:

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

Что именно означает ' # ' прямо перед символом размера? Это какой-то префикс дляC строк?

3 2

3 ответа:

Официальное название # - строковый оператор . Он берет свой аргумент и заключает его в кавычки, чтобы сделать строку 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;

Чтобы развить ответ dirkgently, это похоже на реализацию макроса, который принимает аргумент 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, но с именем переменной)

Является ли это телом макроопределения? Тогда # можно было бы использовать для строкования следующего идентификатора, т. е. для печати "string" (без кодов).