`

const 关键字

阅读更多

const  常量

 常变量:  const 类型说明符 变量名

  常引用:  const 类型说明符 &引用名

  常对象:  类名 const 对象名

  常成员函数:  类名::fun(形参) const

  常数组:  类型说明符 const 数组名[大小]    

  常指针:  const 类型说明符* 指针名 ,类型说明符* const 指针名

用法1:常量

  取代了C中的宏定义,声明时必须进行初始化  

用法2:指针和常量
    使用指针时涉及到两个对象:该指针本身和被它所指的对象

    所以出现在 * 之前的const是作为基础类型的一部分:
char *const cp; //到char的const指针
char const *pc1; //到const char的指针
const char *pc2; //到const char的指针(后两个声明是等同的)

用法3:const修饰函数传入参数

void Fun( const A *in); //修饰指针型传入参数
void Fun(const A &in); //修饰引用型传入参数

用法4:修饰函数返回值

 

用法5:const修饰成员函数(c++特性)

 

(一). 常量与指针

    const int *m1 = new int(10);        //const在*之前 所以m1是 const char* 常量指针 即不能通过m1修改他指向的内容

    int* const m2 = new int(20); //const在*之后 所以m1 是int*类型 常量   指针常量  (即,不能让m2指向其他的内存模块)

 

(二):常量与引用

    常量与引用的关系稍微简单一点。因为引用就是另一个变量的别名,它本身就是一个常量。 也就是说不能再让一个引用成为另外一个变量的别那么他们只剩下代表的内存区域是否可变

  int i = 10;

    // 正确:表示不能通过该引用去修改对应的内存的内容。

    const int& ri = i;

    // 错误!不能这样写。

    int& const rci = i;

 

由此可见,如果我们不希望函数的调用者改变参数的值。最可靠的方法应该是使用引用。下面的操作会存在编译错误:

    void func(const int& i)

    {

    // 错误!不能通过i去改变它所代表的内存区域。

    i = 100;

    }

 

但是,有必要深入的说明以下。在系统加载程序的时候,系统会将内存分为4个区域:堆区 栈区全局区(静态)和代码区。从这里可以看出,对于常量来说,系统没有划定专门的区域来保护其中的数据不能被更改。也就是说,使用常量的方式对数据进行保护是通过编译器作语法限制来实现的。我们仍然可以绕过编译器的限制去修改被定义为“常量”的内存区域。看下面的代码:

    const int i = 10;

    // 这里i已经被定义为常量,但是我们仍然可以通过另外的方式去修改它的值。

    // 这说明把i定义为常量,实际上是防止通过i去修改所代表的内存。

    int *pi = (int*) &i;

 

(三):常量函数

    常量函数是C++对常量的一个扩展,它很好的确保了C++中类的封装性。在C++中,为了防止类的数据成员被非法访问,将类的成员函数分成了两类,一类是常量成员函数(也被称为观察着);另一类是非常量成员函数(也被成为变异者)。在一个函数的签名后面加上关键字const后该函数就成了常量函数。对于常量函数,最关键的不同是编译器不允许其修改类的数据成员。例如:

    class Test

    {

    public:

    void func() const;

    private:

    int intValue;

    };

    void Test::func() const

    {

    intValue = 100;

    }

    上面的代码中,常量函数func函数内试图去改变数据成员intValue的值,因此将在编译的时候引发异常

 

(四):常量返回值 

 

1. const常量,如const int max = 100;  
优点:const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误(边际效应)
2.  const 修饰类的数据成员。如:
class A
{

    const int size;

    …

}

const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。如

class A

{

 const int size = 100;    //错误

 int array[size];         //错误,未知的size

}
const数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现。如

class A

{…

 enum {size1=100, size2 = 200 };

int array1[size1];

int array2[size2];

}

枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数

++++++++++++++++++++++++++++++++++++++++

1. C++中的const正常情况下是看成编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中,并在适当的时候折合在代码中.所以,以下代码:
using namespace std;
int main()
{
const int a = 1;
const int b = 2;
int array[ a + b ] = {0};
for (int i = 0; i < sizeof array / sizeof *array; i++)
{
cout << array << endl;
}
}
在可以通过编译,并且正常运行.但稍加修改后,放在C编译器中,便会出现错误:
int main()
{
int i;
const int a = 1;
const int b = 2;
int array[ a + b ] = {0};
for (i = 0; i < sizeof array / sizeof *array; i++)
{
printf("%d",array);
}
}
错误消息:
c:\test1\te.c(8): error C2057: 应输入常数表达式
c:\test1\te.c(8): error C2466: 不能分配常数大小为 0 的数组
出现这种情况的原因是:在C中,const是一个不能被改变的普通变量,既然是变量,就要占用存储空间,所以编译器不知道编译时的值.而且,数组定义时的下标必须为常量.

 

 

2. 在C语言中: const int size; 这个语句是正确的,因为它被C编译器看作一个声明,指明在别的地方分配存储空间.但在C++中这样写是不正确的.C++中const默认是内部连接,如果想在C++中达到以上的效果,必须要用extern关键字.即C++中,const默认使用内部连接.而C中使用外部连接.

 -------------------- -------------------- -------------------- -------------------- -----------

C语言里面的const 是一个变量 是不能改变的变量,既然是变量就要占用空间 所以可以用来定义常量指针  但是他在编译期内是无法确定值的, 如果要定义数组 ,数组定义时的下标必须为常量. 所以 

 const int  i = 100;  char arr[i]; 这样是错误的在C中 ,如果在C++中 不考虑类的情况 这样是可以编译运行通过的 因为C++中把const看作 编译期的常量,编译器并不为const分配空间,所以代码可以运行通过,但是如果在类定义中这样写是错误的const数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。所以不能在类声明中初始化const数据成员, C语言的const关键字被替换为 readonly更加准确

 

---

const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

const intMax=100;

intArray[Max];

这里请在Visual C++6.0 里分别创建.c 文件和.cpp 文件测试一下。你会发现在.c 文件中,

编译器会提示出错,而在.cpp 文件中则顺利运行。为什么呢?我们知道定义一个数组必须指定其元素的个数。这也从侧面证实在语言中,const 修饰的Max 仍然是变量,只不过是只读属性罢了;而在C++里,扩展了const 的含义,这里就不讨论了。

 

 

 

编译器通常不为普通const 只读变量分配存储空间,而是将它们保存在符号表中,这使

得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高

例如:

#define M 3 //宏常量

const int N=5; //此时并未将放入内存中

......

int i=N; //此时为分配内存,以后不再分配!

int I=M; //预编译期间进行宏替换,分配内存

int j=N; //没有内存分配

int J=M; //再进行宏替换,又一次分配内存!

const 定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const 定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静态区),而#define 定义的宏常量在内存中有若干个拷贝。

#define 宏是在预编译阶段进行替换,而const 修饰的只读变量是在编译的时候确定其值

 

静态区:保存自动全局变量和static 变量(包括static 全局和局部变量)。静态区的内容在总个程序的生命周期内都存在,由编译器在编译的时候分配。

 

 

 

在C++中,一个const不必创建内在空间,而在C中,一个const总是需要创建一块内存空间。

const int bufsize = 100;

char buf[bufsize];

尽管看起来好像做了一件合理的事情,但这将得出一个错误。因为bufsize占用某块内存,所以C编译器不知道它在编译时的值。

 

 

 

分享到:
评论
1 楼 yangbinfx 2013-08-20  
const变量分配内存,而是将其保存在符号表中,这是为了提高效率

相关推荐

    C++const关键字详解

    C++中const关键字详解

    const关键字使用总结

    关于C/C++中的const关键字的用法,你了解多少呢?

    C++中const关键字用法详解及实例和源码下载

    现在读到了const关键字的用法,书上面讲解的时候并没有给出完整的实例,只是理论的讲解了一些知识,后来在网上面搜了关于const的关键字的讲解,但是搜到的内容和书上面讲解的内容有着非常让人疑惑的东西,看看下面的...

    const关键字详解

    关于C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性

    c++中const关键字使用详解

    一 const基础;二 const的初始化;三 作为参数和返回值的const修饰符;四 类成员函数中const的使用;五 使用const的一些建议。

    volatile关键字 Const关键字 static关键字 mutable 关键字

    C/C++ 嵌入式 一些关键字: volatile关键字 Const关键字 static关键字 mutable 关键字

    C++中const关键字详解

    C++中const关键字详解

    游戏效率优化(2) 使用const关键字1

    游戏效率优化(2) 使用const关键字1

    C++语言const 关键字使用方法图文详解

    const关键字 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。不管出现在任何上下文都是为这个目的而服务的。 const使用方法 定义const对象 const修饰符可以把对象转变成常数对象...

    详解C语言中const关键字的用法

    主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下

    浅析c++ 中const关键字

    const是一个C++语言的限定符,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。 define与...

    php中static和const关键字用法分析

    主要介绍了php中static和const关键字用法,结合实例形式分析了static和const关键字的功能、使用方法与相关注意事项,需要的朋友可以参考下

    C/C++ 中const关键字的用法小结

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性。 Const作用 NO. 作用 说明 参考 1 可以定义const常量 const int Max = 100; 2 便于进行类型检查 const常量有数据类型,而宏常量...

    详解C/C++中const关键字的用法及其与宏常量的比较

    1.const关键字的性质 简单来说:const关键字修饰的变量具有常属性。 即它所修饰的变量不能被修改。 2.修饰局部变量 const int a = 10; int const b = 20; 这两种写法是等价的,都是表示变量的值不能被改变,需要...

    总结C语言中const关键字的使用

    const关键字使用非常的灵活,这一点和php差别很大,php中const用来在类中定义一个常量,而在c中,const因位置不同有不同的作用,因情景不同有不同的角色,使用起来也是非常的灵活。 (1):const用来修饰普通的变量...

    C++编程中的const关键字常见用法总结

    这篇文章主要介绍了C++编程中的const关键字常见用法总结,const关键字的使用是C++入门学习中的基础知识,需要的朋友可以参考下。

    C++常对象精讲_const关键字的用法

    const关键字: 用const修饰的定义对象称为常对象; 用const修饰的声明成员函数称为常成员函数; 用const修饰的声明数据成员称为常数据成员。 变量或对象被 const修饰后其值不能被更新。因此被const修饰的变量或对象...

Global site tag (gtag.js) - Google Analytics