전처리 연산자 #은 매크로 정의에서 형식 매개변수를 문자열화 한다.

가령 다음과 같이 매개변수를 갖는 매크로를 정의하면,

#define print(a) printf(#a)       //  매개변수로 들어온 녀석을 " 로 감싸버려서 치환해준다.


이제  print(Hello world!\n);   는   printf("Hello world!\n"); 으로 바뀐후 컴파일된다.


몇가지 간단한 응용을 생각해 볼 수 있다.


예1.
#define love(a,b) printf(#a " loves " #b)
이렇게 쓰면, love 가 받는 두개의 인자가 각 각 " " 묶여서 치환되고, printf 내에 " " 세개가 나란히 들어가게 되는데,
나열된 문자열상수는 결합되기 때문에 문자열 a와 b가 포함된 문자열을 인쇄한다.

가령, love(James,Lisa); 라는 코드는, printf("James loves Lisa"); 로 바뀐다.

예2.
#define print(a) printf(#a " = %d\n",a)
이렇게 쓰면, 정수형변수를 받아서, 그것의 이름과 십진정수값을 포함한 문자열을 출력하는 간단한 매크로가 만들어진다.

-------------------------------------------------------------------------------------------

연산자 ## 은 토큰을 결합하는데 사용한다.

가령 x ## i 는 x와 i 라는 두개의 토큰을 하나의 토큰 xi 로 만들어 준다. 이것은, 각각의 토큰 x 와 i 가 파라미터로 쓰이면서 하나의 토큰 xi 를 만들수 있게 해준다.

예. #define U(a,i) a##i    // 코드에서 U(x,1) 라고 썼다면, 그부분을 x1 로 대체한다.
     #define F(i) f##i   


#와 ##을 사용하여, 배열과 인덱스를 파라미터로 받아 출력하는 매크로를 다음과 같이 만들수도 있다.

#define arrprint( arr, index ) printf(#arr "[%d] = %d\n" , index, arr ## [index] )

가령 int a[3]={10,15, 22} ; 라고 있을때,
       arrprint(a,2);   라는 코드는 다음의 코드로 치환된다.

      printf("a" "[%d] = %d\n",2,a[2]);

그런데, 연속된 문자열이 접합되므로,       printf("a[%d] = %d\n",2,a[2]);  이 된다.