• 一个宏定义引发的问题


    问题1:对与buffer宏定义的理解

         一些得到的基本结论:int型数据占有一个字的空间,char型数据占有一个字节的空间,并且char数据类型的定义是为ASCII字符表量身定制的

    对与buffer的理解:

    #define buffer ((char*) * (int far*)0x200)

    首先,复习对与基本宏定义的知识:对于# define pi (3.14)即pi = 3.14,在此我们首先应该认识到,最外面的括号仅仅是一个结构,来说明里面的内容是一个整体。

    下面来研究buffer究竟是什么:

    基本出发点:

    通过研究buffer[10] = 0;这个语句的汇编结构来认识buffer是什么

    图1

    通过汇编语句,我们发现,首先,我们的将偏移地址0x200变成了0x0000 0200.并不是我们想当然认为的ds:0200

    于是,我们首先对(int far *)0x200进行一个详细深入解读:

    1.*首先赋予了0x200这个数地址的含义

    2.()表明要对后面的数据进行强制性转换,但是转换成多少位?

    3 far则表明了要将后面的数据进行4位16进制数扩展成8位16进制数。所以前面变成了0000

    4 int 则表明了 0x0000 0200这个地址存放的整型数据。

    清楚了上面的结构来进一步研究,则*(…) 其实就相当于取0x00000200处的内容.再将这个内容作为地址,放的是一个char型数据,也就是说buffer代表的是一个地址常量。

    通过上面的汇编代码清晰的验证了这一点。 

    在此再次总结两个要点:1,括号里面的*用来赋予数据实际意义,来告诉我们后面的数据是一个地址,而不是一个数据。2括号外面的*用来告诉我们我们要取地址里面的内容,深入理解以上两点对于C语言指针的理解十分必要!

    其实又重新引入了这样一个问题:我们为什么大费周折的让buffer等于一个地址里面的内容,而不是直接等于这个地址?这样做的意义何在

    顺带思考buffer[0] = 0,&buffer,buffer = 0

    如果是承接上面的内容,那么无疑地,&buffer虽然本意是要取buffer的地址,但这样的操作是错误的,因为#define定义的是常量,而常量可以认为是标号,没有被分配给地址空间,编译的时候直接赋予相应的值,只有变量才有取地址的意义,同样的对buffer进行赋值同样不正确。而buffer[0] = 0这个操作是合理的,因为这是一个有意义的操作,是将ds:buffer+0处的内存赋值为0,是有确定的含义的。

    进一步,我们发现删除掉buffer  = (char*)malloc(20);

    发现程序编译连接仍让能够通过,说明了上述语句并不是赋值语句?

  • 相关阅读:
    进程与线程(二)(线程池)
    进程与线程(一)(基本定义和demo)
    SpringBoot的整合(二、整合redis)
    SpringBoot的整合(一、定时任务task)
    Thymeleaf的学习(二)(常用标签的使用方法)
    程序员常用单词词汇汇总
    程序员代码打字练习题库
    浅谈原型对象和原型链(源于学习整理笔记)
    JS中this的四种用法
    VS code自定义用户代码片段snippet
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/8012978.html
Copyright © 2020-2023  润新知