C++/C常量

转载 2013年12月03日 12:22:03

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

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;
}

C++/C 常量 - 默默 - zhaoweizhuanshuo 的博客

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

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++ 宏定义与常量的区别,仔细了想了想,并没有答起(尴尬),这次就简单总结一下C++宏常量与常量的区别吧。 1. 宏定义 宏定义是C语言提供的三种预处理中的一种...
  • t894690230
  • t894690230
  • 2016年01月29日 13:10
  • 2026

C++中 常量引用、指向常量的指针、常量指针的区别

先初步了解引用、指针的一些注意事项。 引用并非对象 引用必须初始化 引用只能绑定在对象上,而不能与字面值或某个表达式的计算结果绑定在一起 类型要严格匹配 int &a = 10; ...
  • Rueing839
  • Rueing839
  • 2015年09月13日 17:11
  • 1488

C和C++中全局变量,局部变量,静态变量和常量

C/C++中常量,静态变量,全局变量和局部变量的区别和作用。把局部变量改变为静态局部变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态全局变量是改变了它的作用域, 限制了它的使用范围。...
  • zcyzsy
  • zcyzsy
  • 2016年08月14日 22:54
  • 1644

C/C++中的常量指针与指针常量

常量指针 常量指针是指向常量的指针,指针指向的内存地址的内容是不可修改的。 常量指针定义“const int *p=&a;”告诉编译器,*p是常量,不能将*p作为左值进行操作。但这里的指针p还是一个变...
  • u014744118
  • u014744118
  • 2016年03月30日 23:22
  • 565

C++静态常量探究

c++静态常量详解。c++静态常量应用场景及使用方法。 今天想,如果我希望一个类中,具有一些常量,但是不希望常量在各个类的对象中有多份拷贝(占用不必要的内存)。想应该如何定义。 需求细化: 需求1、常...
  • hzhsan
  • hzhsan
  • 2015年05月22日 13:18
  • 1657

c/c++里的 堆区 栈区 静态区 文字常量区 程序代码区

任何一个运行的程序,在内存中都被分为代码区和数据区2部分,而数据区又被分为静态存储区,栈区等等。一个由c/c++编译的程序占用的内存分为以下几个部分 1,栈区(stack)-由编译器自动分配释放,存...
  • xiaxuiau
  • xiaxuiau
  • 2015年03月18日 21:58
  • 912

【C++】基本的数据类型(一) 整型常量的表示方法

很长时间没有更新了,不是没有看书,而是实在看得有点晕了··  第一章的结尾讲的是class(类)的应用,由于网站没有打开,所以就放弃了。还好第二章介绍的是类的编写,这样可以更好的掌握类的本质了。 ...
  • altairdipper
  • altairdipper
  • 2014年05月26日 13:50
  • 880

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

转自:http://blog.csdn.net/subo86/article/details/4814874 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部...
  • u012942555
  • u012942555
  • 2015年10月03日 08:01
  • 2186

详解指针常量和常量指针(C、C++工程师面试题)

常量指针:指向常量的指针。 指针本身可以改变,可以再次指向另外的对象。 不能通过指针修改其所指向的对象的值。 指针常量:指针类型的常量。 指针本身的值不能改变,即不能再指向另外的对象。 可以修改指针...
  • rl529014
  • rl529014
  • 2016年06月08日 18:35
  • 1012

常量指针、指针常量、C++类型转换

一、const应用 1.const关键字,他后面内容的不可修改,一般来说,其修饰的变量不可再进行赋值操作; 2.常量指针 int a = 3; int b = 4; const int* pt = &...
  • zz460833359
  • zz460833359
  • 2015年09月10日 22:05
  • 769
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++/C常量
举报原因:
原因补充:

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