linux下cpp字符串定义,linux下CPP的认识

linux中命令cpp是C Preprocessor的缩写,而不是C++那个后缀名称。

先来个关于printf奇怪用法的程序,这个程序是一个牛人写的,得过大奖,背景在此就不多说了,有闲情想了解的同志们去百度吧。在linux或unix平台上运行的结果是unix。

1main(){printf(&unix["\020%six\012\0"],(unix)["have"]+"fun"-0x60); }

下面是后者中的一些解答部分,本人才疏学浅,不敢在此发表自己见解。

因为:数组str[n] <==>(n)[str]

所以:(unix)["have"] + "fun" - 0x60 <==> "have"[1]+"fun"-0x60

即: 'a'+"fun"-0x60

因为:'a' = 0x61

所以:变为“fun”+1(隐含了同类型运算优先?)

因为:“fun”是个char型指针

所以:指向“un”

因为:\021是一个八进制数,代表第一个字符

所以:&1["\021unix\012\0"]<==>"unix\012\0"

因为:012是八进制的换行,\0是字符串结束

==所以:最终结果是unix==

代码示例过程:

1

2

3

4

5

6

7printf(&unix["/021%six/012/0"], (unix)["have"] + "fun" - 0x60);

==> printf(&1["/021%six/n/0"], (1)["have"] + "fun" - 0x60);

==> printf(&"/021%six/n/0"[1], "have"[1] + "fun" - 0x60);

==> printf("%six/n", 'a' + "fun" - 0x60);

==> printf("%six/n", 0x61 + "fun" - 0x60);

==> printf("%six/n", "fun" + 1);

==> printf("%six/n", "un");

理解这个程序需要知道数组的那个诡异但正确的用法,取地址,指针运算,UNIX/Linux编译器的熟悉程度(说白了就是要知道unix是一个已经预定义好的宏,见下文),当然还要知道十六进制和八进制表示方法。

1$cpp -dM /dev/null > macro-on-linux.txt

(其中的/dev/null可用C文件代替,添加选项-std=c99可得不同结果,详细用法请man cpp,实际结果请实践之)

macro-on-linux.txt文件中内容如下,这里删除了其中很多内容,其中unix藏在某个角落里,所以,上面的程序如果使用下面许多宏来代替,结果是一样的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34#define __DBL_MIN_EXP__ (-1021)

#define __FLT_MIN__ 1.17549435e-38F

#define __unix__ 1

#define __DBL_MIN_10_EXP__ (-307)

#define __FINITE_MATH_ONLY__ 0

#define __GNUC_PATCHLEVEL__ 0

#define __linux 1

#define __DEC32_EPSILON__ 1E-6DF

#define __unix 1

#define __LDBL_MAX_EXP__ 16384

#define __linux__ 1

#define __SIZEOF_LONG__ 4

#define __DECIMAL_DIG__ 21

#define __gnu_linux__ 1

#define __LDBL_HAS_QUIET_NAN__ 1

#define __GNUC__ 4

#define __DEC32_MIN__ 1E-95DF

#define __DBL_MAX_EXP__ 1024

#define __SIZEOF_SIZE_T__ 4

#define __NO_INLINE__ 1

#define __i386 1

#define __FLT_MANT_DIG__ 24

#define __VERSION__ "4.3.0 20080428 (Red Hat 4.3.0-8)"

#define unix 1

#define __i386__ 1

#define __SIZE_TYPE__ unsigned int

#define __ELF__ 1

#define linux 1

#define __FLT_MIN_10_EXP__ (-37)

#define __INTMAX_TYPE__ long long int

#define i386 1

#define __STDC__ 1

#define __PTRDIFF_TYPE__ int

#define __GNUC_GNU_INLINE__ 1

这些宏都是预定义好了的,就像__cpluscplus,__func__那些一样。网上说是编译器内建的,在具体文件是找不到的,我功底不深,不能从原理上解释,见谅。

个人觉得,如果想在linux下搞些开发,这些知识应该要懂一点,多知道一些总不是坏事。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值