一、说说const

一般而言,const主要是用来防止定义的对象再次被修改,定义对象变量时要初始化变量。

常见用法如下:

1.用于定义常量变量,这样这个变量在后面就不可以再被修改

const int Val = 10;

//Val = 20; //错误,不可被修改

2. 保护传参时参数不被修改,如果使用引用传递参数或按地址传递参数给一个函数,在这个函数里这个参数的值若被修改,

则函数外部传进来的变量的值也发生改变,若想保护传进来的变量不被修改,可以使用const保护

void  fun1(const int &val)

{

//val = 10; //出错

}

void fun2(int &val)

{

val = 10; //没有出错

}

void main()

{

int a = 2;

int b = 2;

fun1(a); //因为出错,这个函数结束时a的值还是2

fun2(b);//因为没有出错,函数结束时b的值为10

}

如果只想把值传给函数,而且这个不能被修改,则可以使用const保护变量,有人会问为什么不按值传递,按值传递还需要把这个值复制一遍,

而引用不需要,使用引用是为了提高效率//如果按值传递的话,没必要加const,那样根本没意义

3. 节约内存空间,

#define  PI  3.14 //使用#define宏

const double Pi = 3.14 //使用const,这时候Pi并没有放入内存中

double  a = Pi;  //这时候才为Pi分配内存,不过后面再有这样的定义也不会再分配内存

double  b = PI;  //编译时分配内存

double  c = Pi;  //不会再分配内存,

double  d = PI;  //编译时再分配内存

const定义的变量,系统只为它分配一次内存,而使用#define定义的常量宏,能分配好多次,这样const就很节约空间

4.类中使用const修饰函数防止修改非static类成员变量

class

{

public:

void fun() const //加const修饰

{

a = 10; //出错,不可修改非static变量

b = 10; //对,可以修改

}

private:

int  a ;

static int b;

}

5.修饰指针
const int *A; 或 int const *A;  //const修饰指向的对象,A可变,A指向的对象不可变
int *const A;               //const修饰指针A, A不可变,A指向的对象可变
const int *const A;           //指针A和A指向的对象都不可变

6.修饰函数返回值,防止返回值被改变

const int fun();

接收返回值的变量也必须加const

const int a = fun(); //接收的变量也要是const的,int a = fun()是错误的

7.修饰类的成员变量

使用const修饰的变量必须初始化,在类中又不能在定义时初始化,

如;

class

{

private:

int a = 10;

const int b = 10;

static const int c = 10;

//这样初始化都是错的,

}

初始化const int类型(没有static),在类的构造函数上初始化

Class Test

{

Public:

Test():b(23) //构造函数上初始化b的值为23

{

}

private:

const int b ;

}

初始化staticconst int这个类型的(带有static的),在类的外面初始化

class Test

{

private:

static const int c;

}

const int Test::c=10; //类的外部初始化c为10

8.const定义的对象变量只能作用于这个程序该C/C++文件,不能被该程序的其他C/C++文件调用,

如file1.cpp中 const int val;

在file2.cpp中, extern intval; //错误,无法调用,

要想const定义的对象变量能被其他文件调用,定义时必须使用extern修饰为

extern const int val;

非const变量默认为extern,要是const能被其他文件访问必须显示指定为extern

二、说说typedef

(C++Primer Plus,p149,p248等有相关论述)

以前简单地以为typdef的用法不过是typedef A B,即把类型B作为类型A的一个新名字。但是碰到像typedef string *pstring或者是typedef int int_array[4]这样的定义就比较容易误解。

常见难点用法如下:

1)用typedef简化指向多维数组的指针的定义

首先,以一维数组为例:

比如typedef int int_array[4],如果去掉前面的typedef那么定义的是一个叫做int_array的含有4个元素的数组。而前面加上typedef以后,int_array就变成了含有4个元素的数组类型的替代名。以后要有int_array ia;这句话我们就知道它等同于int ia[4];

二维数组的例子解读可参考:typedef和const之间的trap

2)用typedef简化函数指针的定义

例如:

typedef bool (*cmpFcn)(conststring &, const string &);

该定义表示 cmpFcn 是一种指向函数的指针类型的名字。该指针类型为“指向返回bool类型并带有两个const string引用形参的函数的指针”。在要使用这种函数指针类型时,只需直接使用cmpFcn即可,不必每次都把整个类型声明全部写出来。如:用新得到的类型来定义两个新的函数指针pf1和pf2,

cmpFcn pf1;

cmpFcn pf2;
 

又假设给出以下语句:

typedef string *pstring;

const pstring cstr;

很多人都错误地认为是:

const string *cstr;//const pstring 是一种指针,指向string 类型的 const 对象

