• 关于浮点数和字面值常量 的使用—— 学习汇编的重要性


    VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
    对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
    (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
    想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
    从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
    指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

     float a = 1.0f;
        cout << (int)a << endl;
        cout << &a << endl;
        cout << (int&)a << endl;
        cout <<boolalpha<<((int)a ==(int&)a) << endl;
        
        float b = 0.0f;
        cout << (int)b << endl;
        cout << &b << endl;
        cout << (int&)b << endl;
        cout <<boolalpha<<((int)b ==(int&)b) << endl;
    输出如下:
    1
    001FFBC0
    1065353216
    false
    0
    001FFBB4
    0
    true

    解答:(int&)a就是将a变量用int类型来解释

    float a = 1.0f,在计算机中存储的值为0x3F800000,对应的十进制的值就是065353216

    float b = 0.0f,在计算机中存储的值为0x00000000,对应的十进制的值就是000000000

    (int)a实际上是以浮点数a为参数构造了一个整型数,该整数的值是1,(int&)a则是告诉编译器将a当作整数看(并没有做任何实质上的转换)。因为1以整数形式存放和以浮点形式存放其内存数据是不一样的,因此两者不等。对b的两种转换意义同上,但是0的整数形式和浮点形式其内存数据是一样的,因此在这种特殊情形下,两者相等(仅仅在数值意义上)。 
    注意,程序的输出会显示   (int&)a=1065353216,这个值是怎么来的呢?前面已经说了,1以浮点数形式存放在内存中,按ieee754规定,其内容为   0x0000803F(已考虑字节反序)。这也就是a这个变量所占据的内存单元的值。当(int&)a出现时,它相当于告诉它的上下文:“把这块地址当做整数看待!不要管它原来是什么。”这样,内容0x0000803F按整数解释,其值正好就是1065353216(十进制数)。 
    通过查看汇编代码可以证实“(int)a相当于重新构造了一个值等于a的整型数”之说,而(int&)的作用则仅仅是表达了一个类型信息,意义在于为cout < <及==选择正确的重载版本。 

    #include<stdio.h>
     
    int main()
    {   
        const char str1[] = "abc";
        const char str2[] = "abc";
         
        const char *p1 = "abc";
        const char *p2 = "abc";
        return 0;
    }

    在vs下跑程序,分别添加监视,str1,str2,p1,p2. 为什么str1,str2不相同,而p1,p2相同?以下为监视结果:
    + str1 0x0017fd40 "abc" const char [4]
    + str2 0x0017fd34 "abc" const char [4]
    + p1 0x0101573c "abc" const char *
    + p2 0x0101573c "abc" const char *

    const char str1[] = "abc";
        const char str2[] = "abc";
        
    这是在栈上分配的  从高地址到低地址分配  当然不相等
    而const char *p1 = "abc";
        const char *p2 = "abc";
    这两个指针指向的是同一地址   编译器认为p1指向的“abc”和p2指向的“abc”是属于同一常量

  • 相关阅读:
    mysql密码重置
    利用python生成定制二维码
    totnado前后端分离跨域设置
    supervisor详解
    redis持久化常识和配置
    redis数据的备份与恢复
    supervisor下更换源文件报错
    EF5框架封装
    IEnumerable和IEnumerator 详解
    心宽,路自宽
  • 原文地址:https://www.cnblogs.com/limera/p/5405619.html
Copyright © 2020-2023  润新知