新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → C++关键字(static/register/atuo/extern/volatile/const)释疑[ZT] 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 9612 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: C++关键字(static/register/atuo/extern/volatile/const)释疑[ZT] 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     longshentailang 帅哥哟,离线,有人找我吗?
      
      
      威望:1
      等级:计算机学士学位
      文章:325
      积分:2990
      门派:XML.ORG.CN
      注册:2006/6/20

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给longshentailang发送一个短消息 把longshentailang加入好友 查看longshentailang的个人资料 搜索longshentailang在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看longshentailang的博客楼主
    发贴心情 C++关键字(static/register/atuo/extern/volatile/const)释疑[ZT]

    C++关键字(static/register/atuo/extern/volatile/const)释疑[ZT]

    下面关于C++的几个关键字是经常和我们打交道的而我们又经常对这些含糊不清的,本文根据自己的学习体会作以总结,以期达到真正理解和活用的目的。
    static

    l         静态变量作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0,使用时可改变其值。

    l         静态变量或静态函数,即只有本文件内的代码才可访问它,它的名字(变量名或函数名)在其它文件中不可见。

    l         在函数体内生成的静态变量它的值也只能维持

    int max_so_far( int curr )//求至今(本次调用)为止最大值

    {

       static int biggest; //该变量保持着每次调用时的最新值,它的有效期等于整个程序的有效期

       if( curr > biggest )

          biggest = curr;

       return biggest;

    }

    l         在C++类的成员变量被声明为static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。

    l         类的静态成员变量必须在声明它的文件范围内进行初始化才能使用,private类型的也不例外。如,

                   float SavingsAccount::currentRate = 0.00154;

       (注:currentRate是类SavingsAccount的静态成员变量)

    register

    l         用register声明的变量称着寄存器变量,在可能的情况下会直接存放在机器的寄存器中;但对32位编译器不起作用,当global optimizations(全局优化)开的时候,它会做出选择是否放在自己的寄存器中;不过其它与register关键字有关的其它符号都对32位编译器有效。
    auto

    l         它是存储类型标识符,表明变量(自动)具有本地范围,块范围的变量声明(如for循环体内的变量声明)默认为auto存储类型。
    extern

    l         声明变量或函数为外部链接,即该变量或函数名在其它文件中可见。被其修饰的变量(外部变量)是静态分配空间的,即程序开始时分配,结束时释放。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义(实现)。在文件内声明一个变量或函数默认为可被外部使用。

    l         在C++中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前Microsoft C/C++仅支持”C”转换标记,来支持C编译器链接。使用这种情况有两种形式:

    u       extern “C” 声明语句

    u       extern “C” { 声明语句块 }
    volatile

    l         限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下:

    int volatile nVint;

           这样的声明是不能达到最高效的,因为它们的值随时会改变,系统在需要时会经常读写这个对象的值。       只常用于像中断处理程序之类的异步进程进行内存单元访问。

    当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指

    令刚刚从该处读取过数据。而且读取的数据立刻被保存。

    例如:

    volatile int i=10;
    int a = i;
    。。。//其他代码,并未明确告诉编译器,对i进行过操作
    int b = i;

    volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的

    汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间

    的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果

    i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问

    注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编

    代码,测试有无volatile关键字,对程序最终代码的影响:

    首先用classwizard建一个win32 console工程,插入一个voltest.cpp文件,输入下面的代码:

    #include <stdio.h>
    void main()
    {
    int i=10;
    int a = i;

    printf("i= %d\n",a);
            //下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道
    __asm {
      mov         dword ptr [ebp-4], 20h
    }

    int b = i;
    printf("i= %d\n",b);
    }

    然后,在调试版本模式运行程序,输出结果如下:
    i = 10
    i = 32

    然后,在release版本模式运行程序,输出结果如下:
    i = 10
    i = 10

    输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。

    下面,我们把 i的声明加上volatile关键字,看看有什么变化:


    #include <stdio.h>
    void main()
    {
    volatile int i=10;
    int a = i;

    printf("i= %d\n",a);
    __asm {
      mov         dword ptr [ebp-4], 20h
    }

    int b = i;
    printf("i= %d\n",b);
    }

    分别在调试版本和release版本运行程序,输出都是:
    i = 10
    i = 32

    这说明这个关键字发挥了它的作用!

    ////////////////////////////////////////////////////////////////////
    const

    l         const所修饰的对象或变量不能被改变,修饰函数时,该函数不能改变在该函数外面声明的变量也不能调用任何非const函数。在函数的声明与定义时都要加上const,放在函数参数列表的最后一个括号后。

    l         在C++中,用const声明一个变量,意味着该变量就是一个带类型的常量,可以代替#define,且比#define多一个类型信息,且它执行内链接,可放在头文件中声明;但在C中,其声明则必须放在源文件(即.C文件)中,在C中const声明一个变量,除了不能改变其值外,它仍是一具变量,如

    const int maxarray = 255;

    char store_char[maxarray];  //C++中合法,C中不合法

    l         const修饰指针时要特别注意。例:

    char *const aptr = mybuf;  // 常量指针

    *aptr = 'a';       // Legal

    aptr = yourbuf;    // Error

    const char *bptr = mybuf;  // (指针bptr)指向常量数据

    *bptr = 'a';       // Error

    bptr = yourbuf;    // Legal

    l         const修饰成员函数时不能用于构造和析构函数。


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/11/2 21:18:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的

    汇编代码会重新从i的地址读取数据放在b中。而优化做法是,由于编译器发现两次从i读数据的代码之间

    的代码没有对i进行过操作,它会自动把上次读的数据放在b中。而不是重新从i里面读。这样以来,如果

    i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问

    明白了~~~~

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2006/11/6 9:43:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/10 13:16:38

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    46.875ms