C/ C++常量

原创 2013年12月03日 10:07:10

常用的常量可以分为:字面常量、符号常量、契约性常量、布尔常量、和枚举常量

1、字面常量

这种常量最为常见,例如直接出现的各种进制的数字、字符(‘’括住的单个字符)或者字符串(“”括住的一系列字符)等。实际上,只存在基本数据类型的字面 常量。

字面常量只能引用,不能修改,语言实现一般讲它保存在程序的符号表里,而不是一般的数据区中。符号表是“只读”的(这里不同于只读存储器,只是一种访问机制)。此外,初字符串以外,无法读取字面常量的地址。

例如 int *p = &5;                             //错误,不能读取字面常量的地址

         char *pChar   = "abdcef";       //正确,取字符串的地址。注意,这里不是给一个字符串变量,字符数组初始化

         char c[7]        = "abdcef";       //正确,一个字符数组初始化。

         *(pChar+2)= 'k';                 //错误,不能修改字面常量的内存单元

2、符号常量

存在两种符号常量:用#define定义的宏常量和用const定义的常量。由于#define是预编译伪指令,它定义的宏常量在进入编译阶段前就已经被替换为所代表的字面常量,因此宏常量在本质上是字面常量。

在c语言中,用const定义的常量其实是值不能修改的变量,因此会给它分配存储空间(外连接的);但是在c++中,const定义的常量要具体情况具体对待:对于基本数据类型的常量,编译器会把它放到符号表中而不分配存储空间;而ADT/UDT(一个协议的参考实现)的const对象则需要分配内存空间(大对象)。还有一些情况也要分配存储空间,例如强制声明为extern的符号常量或者取符号常量的地址等操作,都将强迫编译器为这些常量分配内存空间,以满足用户需求。

可以对一个const常量取地址:对于基本数据类型的const 常量,编译器会重新在内存中创建一个它的拷贝,通过其地址访问的是这个拷贝而非原始的符号常量;而对于构造类型的const 常量,实际上它是编译时不允许修改的变量,因此如果能绕过编译器的静态类型安全检查机制,就可以在运行时修改其内存单元:

例如:

const long lng   = 10;

long *pl = (long*)&lng;                            //取常量的地址

*pl = 1000;                                             //迂回修改

cout<< *pl <<endl;                                  //1000,修改的拷贝的内容

cout<< lng<<endl;                                  //10,原始常量没有变

class Interger{

public:

        Interger():m_lng(100){}

        long m_lng;

}

const  Interger int_1;               

Interger *pInt = (Interger*)&int_l;            //去除常数属性

pInt->m_lng = 1000;                                   //迂回修改

cout<< pInt->m_lng <<endl;                       //1000,修改const对象

cout<< int_1.m_lng <<endl;                        //1000,迂回修改成功

3、契约性常量

用const修饰函数返回值,如果给“指针传递”的函数返回值加const那么函数返回值是一种契约性常量,不能直接被修改,并且该返回值只能被赋值给加const修饰的同类型指针(除非强制转型)。例如:

const char *GetString(void);

char *str = GetString();                         //错误;

const char* str = GetString();                //正确;

//=======================================================================

//测试环境 windowsxp,vc6.0

/*int Stringlength(const char *s)*/

#include<iostream>
#include <stdlib.h>

using namespace std;

int Stringlength(const char *s)
{

 cout<<s<<endl;     //输出值s并非字符串地址,而是字符串,注意C++/C默认char* 表示字符串
 if(s == NULL) exit(1);

 int length = 0;

 char *base = (char *)s;      //这里是将s的类型强制转换了,如果不强制转换应该为const char *base = s;

 while((*base++) != ' \0 ' )  length++;
 return length;
}
void main()
{
 char *ch = "Hello,c++ world!";     //取字符串常量的地址
 cout<<ch<<endl;                       //输出的是整个字符串
 cout<<*ch<<endl;                      //输出的是字符串的首个字符
 int len = Stringlength(ch);
 cout<<len<<endl;
}

运行结果:

在“引用传递”时,也存在契约性常量:例如

void ReadValue(const int& num)

{

cout<<num;

int main()

{

      int n = 0;

      ReadVaule(n);           //契约性常量,n被看做是const

}


4,枚举常量

enum Gigantic

{

    SMALL = 10,

    GIGANTIC = 100000000

};

5、布尔常量

布尔常量只有两个 false和true,大小写不敏感。

总结:

        const与#define都可以用来定义常量,但是前者有更多优点:

(1)const有数据类型,而宏常量没有。编译器可以对前者进行静态安全检查;

(2)有些集成化调试工具可以对const常量进行调试,而对宏常量不可以

(3)被const修饰的东西都受到c++/c语言实现的静态安全检查机制的强制保护,可以预防以外修改。


相关文章推荐

C/C++堆区、栈区、常量区、静态数据区、代码区详解

转自:http://blog.csdn.net/subo86/article/details/4814874 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部...

C/C++定义常量#define与const比较

1。const定义常量是有数据类型的,而#define宏定义常量却没有。 这样const定义的常量编译器可以对其进行数据静态类型安全检查,而#define宏定义的常量却只是进行简单的字符替换,没有类...

C/C++编译程序的内存分配(栈,堆,全局区,文字常量区,程序代码区)

栈: 由程序自动分配和释放,非全局变量或静态变量,以及非malloc申请的空间,都在栈中。 堆: 由程序员申请的内存空间: malloc, 在堆中申请的内存需要自己释放,malloc与free成对 全...

开门篇:C/C++中的多字节字符、转义字符、三字母词,顺带提及字符串常量

估计转义字符大家都听过,多字节字符通过微软常用的wchar_t也都了解过,三字母词是神马?不知道吧?之写这篇博客前我也不知道。因为编程中很少用得到。 但是你仍然需要了解它。因为总有些时候会遇到让你困惑...

C/C++定义全局变量/常量几种方法的区别

摘要:使用全局变量最稳妥的方法,就是在common.h中声明,在common.cpp中定义;其他文件include “common.h”来使用全局变量 在讨论全局变量之前我们先要明白几个基本的概念:...

c/c++中extern、static、const的用法及全局变量/常量

基本概念 编译单元 由.cpp(.c)文件及include的.h文件构成一个编译单元(把头文件内容复制到cpp中),在编译时,编译为一个.obj文件,obj文件里包含了变量存储的相对地址。 声明与定...
  • lwwl12
  • lwwl12
  • 2017年07月28日 13:06
  • 132

关于C/C++的内存区划分:堆、栈、自由存储区、全局/静态存储区和常量存储区

From:http://www.cnblogs.com/JCSU/articles/1051579.html 一. 在c中分为这几个存储区 1.栈 - 由编译器自动分配释放 2.堆 - ...

C/C++中,内存中数据存储分成4个区:堆、栈、全局/静态存储区和常量存储区。

栈(stack),就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。      堆(heap),一般由程序员分配释放,若程序员不释放,程序...
  • zifuttt
  • zifuttt
  • 2012年04月01日 10:29
  • 3470

C++/C 常量

常用的常量可以分为:字面常量、符号常量、契约性常量、布尔常量、和枚举常量 1、字面常量 这种常量最为常见,例如直接出现的各种进制的数字、字符(‘’括住的单个字符)或者字符串(“”括住的一系...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C/ C++常量
举报原因:
原因补充:

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