设为首页 加入收藏

TOP

c语言,有时莫名,有时奇妙----小话c语言(25) (三)
2014-11-23 23:39:54 来源: 作者: 【 】 浏览:46
Tags:语言 有时 莫名 奇妙 ---- 小话
c,%esp
0x00001f62 : pop %esi
0x00001f63 : pop %edi
0x00001f64 : pop %ebx
0x00001f65 : pop %ebp
0x00001f66 : ret

0x00001ef0 : push %ebp
0x00001ef1 : mov %esp,%ebp
0x00001ef3 : push %ebx
0x00001ef4 : push %edi
0x00001ef5 : push %esi
0x00001ef6 : sub $0x2c,%esp
0x00001ef9 : mov 0xc(%ebp),%eax
0x00001efc : mov 0x8(%ebp),%ecx
0x00001eff : mov $0x0,%edx
0x00001f04 : lea 0x1fa7,%esi
0x00001f0a : lea 0x1f94,%edi
0x00001f10 : mov $0x4,%ebx
0x00001f15 : movl $0x0,-0x10(%ebp)
0x00001f1c : mov %ecx,-0x14(%ebp)
0x00001f1f : mov %eax,-0x18(%ebp)
0x00001f22 : movl $0x1,-0x1c(%ebp)
0x00001f29 : mov %edi,(%esp)
0x00001f2c : movl $0x4,0x4(%esp)
0x00001f34 : mov %edx,-0x20(%ebp)
0x00001f37 : mov %ebx,-0x24(%ebp)
0x00001f3a : mov %esi,-0x28(%ebp)
0x00001f3d : call 0x1f6e
0x00001f42 : mov -0x1c(%ebp),%ecx
0x00001f45 : mov -0x28(%ebp),%edx
0x00001f48 : mov %edx,(%esp)
0x00001f4b : mov %ecx,0x4(%esp)
0x00001f4f : mov %eax,-0x2c(%ebp)
0x00001f52 : call 0x1f6e
0x00001f57 : mov -0x20(%ebp),%ecx
0x00001f5a : mov %eax,-0x30(%ebp)
0x00001f5d : mov %ecx,%eax
0x00001f5f : add $0x2c,%esp
0x00001f62 : pop %esi
0x00001f63 : pop %edi
0x00001f64 : pop %ebx
0x00001f65 : pop %ebp
0x00001f66 : ret 注意main+60位置,它直接将sizeof(i++)得到的数值4放入堆栈,并没有对i自增。

Q5: 为什么形如2["hello"]这样的表达式是什么意思?

[cpp]
#include

#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
#define PRINT_CH(charValue) printf(#charValue" is %c\n", (charValue));

int main(int argc, char **argv)
{
char ch = 2["hello"];
PRINT_CH(ch)

return 0;
}

#include

#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
#define PRINT_CH(charValue) printf(#charValue" is %c\n", (charValue));

int main(int argc, char **argv)
{
char ch = 2["hello"];
PRINT_CH(ch)

return 0;
}
A: 2["hello"]等同于"hello"[2], 又等同于 char *str = "hello"; str[2] . 但是,为什么?

因为编译器对于数组访问根本就采用指针加减的计算方法,即2["hello"] == *(2 + "hello"), "hello"是个字符指针, *(2 + "hello") == *("hello" + 2), 所以结论也就出来了。

Q6: 为什么一个整形数据用%f格式输出,结果改变了?

[cpp]
#include

#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
#define PRINT_F(floatValue) printf(#floatValue" is %f\n", (floatValue));

int main()
{
int d = 2;
PRINT_F(d)

return 0;
}

#include

#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
#define PRINT_F(floatValue) printf(#floatValue" is %f\n", (floatValue));

int main()
{
int d = 2;
PRINT_F(d)

return 0;
}
A: 原因在于printf分析%f格式时是从对应地址取出sizeof(float)个字节数据然后当成float格式输出,所以,一般情况下,输出都是错误的。

对于float内部的格式,IEEE 754标准写的很清楚,如果出现类似的问题,可以使用如下结构来简单地验证:


[cpp]
// IEEE 754 single floating number's format(intel little-endian mode)
typedef union
{
// float value
float f;

// intel bits mode that stands for float value
struct
{
unsigned int dot : 23; // low bits
unsigned int exp : 8; // middle bits
unsigned int sign : 1; // highest bit
}float_bit;
}float_value;

// IEEE 754 single floating number's format(intel little-endian mode)
typedef union
{
// float value
float f;

// intel bits mode that stands for float value
struct
{
unsigned int dot : 23; // low bits

首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇[面试]字符串专题 下一篇 C语言的一些特殊用法(#define)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: