我的一个长久以来的误区,关于C

原创 2007年09月19日 22:46:00
 
我的一个长久以来的误区,关于C
 
很久以前学C语言的时候就知道了#define,它可以用来定义宏,宏至少有两个作用,一是作为常量,二是作为很短的函数或代码段。后来学到C++,提到了取代#define的两个关键字,一是const,一是inline。上大一的时候学校也开了C语言课,后面有一章是介绍C++,其中涉及到C++的两个关键字,分别是const和volatile,前者用来定义常量,后者用来定义会被其他地方修改的变量。由此我得到一个认识,就是const和volatile并不被C支持,而是C++才具有的关键字。
但昨天和讨论中我才惊讶的发现,原来这两个关键字其实也被C语言支持。例如,如下代码在TC 2.0可以被正常编译并工作的很好:
const int a = 1;
volatile int b = 2;
其实,C支持这两个关键字也是理所当然的。对于volatile来说,在早期使用C语言编写中断服务程序是很常见的,如果一个变量会在中断服务程序中被修改,那么它应该被声明为volatile,这样就告诉编译器,不能对这个变量的值做任何假设,每次使用时必须重新获取,因为它很有可能已经在中断服务程序中被修改了;对于const来说,它告诉编译器被它所声明的量的值不可修改,虽然在运行时这并不能被保证,但至少在编译阶段的显式修改是可以被发现的。对此,不难发现C的const和C++的const是有所不同的,这里可以做一组实验来验证:
#include <stdio.h>
void main()
{
       const int a = 1;
       int* pa = (int*)&a;
       *pa = 2;
       printf("%d", a);
}
分别使用VC6和TC2编译这段代码,得到的结果是不同的。TC2(C语言)得到的结果为2,这很好理解,虽然a被声明为const,但我们还是可以通过指针来改变它的值;VC6(C++语言)得到的结果为1,这是因为在C++中const有两层含义,一是用来声明值不可改变的量,这等同于C语言中的意义,二是用来声明可以在编译期确定其值的量,这类似于C语言的#define。如果一个量的值确实可以在编译期算出来,那么编译器将尽可能对其进行优化,在之后用到此量的地方都直接用其值来代替,从而减少对内存的访问,以达到和#define相同的效率。
正是因为多了这一层含义,C++的教材上才说使用const和inline可以取代#define,不仅在功能上,而且是在性能上。假如C++的const仍然只具有和C语言的const一样的能力,那么它在性能上仍不能取代#define。看来,我当年读到的那本教材并没有把这个问题完全说清楚。
结论:
1 C语言支持const和volatile
2 C语言的const只保证量值不被显式修改,不进行性能上的优化
 

相关文章推荐

我的一个长久以来的误区,关于C

我的一个长久以来的误区,关于C   很久以前学C语言的时候就知道了#define,它可以用来定义宏,宏至少有两个作用,一是作为常量,二是作为很短的函数或代码段。后来学到C++,提到了取代#...

长久以来对设计模式的重大误解

  • 2008年10月27日 13:09
  • 223KB
  • 下载

C-C++ 常见误区

  • 2013年08月13日 13:31
  • 3KB
  • 下载

C 清空输入缓冲区,以及fflush(stdin)的使用误区和解决方法

对C 语言初学者来说,fflush(stdin)函数被解释为会清空输入缓冲区的一个系统函数,这是一个曾经几乎对过一半的说法,随着计算机科学的进步,在学习的过程中的逐步完善,将fflush(stdin)...

C/C++语言误区之:fflush(stdin)

1.为什么fflush(stdin) 是错的  首先请看以下程序:   #include   int main( void )   {       int i=1;       whil...

使用javah生成C/C++头文件的误区

出处:http://www.cnblogs.com/charley_yang/archive/2011/03/13/1983038.html 使用Javah 可以获取您的 Java 源文件并生成...
  • zwxtfqd
  • zwxtfqd
  • 2015年10月22日 12:33
  • 216

C/C++ 面试题之新手误区

1.内存泄漏的问题 现象:很多新手经常会碰到这样的问题:用new动态分配一个 char *类型,最后加上delete后就会报错,不加上delete就不会报错。 实例: #include using...

化解一个误区,其实switch和enum是可以很方便配合使用的

enum switch case label must be the unqualified name of an enumeration constant或 错误: 枚举 switchcase 标签...

JBoss 系列八十四: 使用 JMS session 时的一个误区

概述 我们通常使用 JMS session 连接JMS消息队列,创建生产者往队列发送消息,或创建消费者从队列消费消息,BaseJMSTaskServer.java中的start()方法就是一个例子,...

MySQL中关于join的一个误区

我估计应该有一部分MySQL的小白用户跟我一样,以为 A left join B on a.key=b.key and condition 等价于 A left join B on a.key = b...
  • itjin45
  • itjin45
  • 2014年11月18日 08:35
  • 225
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:我的一个长久以来的误区,关于C
举报原因:
原因补充:

(最多只允许输入30个字)