C中的const,功能比较单一,较容易理解:                作用:被修饰的内容不可更改。                使用场合: 修饰变量,函数参数,返回值等。(c++中应用场合要丰富的多)                特点: 是运行时const,因此不能取代#define用于成为数组长度等需要编译时常量的情况。同时因为是运行时const,可以只定义而不初始化,而在运行时初始化。如 const int iConst;。 另外,在c中,const变量默认是外部链接,因此在不同的编译单元中如果有同名const变量,会引发命名冲突,编译时报错。c++中的const:跟c中比较,内容要丰富很多,当然,作用也更大了1:非类成员const       *在c++中,const变量(在这里涉及的const都不是类中的const,类中的const专门提出来记录)默认是内部连接的,因此在不同的编译单元中可以有同名的const 变量定义。       *是编译时常量,因此可以像#define一样使用,而且因为上面一点,可以在头文件中定义const变量,包含的不同的cpp文件(编译单元)中使用而不引起命名冲突。       *编译器默认不为const变量分配内存,除非:1. 使用 extern 申明, 2:程序中有引用const 变量的地址。       * 可以使用下面的类型转换(不安全的): 1: int * = (int *)pConst  2: int * = const_cast<int*>pConst(c++解const属性cast)       * 函数参数或者返回值能使用 const & or const * 时,尽量使用const属性,增强程序健全性。       *c++中临时对象/内置变量默认具有const属性2:类中的const      *类中的const与c语言中的const一样,只是运行时常量,不能作为数组维数使用,即不能取代#define。在类中使用下面两种方式取代#define: 1:static const...  2: enum{....}//enum 不占存储空间      *类中的const 变量占用存储空间      *类中的const成员变量需要在构造函数初始化列表中初始化      *const 对象:在该对象生命周期内,必须保证没有任何成员变量被改变。const对象只能调用const成员函数。      *const成员函数: void fun() const ... 不仅能被const对象调用,也能被非const对象调用,因此,如果确认一个任何成员函数不改变任何成员变量,应该习惯性将该函数定义成const类型。 如果const成员函数需要改变成员变量,有两种实现方式: 1 ,const_cast<class*> this强制取消this指针的const属性。 2:将被改变的成员变量定义成mutable:mutable int i; //应永远只使用第二种方法,让任何阅读程序的人都知道该变量可能被const函数改变。

*如果一个对象被定义成const,那么该const对象“可能”会被放入到ROM当中,这在嵌入式开发当中有时非常重要。。。。(不能有任何自定义的constructor 和destructor。它的基类或者成员对象不能有自定义的constructor和destructor,不能有任何mutable成员变量)

C++中的const正常情况下是看成编译期的常量,编译器并不为const分配空间,只是在编译的时候将期值保存在名字表中,并在适当的时候折合在代码中.所以,以下代码:
#include
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编译器中,便会出现错误:
#include
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是一个不能被改变的普通变量,既然是变量,就要占用存储空间,所以编译器不知道编译时的值.而且,数组定义时的下标必须为常量.
在C语言中:
const int size;
这个语句是正确的,因为它被C编译器看作一个声明,指明在别的地方分配存储空间.但在C++中这样写是不正确的.C++中const默认是内部连接,如果想在C++中达到以上的效果,必须要用extern关键字.
C++中,const默认使用内部连接.而C中使用外部连接.
内连接:编译器只对正被编译的文件创建存储空间,别的文件可以使用相同的表示符
或全局变量.C/C++中内连接使用static关键字指定.
外连接:所有被编译过的文件创建一片单独存储空间.一旦空间被创建,连接器必须解
决对这片存储空间的引用.全局变量和函数使用外部连接.通过extern关键
字声明,可以从其他文件访问相应的变量和函数.
************************C++代码******************************
header.h
const int test = 1;
test1.cpp
#include
#include "header.h"
using namespace std;
int main()
{
cout << "in test1 :" << test << endl;
}
test2.cpp
#include
#include "header.h"
using namespace std;
void print()
{
cout << "in test2:" << test << endl;
}
以上代码编译连接完全不会出问题,但如果把header.h改为:
extern const int test = 1;
在连接的时候,便会出现以下错误信息:
test2 error LNK2005: "int const test" (?test@@3HB) 已经在 test1.obj 中定义
因为extern关键字告诉C++编译器test会在其他地方引用,所以,C++编译器就会为test创建存储空间,不再是简单的存储在名字表里面.所以,当两个文件同时包含header.h的时候,会发生名字上的冲突.
此种情况和C中const含义相似:
header.h
const int test = 1;
test1.c
#include
#include "header.h"
int main()
{
printf("in test1:%d\n",test);
}
test2.c
#include
#include "header.h"
void print()
{
printf("in test2:%d\n",test);
}
错误消息:
test3 fatal error LNK1169: 找到一个或多个多重定义的符号
test3 error LNK2005: _test 已经在 test1.obj 中定义
C++中,是否为const分配空间要看具体情况.
如果加上关键字extern或者取const变量地址,则编译器就要为const分配存储空间.
C++中定义常量的时候不再采用define,因为define只做简单的宏替换,并不提供类型检查.

