程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 宏定義運算符# ##

宏定義運算符# ##

編輯:關於C語言

宏定義可以包含兩個運算符:#和##。

 

#運算符將一個宏的參數轉換為字符串字面量。它僅允許出現在帶參數的宏的替換列表中。#運算符有大量的用途,這裡只來討論其中的一種。

假設我們決定在調試過程中使用PRINT_INT宏作為一個便捷的方法,來輸出一個整型變量或表達式的值。#運算符可以使PRINT_INT為每個輸出的值添加標簽。下面是改進後的PRINT_INT:

#define PRINT_INT(x) printf(#x " = %d\n", x)

x之前的#運算符通知預處理器根據PRINT_INT的參數創建一個字符串字面量。因此,調用

PRINT_INT(i/j);

會變為

printf("i/j" " = %d\n", i/j);

在C語言中相鄰的字符串字面量會被合並,因此上邊的語句等價於:

printf("i/j = %d\n", i/j);

 

##運算符可以將兩個記號例如標識符)“粘”在一起,成為一個記號。如果其中一個操作數是宏參數,“粘合”會在當形式參數被相應的實際參數替換後發生。考慮下面的宏:

#define MK_ID(n) i##n

當MK_ID被調用時比如MK_ID(1)),預處理器首先使用自變量這個例子中是1)替換參數n。接著,預處理器將i和1連接成為一個記號i1)。下面的聲明使用MK_ID創建了3個標識符:

int MK_ID(1), MK_ID(2), MK_ID(3);

預處理後聲明變為:

int i1, i2, i3;

##運算符不屬於預處理器經常使用的特性。實際上,想找到一些使用它的情況是比較困難的。為了找到一個有實際意義的##的應用,我們來重新思考前面提到過的MAX宏。如我們所見,當MAX的參數有副作用時會無法正常工作。一種解決方法是用MAX宏來寫一個max函數。遺憾的是,往往一個max函數是不夠的。我們可能需要一個實際參數是int值的max函數,還需要參數為float值的max函數,等等。除了實際參數的類型和返回值的類型之外,這些函數都一樣。因此,這樣定義每一個函數似乎是個很蠢的做法。

解決的辦法是定義一個宏,並使它展開後成為max函數的定義。宏會有唯一的參數type,它表示形式參數和返回值的類型。這裡還有個問題,如果我們是用宏來創建多個max函數,程序將無法編譯。C語言不允許在同一文件中出現兩個同名的函數。)為了解決這個問題,我們是用##運算符為每個版本的max函數構造不同的名字。下面是宏的顯示形式:

#define GENERIC_MAX (type)         \

type type##_max(type x, type y) \

{                                        \

   return x > y ? x : y;             \

}

請注意宏的定義中是如何將type和_max相連來形成新函數名的。

現在,假如我們需要一個針對float值的max函數。下面是如何使用GENERIC_MAX宏來定義函數:

GENERIC_MAX(float)

預處理器會將這行展開為下面的代碼:

float float_max(float x, float y) { return x > y ? x : y; }


本文出自 “孫轲的技術博客” 博客,請務必保留此出處http://sunke.blog.51cto.com/4812218/1290137

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved