红联Linux门户
Linux帮助

linux中#和##用法

发布时间:2016-01-19 10:48:01来源:linux网站作者:末日狂奔

在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.linuxdiyf.com/linux/17472.html