c/c++中const使用总结(金典)
原文地址: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;
- char *const cp; //到char的const指针
- char const *pc1; //到const char的指针
- 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是作为基础类型的一部分:
- char *const cp; //到char的const指针
- char const *pc1; //到const char的指针
- 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使用总结(金典)的更多相关文章
- C、C++中const的区别
C语言中: 被const修饰的变量,仍然是变量.虽然不能用C语法给这个变量改变值,但他本质上还是变量. C编译器会给它分配空间. C中,const默认使用的是外部链接. C++中: 被const修饰的 ...
- JavaScript中const、var和let区别浅析
在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始 ...
- C/C++中const的用法 分类: C/C++ 2015-07-05 00:43 85人阅读 评论(0) 收藏
const是C语言的关键字,经C++进行扩充,变得功能强大,用法复杂.const用于定义一个常变量(只读变量),当const与指针,引用,函数等结合起来使用时,情况会变得复杂的多.下面将从五个方面总结 ...
- C++中const 的各种用法
C++中const 关键字的用法 const修饰变量 const 主要用于把一个对象转换成一个常量,例如: ; size = ; // error: assignment of read-only v ...
- (转) C/C++中const关键字详解
文章转自 http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777416.html 为什么使用const?采用符号常量写出的代码更容易维 ...
- 实例讲述PHP面向对象的特性;;;php中const与define的使用区别
php中const与define的使用区别 1.const:类成员变量定义,一旦定义且不能改变其值. define:定义全局常量,在任何地方都可以访问.2.define:不能在类中定义,而const可 ...
- C++中const简介及用法
1.const简介 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰 ...
- C/C++ 中 const 修饰符用法总结
C/C++ 中 const 修饰符用法总结 在这篇文章中,我总结了一些C/C++语言中的 const 修饰符的常见用法,供大家参考. const 的用法,也是技术性面试中常见的基础问题,希望能够帮大家 ...
- C++中const用法详解
本文主要内容来自CSDN论坛: http://bbs.csdn.net/topics/310007610 我做了下面几点补充. 补充: 1. 用const声明全局变量时, 该变量仅在本文件内可见, 类 ...
- C++ 中 const和define的区别
来源网址:http://wujiangping.blog.163.com/blog/static/195182011201255115125205/ 请区别用#define命令定义的符号常量和用con ...
随机推荐
- work1
参考书选择 我选择的是 [代码大全2英文版(完整清晰版)].chm 问题分析 对于一维的情况,经典的方式是使用前缀数组s[i]表示a[0]至a[i]的加和,区间最大和若是a[i]至a[j]则等价于s[ ...
- Auto Layout 使用心得
此系列文章代码仓库在 https://github.com/johnlui/AutoLayout ,有不明白的地方可以参考我的 Auto Layout 设置哦,下载到本地打开就可以了. 简介 Auto ...
- ltt.js
var dailyBox = $('.daily-box-office'), curDate = new Date(), curYear = curDate.getFullYear(), curMon ...
- Oracle10g完全卸载正确步骤
Oracle卸载要求比较严格,不能简单的卸载就完事了:当然Oracle卸载也没有那么难,只是步骤比较多.Oracle10g还是Oracle11g卸载步骤都是一样的.下边详细介绍一下. 找到Oracle ...
- DOS/Windows下黑客攻防(一)——神秘黑客大曝光
一.认识神秘的黑客 谈到网络安全,人们不自觉间就会联想到黑客,人们往往会将他们同破坏网络安全.盗取用户账号.偷窃个人私密信息联系起来.其实黑客也有好坏之分,他们并不全是网络上的捣乱分子,其中也有一部分 ...
- MySQL 约束
MySQL中约束保存在information_schema数据库的table_constraints中,可以通过该表查询约束信息: 约束主要完成对数据的检验,保证数据库数据的完整性:如果有相互依赖数据 ...
- C#操作sql通用类 SQLHelper
Codeusing System; using System.Data; using System.Configuration; using System.Web; using System.Web. ...
- Oracle 监听器无法启动(TNS-12537,TNS-12560,TNS-00507)
Oracle启动监听报错,提示 连接中断 [oracle@localhost ~]$ lsnrctl start LSNRCTL for Linux: Version 11.2.0.1.0 - Pro ...
- linq to sql 扩展方法
老赵的博客:http://blog.zhaojie.me/2008/02/using-translate-method-and-modify-command-text-before-query-in- ...
- JAVA使用EPoll来进行NIO处理的方法(转)
JDK 6.0 以及JDK 5.0 update 9 的 nio支持epoll (仅限 Linux 系统 ),对并发idle connection会有大幅度的性能提升,这就是很多网络服务器应用程序需要 ...