linux中#和## 用法

迷霧綠洲發表於2014-06-05

在linux核心中能看到很多的##    一般來講# 很容易理解 

一般來講有兩個用途

1. 在一些連線指令碼檔案裡作為註釋

也就是說#後面的都是註釋內容

2.c程式碼中做類似巨集定義的字串替換

舉個例子:

#define TEST(a) #a

printf("%s\n",TEST(tim)

執行結果就是

tim

這裡就可以看出來這個#的功能就是將後面的變數變成一個字串  



  但是##是什麼意思呢?

這裡就給出一個介紹

## 的左右有兩個

一,

做連線符 

顧名思義就是連線兩個符號

a1和 a##1 是一樣的  暫時沒想到這種用處的必要性  畢竟我並不是想吧簡單東西複雜化   讓程式碼難讀

#define TEST(x, y) x##y

printf("%d\n",TEST(1,2))

執行結果顯示

2

具體的是實現是 TEST(X,Y)=X##Y=XY

TEST(1,2)=1*2=2

二,這裡還有一種用法  不太常見

這裡有一個網上的例子  感覺挺典型的

#include <stdio.h>
#include <stdlib.h>

#define YYG_PRINT(fmt, arg...) printf(fmt, ##arg)

int
main()
{
 
  int m = 20, n = 90, l = 80; 
  char str[16] = "amstr";
  char ch = 'a';
  YYG_PRINT("m is %d n is %d l is %d str is %s ch is %c\n", m, n, l, str, ch);
  exit(0);

}

run result:

[root@UFO]# ./a.out 
m is 20 n is 90 l is 80 str is amstr ch is a


這就表明這個作用就是一個省略的意思   以為不可能列出所有的變數  就用這個符號和第一個變數代表了

最後給出Linux標準檔案中的說明

來自ISO-IEC1999檔案:
=====================================================================
6.10.3.1 Argument substitution
1 After the arguments for the invocation of a function-like macro have been identified,argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

2 An identifier _ _VA_ARGS_ _ that occurs in the replacement list shall be treated as if it were a parameter, and the variable arguments shall form the preprocessing tokens used to replace it.

6.10.3.2 The # operator
Constraints
1 Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.

Semantics
2 If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument. Each occurrence of white space between the argument’s preprocessing tokens becomes a single space character in the character string literal. White space before the first preprocessing token and after the last preprocessing token composing the argument is deleted. Otherwise, the original spelling of each preprocessing token in the argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character constants: a \ character is inserted before each " and \ character of a character constant or string literal (including the delimiting "
characters), except that it is implementation-defined whether a \ character is inserted before the \ character beginning a universal character name. If the replacement that results is not a valid character string literal, the behavior is undefined. The character string literal corresponding to an empty argument is "". The order of evaluation of # and ## operators is unspecified.

6.10.3.3 The ## operator
Constraints
1 A## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form of macro definition.

Semantics
2 If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.145)

3 For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token. Placemarker preprocessing tokens are handled specially: concatenation of two placemarkers results in a single placemarker preprocessing token, and concatenation of a placemarker with a non-placemarker preprocessing token results in the non-placemarker preprocessing token. If the result is not a valid preprocessing token, the behavior is undefined. The resulting token is available for further macro replacement. The order of evaluation of ## operators is unspecified.

4 EXAMPLE 
In the following fragment:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to
// char p[] = "x ## y";
The expansion produces, at various stages:
join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"
In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but
this new token is not the ## operator.
給一個下載的網站 http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=57853   不過是付費的哦 198瑞士法郎 摺合人民幣一千四  估計沒人下了   後面我會傳上來這個文件


相關文章