const在c和c++中地位不同
先测试C语言的const:
#include<stdio.h> int main()
{
const int a = ;
//等价于
//int const a = 10;
//a = 11;//err int s = ;
const int *p=&s;
//*p = 10;//err 改变p所指向的内容
p = NULL;//改变p是可以的 int *const p1 = &s;
//p1 = NULL;err
*p1 = ; return ;
}
不是指针变量的表达式,const放在类型的前后都没关系,但是在指针变量中,const的位置就有讲究了,此时要分清楚是指针变量的值是只读的还是指针所指向的内存空间是只读的。而且,C语言中,const是个假const:
#include<stdio.h> int main()
{
const int a = ;
//等价于
//int const a = 10;
//a = 11;//err //看似不能改变a的值,其实只是不能直接更改而已,但可以间接修改
int *p = &a;//C语言中这种类型不符合是可以被接受的,c++中不行
*p = ;
printf("%d\n", a); return ;
}
运行结果显示a的值被改变。所以,在C语言中,const不是真正的常量,只是不能直接修改而已,因此,在那些必须要常量的场合,不能用const定义的变量。比如数组的维数,虽然在C99中支持了变长数组,但是很多时候我们使用的都不是VLA,因为VLA局限性比较大,不能初始化,还必须是局部变量。那么,C语言中的常量只有define和直接数字值还有就是枚举。
#include<stdio.h>
enum test
{
saturday,
sunday = ,
monday,
tuesday,
wednesday,
thursday,
friday
} ;
int main()
{ int a[friday] = { }; return ;
}
枚举类型可以编译通过,因为它是真正的常量。这是在没有支持C99的前提下测试的。define自然支持就不再测试了。
那么,其实在很多时候,C语言中的代码加上了const修饰,也还是不安全的。
int main()
{
int a = ;
int const *p2 = &a;
int * p1 = p2;
*p1 = ;
printf("%d\n", a); return ;
}
上述代码还是会改变a的值,但这个例子一般我们不会这样写,不过从上面的代码中,我们可能会像下面这样写程序,因为很多时候,我们想用const指针修饰的形参。目的是不想实参被改变,但是如果不注意,还是达不到想要的效果:
#include<stdio.h>
void test(int const *p)
{
int *p1 = p;
*p1 = ;
}
int main()
{
int a = ;
test(&a);
printf("%d\n", a); return ;
}
我们把形参的指针所指向的内存空间设置成const的,就是不想实参被改变,但是还是可能会被间接修改,所以,在编写代码的时候,我们不要使用上述代码的
int *p1 = p; 因为就算你形参用const保护了,后续忘记了用const去接这样的变量,还是无用的。这提醒我们注意,应该这样去写这句
话:
int const *p1 = p;
保证接它的变量也要是const的。 c++中,const是升级过的了:
#include<iostream>
using namespace std; int main()
{
int const a = ;
//int *p = &a;c++中,不允许这样的转换,而C语言中是可以的,c++对类型检查更为严格
int *p = (int *)&a;
*p=100;
cout << a << endl;
return ;
}
此时,c++不再允许我们对此进行更改,这证明了,c++中const修饰的变量是真正的常量,是不是const修饰的就如果简单了呢?那么我们再试试换个方式:
#include<iostream>
using namespace std; int main()
{
int b = ;
int const a = b;
//int *p = &a;c++中,不允许这样的转换,而C语言中是可以的,c++对类型检查更为严格
int *p = (int *)&a;
*p = ;
cout << a << endl;
return ;
}

