Что делает "#" в C?

У меня есть программа.

#include <stdio.h>

#define f(a,b) a##b
#define g(a)   #a
#define h(a) g(a)

int main()
{
      printf("%s\n",h(f(1,2)));
      printf("%s\n",g(f(1,2)));
      return 0;
}

Эта программа работает правильно и дает результат как:

12
f(1, 2)

Я не понимаю, как компилятор дает этот вывод.

Какова функция # в a##b и #a?

Ответ 1

Позвольте мне сломать вам:

#define f(a,b) a##b //2 this macro is evaluated first with a = 1 and b = 2 it concatenates them and returns 12
#define g(a)   #a //4 g turns 12 into "12" (string)
#define h(a) g(a) //3 back to h which now has a = 12 and call g()

int main()
{
      printf("%s\n",h(f(1,2)));//1 printf calls the macro h() and gives it the macro f() as an argument 
      printf("%s\n",g(f(1,2)));// g here turns f(1,2) into "f(1,2)" (string)
      return 0;
}

Ответ 2

## объединяет два токена вместе.

Важно то, что он может использоваться только в препроцессоре.

Оператор # используется для тонирования токенов.

Например:

#(a ## b), который становится #ab, который становится "ab"

Итак, h (f (1,2)) становится "f (1,2)"

Также обратите внимание, что # и ## - два разных оператора.

Оператор препроцессора ## обеспечивает способ объединения фактических аргументы во время макрорасширения. Если параметр в замене текст смежна С##, параметр заменяется фактическим аргумент ## и окружающее пустое пространство удаляются, а результат повторно сканируется.

Также ознакомьтесь с этой Конкатенацией.

От здесь: -

Stringification

Иногда вам может потребоваться преобразовать аргумент макроса в строку постоянная. Параметры не заменяются внутри строковых констант, но вы Вместо этого вместо можно использовать '#' препроцессор. Когда параметр макроса используется с ведущим "#", препроцессор заменяет его буквальный текст фактического аргумента, преобразованный в константу строки. В отличие от замены нормального параметра аргумент не сначала макроскладывается. Это называется строкой.

Невозможно объединить аргумент с окружающим текстом и соединить все это вместе. Вместо этого вы можете написать ряд смежных строковые константы и строгие аргументы. Препроцессор будет замените строковые аргументы на строковые константы. С компилятор затем объединит все соседние строковые константы в один длинная строка.

Ответ 3

## называется оператором "token-pasting" или "слиянием", который может использоваться для объединения двух токенов для формирования фактического аргумента.

# называется Stringing Operator, который "преобразует макро параметры в строковые литералы без расширения определения параметра".

Обычно они называются операторами препроцессора. Существует еще несколько таких операторов препроцессора. За дополнительной информацией обратитесь к операторам препроцессора в C (http://msdn.microsoft.com/en-us/library/wy090hkc.aspx).


Также проверьте http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx и раздел "см. также" на этой странице для получения дополнительной информации о препроцессоре C.