想当初面试时,面试官问我熟悉C++么?熟悉的话说一下const的用法,然后我就开始凌乱了~

其实const的用处还真不少,好好捋顺一下会有很大的帮助。

有时候我们希望定义一种常量,它的值不能被修改,这个常量既可以防止程序其他地方不小心修改这个值,也能让程序员比较方便的调整这个值的大小。

以往我们很容易想到#define宏定义,现在使用const是个更为不错的选择,因为它有类型,可以进行类型检查。

第一部分const的初始化

Const值一旦创建后就不能修改,所以const对象必须初始化。

Const int i=0;//正确

Constint i;//错误

Const对象可以用非const对象初始化,也可以付给非const对象,同时也能参与运算,只要初始化后不改变它的值就没问题。

Int i;

Constint j=i;//正确

Intm=j;//正确

第二部分const的作用域

默认状态下,Const对象仅在文件内有效。所以不同文件的const对象不是同一个对象,即使名字相同,因为这样才能避免重复定义。

那为了使一个非常量表达式的const变量在不同文件之间可以共享,可以使用extern来解决问题。

我们知道关键字extern可以用作对象的声明而不定义。所以我们按如下的方式:

//file.cpp

extern constint temp=fun();

//file.h

extern constint temp;//正确

第三部分const与引用

引用可以节省拷贝带来的内存损耗。类似起了个别名。

1.      对常量的引用必须要用const引用

Const int c=42;

Int &r1=c;      //错误,因为非常量引用可以改变所引用对象,所以这样不合理

Const int&r2=c;//正确,引用与对应的对象都是常量

2.      对const的引用可能并非引用一个const对象

int a=0;

int &r1=a;

const int&r2=a;//正确

r1=0;

r2=0;         //错误,r2是常量引用不能修改所引用的值

3.      初始化常量引用时允许用任意表达式(可以是不同类型)作为初始值

Int i=4;

Double b=9.22;

Const int &r1=i;

Const int &r2=b;

Const int&r3=44;

Const int&r4=r1*2;

//以上都是正确的

int &r5=r1*2;     //错误,r5是普通的非常量的引用

第四部分const与指针

1.      与常量引用相似,指向常量的指针必须要用const指针(指向常量的指针)

const int c=42;

int *r1=&c;      //错误

const int*r2=&c;//正确

*r2=42;//错误,不能给指针所指对象赋值

2.  常量指针(指向const的指针)和指针常量(const指针)

区分常量指针(指向常量的指针)和指针常量(地址是常量,指针指向的地址不变)

(前两个字作为形容词修饰后两个字。

同时大家也要注意const指针这一说法,不要理解成常量指针)

Int num=0;

Int*const cur=#//一直指向num

Const double pi=3.1415;

Const double * const pip=π//指向常量的常量指针。

*现在举例子说明一下常量指针域指针常量到底如何区分。

1. int const* cur;   常量指针,指向常量的指针

2.Const int * cur;   常量指针,指向常量的指针

3. int*const cur;   指针常量

4. const(int *) cur;  //错误,不可以这么写

现在我们可以以*为分界,我们从右向左读取指针变量(cur)最近的关键字,1和2的情况变量紧挨着*(理解为*直接修饰cur),证明该指针不是常量指针,而3中const比*更接近变量,所以3是常量指针(理解为*修饰const  cur ,const修饰cur,所以cur是不变的)

这里记忆的方法并不是深入C++原理的方法,不过个人觉得非常有效!!!强烈建议试试!!

虽然没有第四种情况,但是在使用typedef时有一个类似的情况,这里在给出一个例子。

typedef  char* pstring;

const  pstring cstr=0;

//cstr是一个指向char的常量指针,这句话等价于char*  Const  cstr=0;

//而不是等价于Const  char*  cstr=0;

第五部分const与函数参数

1.       顶层const与底层const

带有const声明的变量本身不变是顶层const,所引用或所指向的对象不变就是底层const。

在进行拷贝操作时,顶层const一般可以忽略,但是底层const不可以忽略。

2.      实参初始化形参时会忽略顶层const

Void fun(const inti)

Void fun(int i)//再次定义则会报错,重复定义,二者其实没什么差别,因为第一个顶层const被忽略

3.      形参的初始化方式和变量的初始化方式一样,可以使用非常量初始化一个底层const,但反过来不

可以

Int i=0;

Const int &j=i;//正确

Int &r1=j;//错误

同理,对于函数int  reset(int *a){}

Int i=0;

Const int ci=i;

Reset(&i);//正确

Reset(&ci);//错误

4.      尽量使用常量引用

把函数不会改变的形参定义成普通引用会造成一种可以改变的错觉,而且限制了实参的类型。因为我们上面说了,常量引用可以接受更多种类的赋值,包括表达式,字面值等。有时,还可能出现把常量引用作为参数赋给非常量引用的错误。

下面是C++primer里面的两个例子(有修改,这里不在意功能):

例1:

