网上看到的一个笑死人不偿命的段子:
a lot of people don't know this: C actually lets you do arithmetic with mixed types, much like JavaScript:
// a lot of people don't know this:
// C actually lets you do arithmetic with mixed types, much like JavaScript:
#include <stdio.h>
int main() {
puts("-0.5" + 1);
return 0;
}
编译,运行
$ gcc mixedtype.c
$ ./a.out
0.5
笑翻在地。
这是一个只有用过C语言的人能懂的段子,为什么会得到这个结果呢?当然不是因为C也可以混合计算了,而是因为,这个加法实际是"-0.5"的地址+1,也就是去掉了符号位。
实际验证一下:man ascii可知"-0.5"的ascii码如下表:
char | ASCII | Hex |
---|---|---|
- | 45 | 0x2d |
0 | 48 | 0x30 |
. | 46 | 0x2e |
5 | 53 | 0x35 |
查看内存,可找到字符串对应的地址:
(gdb) x/32bx 0x5555555546e4
0x5555555546e4: 0x2d 0x30 0x2e 0x35 0x00 0x00 0x00 0x00
0x5555555546ec: 0x01 0x1b 0x03 0x3b 0x38 0x00 0x00 0x00
0x5555555546f4: 0x06 0x00 0x00 0x00 0x14 0xfe 0xff 0xff
0x5555555546fc: 0x84 0x00 0x00 0x00 0x34 0xfe 0xff 0xff
(gdb) print ((char*)0x5555555546e4)
$3 = 0x5555555546e4 "-0.5"
+1就是地址+1,也就是从0x5555555546e4变成0x5555555546e5,就得到0.5了:
(gdb) print (char*)(0x5555555546e4+1)
$4 = 0x5555555546e5 "0.5"
在C语言中,函数内直接使用的“字符串”,是分配在栈(stack)中的,生命周期随着函数的结束而结束。对其进行加减法操作,都是对其所在地址的指针移动操作。
网友评论