错误的原因在于将 typedef 当做文本扩展了。声明 const pstring 时,const 修饰的是pstring的类型,这是一个指针。因此,该声明语句应该是把cstr定义为指向string 类型对象的const指针,这个定义等价于:string *const cstr;

3) 用typedef简化复杂类型的定义

篇幅有限,更详细的用法解读推荐参阅:C++ typedef用法小结(强烈推荐)

C/C++ typedef用法 

const和typedef的常见用法详解的更多相关文章

  1. STL priority_queue 常见用法详解

    <算法笔记>学习笔记 priority_queue 常见用法详解 //priority_queue又称优先队列,其底层时用堆来实现的. //在优先队列中,队首元素一定是当前队列中优先级最高 ...

  2. STL pair 常见用法详解

    <算法笔记>学习笔记 pair 常见用法详解 //pair是一个很实用的"小玩意",当想要将两个元素绑在一起作为一个合成元素, //又不想因此定义结构体时,使用pair ...

  3. STL stack 常见用法详解

    <算法笔记>学习笔记 stack 常见用法详解 stack翻译为栈,是STL中实现的一个后进先出的容器.' 1.stack的定义 //要使用stack,应先添加头文件#include &l ...

  4. STL queue 常见用法详解

    <算法笔记>学习笔记 queue 常见用法详解 queue翻译为队列,在STL中主要则是实现了一个先进先出的容器. 1. queue 的定义 //要使用queue,应先添加头文件#incl ...

  5. STL map 常见用法详解

    <算法笔记>学习笔记 map 常见用法详解 map翻译为映射,也是常用的STL容器 map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器) 1. map 的定义 / ...

  6. STL string 常见用法详解

    string 常见用法详解 1. string 的定义 //定义string的方式跟基本数据类型相同,只需要在string后跟上变量名即可 string str; //如果要初始化,可以直接给stri ...

  7. STL set 常见用法详解

    <算法笔记>学习笔记 set 常见用法详解 set是一个内部自动有序且不含重复元素的容器 1. set 的定义 //单独定义一个set set<typename> name: ...

  8. STL vector常见用法详解

    <算法笔记>中摘取 vector常见用法详解 1. vector的定义 vector<typename> name; //typename可以是任何基本类型,例如int, do ...

  9. [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

    关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...

随机推荐

  1. JS省市区联动效果

    省市区联动下拉效果在WEB中应用非常广泛,尤其在电商网站最为常见.一般使用Ajax实现无刷新下拉联动.利用jQuery,通过读取JSON数据,实现无刷新动态下拉省市二(三)级联动效果. 首先我们可以看 ...

  2. Java java.text.ParseException: Unparseable date

    用java将字符串转换成Date类型是,会出现java.text.ParseException: Unparseable date异常. 例如下面的这段代码就会出现上面的异常: public bool ...

  3. Hadoop中ssh+IP、ssh+别名免秘钥登录配置

    1.为什么要进行 SSH 无密码验证配置? Hadoop运行过程中需要管理远端Hadoop守护进程,在Hadoop启动以后,NameNode是通过SSH(Secure Shell)来启动和停止各个Da ...

  4. 安装Jenkins服务

    1.下载Jenkins 下载地址:https://jenkins.io/download/ 选择rpm包 2.启动服务 [root@node1 ~]# rpm -ivh jenkins-2.138.3 ...

  5. activiti发布APP时报错:关联的流程无效

    解决办法: 1.检查流程命名和任务命名以及其他命名中是否有特殊字符,有一些字符是不支持的.(中文是可以的,中文标点符号可能不行,我的经验是顿号会报错) 2.检查流程图,把鼠标放到每一根连接线上,观察它 ...

  6. 大数据入门第二十一天——scala入门(一)并发编程Actor

    注:我们现在学的Scala Actor是scala 2.10.x版本及以前版本的Actor. Scala在2.11.x版本中将Akka加入其中,作为其默认的Actor,老版本的Actor已经废弃 一. ...

  7. 20155209 Exp5 MSF基础应用

    Exp5 MSF基础应用 实验准备 在实验之前,上网搜集了很多有关Metasploit渗透测试的资料.对这次实验影响最大的是一篇最受欢迎的10个Metasploit模块和插件.排名第一位的是MSB-M ...

  8. 汇编 for循环

    知识点: for循环生成代码1 for循环生成代码2 inc指令 一.一般情况下的for循环汇编代码分析 ;i<=;i++) { printf("%d,",i); } ...

  9. 【SP1812】LCS2 - Longest Common Substring II

    [SP1812]LCS2 - Longest Common Substring II 题面 洛谷 题解 你首先得会做这题. 然后就其实就很简单了, 你在每一个状态\(i\)打一个标记\(f[i]\)表 ...

  10. Linux常用rmp包网址

    * HA:http://download.opensuse.org/repositories/network:/ha-clustering:/Stable/ * Openstack:https://r ...