原文地址:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html

个人总结:

         (1)const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符

         (2)const和基本类型(int、char)或者类名(class)可以互换。

              因此const char *p = char const *p;

  1. char *const cp;   //到char的const指针
  2. char const *pc1; //到const char的指针
  3. const char *pc2; //到const char的指针(后两个声明是等同的)

         (3    const int *m1 = new int(10);----------指针内容不可变-------------------- 常量指针---const左边是int,因此修饰内容常量(把它等价为int const*m1)

int* const m2 = new int(20);--------- 指针不能变,必须指这个内存地址-----指针常量---const左边是*,因此修饰指针

在上面的两个表达式中,最容易让人迷惑的是const到底是修饰指针还是指针指向的内存区域?其实,只要知道:const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。根据这个规则来判断,m1应该是常量指针(即,不能通过m1来修改它所指向的内容。);而m2应该是指针常量(即,不能让m2指向其他的内存模块)。由此可见:

目录:

    const介绍

   一、const与指针

   二、const与引用

开始:

为什么使用const?采用符号常量写出的代码更容易维护;指针常常是边读边移动,而不是边写边移动;许多函数参数是只读不写的。const最常见用途是作为数组的界和switch分情况标号(也可以用枚举符代替),分类如下:

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

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

常对象:  类名 const 对象名

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

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

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

首先提示的是:在常变量(const 类型说明符 变量名)、常引用(const 类型说明符 &引用名)、常对象(类名 const 对象名)、 常数组(类型说明符const 数组名[大小]), const” 与 “类型说明符”或“类名”(其实类名是一种自定义的类型说明符) 的位置可以互换。如:

const int a=5; 与 int const a=5; 等同

类名 const 对象名 与 const 类名 对象名 等同

用法1:常量
    取代了C中的宏定义,声明时必须进行初始化(!c++类中则不然)。const限制了常量的使用方式,并没有描述常量应该如何分配。如果编译器知道了某const的所有使用,它甚至可以不为该const分配空间。最简单的常见情况就是常量的值在编译时已知,而且不需要分配存储。―《C++ Program Language》
    用const声明的变量虽然增加了分配空间,但是可以保证类型安全。
    C标准中,const定义的常量是全局的,C++中视声明位置而定。

用法2:指针和常量
    使用指针时涉及到两个对象:该指针本身和被它所指的对象。将一个指针的声明用const“预先固定”将使那个对象而不是使这个指针成为常量。要将指针本身而不是被指对象声明为常量,必须使用声明运算符*const。
    所以出现在 * 之前的const是作为基础类型的一部分:

  1. char *const cp; //到char的const指针
  2. char const *pc1; //到const char的指针
  3. const char *pc2; //到const char的指针(后两个声明是等同的)

从右向左读的记忆方式:
cp is a const pointer to char. 故pc不能指向别的字符串,但可以修改其指向的字符串的内容
pc2 is a pointer to const char. 故*pc2的内容不可以改变,但pc2可以指向别的字符串

且注意:允许把非 const 对象的地址赋给指向 const 对象的指针,不允许把一个 const 对象的地址赋给一个普通的、非 const 对象的指针。

用法3:const修饰函数传入参数
    将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。同理,将指针参数声明为const,函数将不修改由这个参数所指的对象。
    通常修饰指针参数和引用参数:
void Fun( const A *in); //修饰指针型传入参数
void Fun(const A &in); //修饰引用型传入参数

用法4:修饰函数返回值
    可以阻止用户修改返回值。返回值也要相应的付给一个常量或常指针。

用法5:const修饰成员函数(c++特性)
const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数;
const对象的成员是不能修改的,而通过指针维护的对象确实可以修改的;
const成员函数不可以修改对象的数据,不管对象是否具有const性质。编译时以是否修改成员数据为依据进行检查。

具体展开来讲:
(一). 常量与指针

常量与指针放在一起很容易让人迷糊。对于常量指针和指针常量也不是所有的学习C/C++的人都能说清除。例如:

const int *m1 = new int(10);

int* const m2 = new int(20);

在上面的两个表达式中,最容易让人迷惑的是const到底是修饰指针还是指针指向的内存区域?其实,只要知道:const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。根据这个规则来判断,m1应该是常量指针(即,不能通过m1来修改它所指向的内容。);而m2应该是指针常量(即,不能让m2指向其他的内存模块)。由此可见:

1. 对于常量指针,不能通过该指针来改变所指的内容。即,下面的操作是错误的:

int i = 10;

const int *pi = &i;

*pi = 100;

因为你在试图通过pi改变它所指向的内容。但是,并不是说该内存块中的内容不能被修改。我们仍然可以通过其他方式去修改其中的值。例如:

// 1: 通过i直接修改。

i = 100;

// 2: 使用另外一个指针来修改。

int *p = (int*)pi;

*p = 100;

实际上,在将程序载入内存的时候,会有专门的一块内存区域来存放常量。但是,上面的i本身不是常量,是存放在栈或者堆中的。我们仍然可以修改它的值。而pi不能修改指向的值应该说是编译器的一个限制。
   2. 根据上面const的规则,const int *m1 = new int(10);我们也可写作:

int const *m1 = new int(10);

这是,理由就不须作过多说明了。
   3. 在函数参数中指针常量时表示不允许将该指针指向其他内容。

void func_02(int* const p)

{

int *pi = new int(100);

//错误!P是指针常量。不能对它赋值。

p = pi;

}

int main()

{

int* p = new int(10);

func_02(p);

delete p;

return 0;

}

4. 在函数参数中使用常量指针时表示在函数中不能改变指针所指向的内容。

void func(const int *pi)

{

//错误!不能通过pi去改变pi所指向的内容!

*pi = 100;

}

int main()

{

int* p = new int(10);

func(p); 

delete p;

return 0;

}

  我们可以使用这样的方法来防止函数调用者改变参数的值。但是,这样的限制是有限的,作为参数调用者,我们也不要试图去改变参数中的值。因此,下面的操作是在语法上是正确的,但是可能破还参数的值:

#include <iostream>

#include <string>

void func(const int *pi)

{

//这里相当于重新构建了一个指针,指向相同的内存区域。当然就可以通过该指针修改内存中的值了。

int* pp = (int*)pi;

*pp = 100;

}

int main()

{

using namespace std;

int* p = new int(10);

cout << "*p = " << *p << endl;

func(p);

cout << "*p = " << *p << endl;

delete p;

return 0;

}

c/c++中const使用总结(金典)的更多相关文章

  1. C、C++中const的区别

    C语言中: 被const修饰的变量,仍然是变量.虽然不能用C语法给这个变量改变值,但他本质上还是变量. C编译器会给它分配空间. C中,const默认使用的是外部链接. C++中: 被const修饰的 ...

  2. JavaScript中const、var和let区别浅析

    在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...

  3. C/C++中const的用法 分类: C/C++ 2015-07-05 00:43 85人阅读 评论(0) 收藏

    const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结 ...

  4. C++中const 的各种用法

    C++中const 关键字的用法 const修饰变量 const 主要用于把一个对象转换成一个常量,例如: ; size = ; // error: assignment of read-only v ...

  5. (转) C/C++中const关键字详解

    文章转自  http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 为什么使用const?采用符号常量写出的代码更容易维 ...

  6. 实例讲述PHP面向对象的特性;;;php中const与define的使用区别

    php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...

  7. C++中const简介及用法

    1.const简介 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰 ...

  8. C/C++ 中 const 修饰符用法总结

    C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...

  9. C++中const用法详解

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

  10. C++ 中 const和define的区别

    来源网址:http://wujiangping.blog.163.com/blog/static/195182011201255115125205/ 请区别用#define命令定义的符号常量和用con ...

随机推荐

  1. A Tour of Go Exercise: Errors

    Copy your Sqrt function from the earlier exercises and modify it to return an error value. Sqrt shou ...

  2. [iOS基础控件 - 1] UI概念

    A. UIView 1.概念      属于UIKit框架      屏幕上能看得见摸得着的东西就是UIView,比如屏幕上的按钮.文字.图片      翻译为:视图/控件/组件      UIBut ...

  3. 转载 SharePoint Foundation和SharePoint Server的区别

    SharePoint Server 2010用来取代MOSS 2007,它有标准版和企业版两个版本,使用SQL Server数据库: 早期版本中的STS或WSS在2010中更名为SharePoint ...

  4. Head First设计模式-观察者模式

    一.整体代码 Subject.java public interface Subject { public void registerObserver(Observer o); public void ...

  5. 【Away3D代码解读】(一):主要类及说明

    在深入解读Away3D的代码之前,需要对其有个大概的认识.本节主要列出Away3D中常用的类,并附上说明: View3D: Away3D的入口类,即创建该类就会初始化一个可以使用GPU呈现3D的对象, ...

  6. iOS UICollectionView基础

    转载自:http://www.cnblogs.com/wayne23/p/4013522.html  初始化部分: UICollectionViewFlowLayout *flowLayout= [[ ...

  7. 传const引用代替传值

    1.为什么使用传const引用? a.被调方法中,形参不再进行copy构造,以及析构,提高效率. b.传值,会出现对象切割的问题. 2.有没有例外? 在编译器底层,引用是使用指针实现的.这就意味着,如 ...

  8. 主流数据库字段类型转.Net类型的方法

    最近在阅读一些开源的代码,发现其中有些方法总结的很全面,至少在我做同样的事情时候,需要抓破脑袋想活着google,现在看到了这个关于主流数据库字段类型转.Net类型的方法,故收藏之,也顺便分享给那些能 ...

  9. OSI七层模型具体解释

    OSI 七层模型通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯,因此其最基本的功能就是帮助不同类型的主机实现传输数据 . 完毕中继功能的节点通常称为中继系统.在OSI七层模型中,处于 ...

  10. sphinx配置文件继承

    # # Minimal Sphinx configuration sample (clean, simple, functional) # source mysql { type = mysql #数 ...