Chinaunix首页 | 论坛 | 博客
  • 博客访问: 577648
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2356
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

2012年(158)

我的朋友

分类: C/C++

2012-11-19 11:22:23

不常用的一个字符常量(character constant )用法


在C/C++中,如果错将"abcd"写成'abcd'依然是合乎语法的,猜想必然有其意图,但一直以来找不到其适用之处,也就作罢。今日需要定义一个int类型表示的字符数组,原本使用
const int fg = *(int*)"ABCD";
感觉有两点不是很好:
a. 需要强制类型转化,看起来有点复杂;
b. 可执行文件中必然需要包含一个"ABCD",理论上这其实是不需要的。
于是就尝试一下“字符常量”看看行不行,写成
'ABCD'
开始感觉不错,因为'A'是0x41,'B'是0x42,'C'是0x43,'D'是0x44,那么'ABCD'就是0x41424344
需要注意的是'ABCD'不一定等同于"ABCD"的前四位,在little-endian上
"ABCD"的前四位在内存的排布是       0x41, 0x42, 0x43, 0x44;
而'ABCD'即0x41424344在内存的排布是 0x44, 0x43, 0x42, 0x41;
所以在little-endian上等同于 *(int*)"ABCD" 的常量应当是 'DCBA'。
写成'DCBA'有点不习惯,所以最终还是改为*(int*)"ABCD"了 ^_^。

后记:晕了,晕了,对于如下代码:
printf( "0x%08X\n", '\x31\x32\x33\x34' );
printf( "0x%08X\n", '1234' );
在 windows2k + gcc3.4.2 中输出是 0x31323334 和 0x31323334;
而在windows2k + VC6.0 中输出是 0x34333231 和 0x31323334,不知道VC6在搞什么东东? :(

阅读(2973) | 评论(21) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-19 11:27:39

哈哈
都是高手阿!

网友评论2012-11-19 11:27:22

hengai
刚看到这个。
关于双字在内存中的存放顺序,确实是与CPU有关的。比如说,在Intel系列CPU上,存放一个WORD类型 0x99AA,在内存中实际上是 AA 99,如果按照二进制写入文件,也会是这个样子。
上次做到一个项目,因为设计是按照Intel系列的CPU来的,并且一个WORD中16位用前面的12位,剩下的4位又与下一个8位组成一个,比如在文件中存储的是 FF AA BB,那么取前面12位 FF A,按道理实际应该是 0x0AFF。但是因为在实际硬件单片机采用的CPU并不是Intel系列的,这个CPU存放一个WORD 0x99AA 在内存中就是按照 99 AA 来存放的,在调试程序中也算是吃尽了苦头:(

网友评论2012-11-19 11:27:08

xawi2000
TO 周星星和绅士也花心
晕...
你们说的答案不是一样的吗?
周星星大哥说
<<而'ABCD'即0x41424344在内存的排布是 0x44, 0x43, 0x42, 0x41;>>
而绅士也花心大哥说
<<'ABCD'的排列顺序(即到底是0x41424344还是0x44434241)和具体的实现相关,你应该用的VC吧。  

不知你用过FASM吗?在我的印象里它是把'ABCD'解释为0x44434241的。 >>
你们仔细看看你们说的不是一样吗?

其实这好像和编译器没有关系而和CPU有很大关系,
在80X86CPU中,字和双字的存放规则是高位字节(字)存放在高地址,
低位字节(字)存放在低地址,
所以在这个地方会逆序存放.

网友评论2012-11-19 11:26:50

RobBiE
我在RH Linux + GCC323+Intel X86下编译的结果是
const int a = *(int*)“ABCD";
const int b = 'ABCD';

printf("a=%X\n",a);
printf("b=%X\n",b);
的结果是
a=44434241
b=41424344

网友评论2012-11-19 11:26:38

longsan
界是嘛?