可以清楚地看到,我们改变了a的值,这也就是说,在c++中,如果用一个字面值给const修饰的变量赋值,例如int const a=10;这样的a就是常量,可以用来当做数组的维数,如果用一个变量给const修饰的变量赋值,例如int const a=b;这样的a就是只读变量,不能直接修改,但可以间接修改,和c中一样了。
另外注意,由于c++中严格检查类型匹配问题,所以我们要知道,在const修饰的指针变量中,顶层const在有赋值效果的操作中将被忽略。
const在c和c++中地位不同的更多相关文章
- const在C与C++中的区别
在C中,const不是常量,只能说是一个不能改变的变量(注意是变量),C编译器不能把const看成看成一个编译期间的常量,因为他在内存中有分配,C编译器不知道他在编译期间的值.所以不能作为数组定义时的 ...
- const在c和c++中的不同
最近开始由学习c转到c++:从面向过程到面向对象的转变中,总是以面向过程的思路思考,发现有很多的不同,今天就稍微发表一下我的见解,如果那里出错,希望大神可以帮忙指出来. 首先是const : 在C语法 ...
- 预处理、const、static与sizeof-C++中const有什么作用(至少说出3个)
1:作用如下: (1)const用于定义常量:const定义的常量编译器可以对其进行数据静态类型安全检查. (2)const修饰函数形式的参数:当输入参数为用户自定义类型和抽象数据类型时,应该将“值传 ...
- 在php中定义常量时,const与define的区别?
问]在php中定义常量时,const与define的区别? [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比define快很 ...
- PHP 中 define() 和 const 定义常量时的区别
自 PHP 5.3.0 起,有两种方式定义常量,使用 const 关键字或者 define() 函数: 1 2 const FOO = 'BAR'; define('FOO', 'BAR'); 这 ...
- iOS 中 const static extern 关键字总结
在看一些高手所写的代码时,总是可以看到我们小白平常不用的关键字,一次,两次,三次,不能总是不明不白,现在总结一下日常开发中常用的关键字的作用: 关键字const/static/extern的释义和用法 ...
- 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?采用符号常量写出的代码更容易维 ...
- C++中 容易忽视的const 修饰符
C++可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的有点: (1)const常量有数据类型,而宏常量没有数据类型.编译器可以对const进行类型安全检查,而后者只进行 ...
随机推荐
- idea 修改编辑区字体样式、大小
idea 修改编辑区字体样式.大小 CreateTime--2018年4月26日10:36:59 Author:Marydon 设置-->Editor-->Font-->修改Fo ...
- 谷歌GSON的字符与对象的互转
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; i ...
- Python画图matplotlib展示图中中文乱码
在用python的 matplotlib 画图的时候,在图表上面有中文乱码问题,如下的: 解决过程: 平台:windows,python2.7步骤一:打开设置文件 import matplotlib ...
- Mac下搭建svn服务器和XCode配置svn
先打开命令行终端. 1.创建svn repository svnadmin create /yourpath/svnroot/repository 2.配置svn用户权限. / yourpath /s ...
- IOS 内存优化和调试技巧
基础部分 1: 图片内存大小小结 a: 图片:是占用内存的大户,尤其是手机游戏图片资源众多.对图片资源在内存中占用量的计算成为J2ME游戏开发者的经常性工作,CoCoMo来解释一下如何计算图片在内存中 ...
- C#基础 - C# 的 常见概念简述
在上篇文章中,你跟着我写了一个HelloWorld,本篇中,我们来谈谈一些C#程序中的小概念 1.C# 程序结构 一个 C# 程序主要包括以下部分: 命名空间声明(Namespace declarat ...
- go 学习笔记(4) ---项目结构
go install和go build之争.目前,IDEA插件和LiteIDE都采用了go build.Eclipse插件采用了go install.官方推荐go install方式编译项目,官方项目 ...
- Android调试技巧之Eclipse行号和Logcat
很多初入Android的开发者可能会发现经常遇到Force Close或ANR这样的问题,一般我们通过Android系统的错误日志打印工具Logcat可以看到出错的内容,今天一起来说下如何通过 Ecl ...
- Js 常用函数【持续更新】
Js Math对象方法介绍:http://www.w3school.com.cn/jsref/jsref_obj_math.asp 1. 算数函数(Math) 1)Js小数取整 常用于:分页算法 js ...
- 中国计算机学会CCF推荐国际学术期刊会议(最新版)
中国计算机学会推荐国际学术期刊会议 2014年12月,中国计算机学会(CCF)启动新一轮<)计算机体系结构/高性能计算/存储系统: )计算机网络:)网络与信息安全:)软件工程/系统软件/程序设计 ...