Int find_char(string&s,char c)

Find_char(“Hello”,’o’);//错误,普通引用无法接收字面值

例2:

Bool  isSentence(const string &s)

{

Return find_char(s,’o’);//错误,s是常量引用不能赋给非常量变量

}

 

第六部分const与类

1.      const成员变量

类中声明变量为const类型。但是不可以初始化,必须要在构造函数初始化列表中初始化。

这样的变量其实只是在一个对象中是不变的,要想在整个类中都不变就得用enum(枚举)

2.      const成员函数

这样的成员函数不可以修改数据成员,如果修改成员变量或者调用了其他非const成员函数就会报错。

Const用法总结(快速区分指针常量与常量指针)的更多相关文章

  1. C++之常指针,指针常量,函数指针,const用法总结

    1.const char *p,char const *p,char * const p 对于C++而言,没有const * 修饰符,所以,const只可以修饰类型或者变量名.因而const char ...

  2. const指针和指向常量的指针

    先看下面六种写法: . const int p; . const int *p; . int const* p; . int * const p; . const int * const p; . i ...

  3. 【转】const int *p和int * const p的区别(常量指针与指向常量的指针)

    [转]作者:xwdreamer   出处:http://www.cnblogs.com/xwdreamer 对于指针和常量,有以下三种形式都是正确的: const char * myPtr = &am ...

  4. c++中指针常量,常指针,指向常量的常指针区分

    const char * myPtr = &char_A;//指向常量的指针 char * const myPtr = &char_A;//常量的指针 const char * con ...

  5. C++ const 常量和常指针

    常量,该指针所指向的值为只读 ; const int * p = &a; 常指针,该指针的值为只读,不可再指向其他地址 const * const p = &a; 常值,常指针 con ...

  6. 指针与 const --- 指针常量与常量指针

    注:该文主要来源于 网易公开课之<C++ 程序设计入门(上)>课件. 在 C 语言标准中,const 修饰的变量称之为 只读变量, 在 C++ 语言标准中,const 修饰的变量称之为 常 ...

  7. C++中const用法详解

    本文主要内容来自CSDN论坛: http://bbs.csdn.net/topics/310007610 我做了下面几点补充. 补充: 1. 用const声明全局变量时, 该变量仅在本文件内可见, 类 ...

  8. const用法详解(转)

    http://www.cnblogs.com/StudyRush/archive/2010/10/06/1844690.html 面向对象是C++的重要特性. 但是c++在c的基础上新增加的几点优化也 ...

  9. C++中指针常量和常量指针的区别

    在C++学习使用过程中,每个人都不可避免地使用指针,而且都或多或少的接触过常量指针或指针常量,但是对这两个的概念还是很容易搞糊涂的. 本文即是简单描述指针常量和常量指针的区别. 常量指针 定义: 又叫 ...

随机推荐

  1. WPF中 PropertyPath XAML 语法

    原文:WPF中 PropertyPath XAML 语法 PropertyPath 对象支持复杂的内联XAML语法用来设置各种各样的属性,这些属性把PropertyPath类型作为它们的值.这篇文章讨 ...

  2. OpenSSL 使用 base64 编码/解码(liang19890820)

    关于 OpenSSL 的介绍及安装请参见:Windows 下编译 OpenSSL 下面主要介绍有关 OpenSSL 使用 base64 编码/解码. 简述 编码解码 更多参考 编码/解码 #inclu ...

  3. R 语言学习(二)—— 向量

    1. 入门 将摄氏度转化为华氏度 >> 27*1.8+32 [1] 80.6 [1]:表示数字的向量索引号,在 R 语言中任何一个数字都看作一个向量. 向量化 >> temp ...

  4. sklearn 下的流行学习(Manifold Learning)—— sklearn.manifold

    1. t-SNE from sklearn.manifold import TSNE X_proj = TSNE(random_state=123).fit_transform(X) 2. t_sne ...

  5. 1-5设定NetCore监听端口

    问题的起源:启动一个.netCore项目,默认使用的是5000端口,当我们有很多个项目的时候(集群),不可能都使用5000端口. 方法1:set ASPNETCORE_URLS=http://127. ...

  6. WPF安装打印机驱动后PrintDialog 执行打印事件

    原文:WPF安装打印机驱动后PrintDialog 执行打印事件 WPF可以很好的利用流文档来实现打印预览和PrintDialog 实现打印功能,但是我在这只是写了一个很简单的打印功能演示. Page ...

  7. Select2使用方法汇总

    引用: <script src="~/Content/plugins/select2/select2.min.js"></script> 1.简单使用 $. ...

  8. C# 写CSV文件字符串前面0不显示的解决办法

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...

  9. C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻(转)

    前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...

  10. Socket 专题

    Socket小白篇-附加TCP/UDP简介 Socket 网络通信的要素 TCP和UDP Socket的通信流程图 1.Socket 什么是Socket Socket:又称作是套接字,网络上的两个程序 ...