转载于:https://blog.51cto.com/boyishachang/1272947

C / C++ const 的区别和使用相关推荐

  1. js中定义变量之②var let const的区别

    var 上一篇文章有讲过,是js定义变量的关键词. 但是在es6中,新添加了两个关键词,用于变量声明的关键词:let 和const 接下来就说一下var let 和const的区别: 首先说var 用 ...

  2. const int * 、int * const、int const* 、const int a(){ } 和int a()const { }的区别和联系

    前言:很多人都把const int * .int * const.int const* 的区别和联系搞混,我自己在学习C++的过程中,也经常性          弄不 清楚,今天特意总结一下,作为学习 ...

  3. readonly和const的区别

    readonly与const的区别 1.const常量在声明的同时必须赋值,readonly在声明时可以不赋值 2.readonly只能在声明时或在构造方法中赋值(readonly的成员变量可以根据调 ...

  4. C# static readonly 与 const 的区别

    static readonly 与 const 的区别: const 表达式的值是在编译时形成的: static readonly 表达式的值直到程序运行时才形成: 转载于:https://www.c ...

  5. cont char *p 和 char* const p 区别及记忆方法

    /* cont char *p 和 char* const p 区别及记忆方法 const char *p = "hello"; 和 char const *p = "h ...

  6. C++中vector章节iterator与const_iterator及const iterator区别

    C++目前倾向于使用迭代器遍历容器中的元素,而不是使用下标访问的方式来访问容器中的元素. 可以使用iterator和const_iterator来访问元素,但是const类型的容器,那么只能用cons ...

  7. const 常量_var,let,const 的区别?

    为了更好的了解var let const 的区别,我们就来简单的了解它们的过程 相信有很多人都会面临面试官问的这个问题 很多的同学都是简单的认为 var声明的变量会提升,而let const 不会,虽 ...

  8. 谈谈var变量提升以及var,let,const的区别

    1.首先我们理解一个''提升''这个概念,意思就是无论var aaa ="我是var"这行代码在哪个位置,变量的声明都会被提升到所在作用域最前端执行,而变量的赋值则是在当前行执行, ...

  9. const char*, char const*, char*const的区别

    const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目. 事实上这个概念谁都有,只是三种声明方式非常相似很容易记混. Bjarne在他的T ...

  10. const int, const int const, 和 int const 的区别

    const int*, const int * const 和 int const *的区别 声明:本文翻译自:Difference between const int*, const int * c ...

最新文章

  1. leetcode897
  2. java8新特性(四)_Stream详解
  3. oracle数据库是db还是dbnms,Oracle数据库中各种类型的文件损坏与修复过程详解(2)...
  4. 【Groovy】字符串 ( 字符串类型变量定义 | 字符类型变量定义 )
  5. React Router 黑笔记?
  6. PHP7开启opcache打造强悍性能
  7. leetcode209. 长度最小的子数组(滑动窗口)
  8. 嵌入式linux调试技术
  9. 类型,对象,线程栈和托管堆在运行时的相互关系(一)。
  10. linux操作系统分析 课程,《Linux操作系统》课程的现状与分析
  11. linux qt应用程序全屏,QT中MDI应用程序中更改子窗口大小或是全屏显示子窗口的方法...
  12. 当初阿里巴巴、百度、美团都差点错过的架构,现在用起来真香!
  13. Python风格总结:数据结构
  14. Python、Go、JavaScript、Rust 将长盛 5 年!
  15. TE和TM主模式的介绍
  16. android html片段,详解Android WebView加载html片段
  17. 樱花树下的欢笑---2012春西安交大樱花节
  18. java 车牌号归属地_本地化JavaAnpr用于本地的车牌
  19. 数字世界的积木-从MOS管搭反相器,与非门,锁存器,触发器
  20. 读书笔记第三集--转换输入日期的格式

热门文章

  1. python安装mysqlclient模块报fatal error: Python.h:解决方法
  2. 大战设计模式【13】—— 组合模式
  3. 正念奇迹(一则正能量)
  4. 《C专家编程》第三章——分析C语言的声明
  5. 《人月神话》阅读笔记--02
  6. IAR stm8 调试时无法看到局部变量解决
  7. 对象与内存控制1---实例变量和类变量
  8. Hibernate的Session会话中get()和load()方法的区别
  9. PHP中数组的三种排序方法
  10. 第01篇:C#星夜拾遗之如何开始C#学习