先测试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++中地位不同的更多相关文章

  1. const在C与C++中的区别

    在C中,const不是常量,只能说是一个不能改变的变量(注意是变量),C编译器不能把const看成看成一个编译期间的常量,因为他在内存中有分配,C编译器不知道他在编译期间的值.所以不能作为数组定义时的 ...

  2. const在c和c++中的不同

    最近开始由学习c转到c++:从面向过程到面向对象的转变中,总是以面向过程的思路思考,发现有很多的不同,今天就稍微发表一下我的见解,如果那里出错,希望大神可以帮忙指出来. 首先是const : 在C语法 ...

  3. 预处理、const、static与sizeof-C++中const有什么作用(至少说出3个)

    1:作用如下: (1)const用于定义常量:const定义的常量编译器可以对其进行数据静态类型安全检查. (2)const修饰函数形式的参数:当输入参数为用户自定义类型和抽象数据类型时,应该将“值传 ...

  4. 在php中定义常量时,const与define的区别?

    问]在php中定义常量时,const与define的区别?  [答]使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数.另外const在编译时要比define快很 ...

  5. PHP 中 define() 和 const 定义常量时的区别

    自 PHP 5.3.0 起,有两种方式定义常量,使用 const 关键字或者 define() 函数:   1 2 const FOO = 'BAR'; define('FOO', 'BAR'); 这 ...

  6. iOS 中 const static extern 关键字总结

    在看一些高手所写的代码时,总是可以看到我们小白平常不用的关键字,一次,两次,三次,不能总是不明不白,现在总结一下日常开发中常用的关键字的作用: 关键字const/static/extern的释义和用法 ...

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

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

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

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

  9. C++中 容易忽视的const 修饰符

    C++可以用const定义常量,也可以用#define定义常量,但是前者比后者有更多的有点: (1)const常量有数据类型,而宏常量没有数据类型.编译器可以对const进行类型安全检查,而后者只进行 ...

随机推荐

  1. Adaptive Thresholding & Otsu’s Binarization

    Adaptive Thresholding Adaptive Method - It decides how thresholding value is calculated. cv2.ADAPTIV ...

  2. 科学计算法帮助类MathUtils

    import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; /** * 科学计算 ...

  3. scala中:: , +:, :+, :::, +++的区别

    4种操作符的区别和联系 一. ::   该方法被称为cons,意为构造,向队列的头部追加数据,创造新的列表. 用法为 x::list,其中x为加入到 头部的元素,无论x是列表与否,它都只将成为新生成列 ...

  4. kafka具体解释一、Kafka简单介绍

    背景:      当今社会各种应用系统诸如商业.社交.搜索.浏览等像信息工厂一样不断的生产出各种信息,在大数据时代,我们面临例如以下几个挑战: 怎样收集这些巨大的信息 怎样分析它 怎样及时做到如上两点 ...

  5. Docker镜像仓库Harbor之搭建及配置

    目录 Harbor介绍环境.软件准备Harbor服务搭建Harbor跨数据复制配置FAQ1.Harbor 介绍 Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的 ...

  6. Matlab调用返回游标的存储过程的分析和处理

    2.Matlab调用Oracl带游标参数输出的存储过程 笔者也是将工作之中遇到的问题进行了搜集与整理,才完成该文的编写,希望能帮助到有需要的朋友. 2.1.PLSQL中的存储过程 PROCEDURE ...

  7. HDUOJ----1301 Jungle Roads

    Jungle Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  8. HDUOJ---(4708)Rotation Lock Puzzle

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  9. .net mvc前台如何接收和解析后台的字典类型的数据 二分搜索算法 window.onunload中使用HTTP请求 网页关闭 OpenCvSharp尝试 简单爬虫

    .net mvc前台如何接收和解析后台的字典类型的数据   很久没有写博客了,最近做了一个公司门户网站的小项目,其中接触到了一些我不会的知识点,今日事情少,便记录一下,当时想在网上搜索相关的内容,但是 ...

  10. DBA_实践指南系列9_Oracle Erp R12应用补丁AutoPatch/AutoControl/AutoConfig(案例)

    2013-12-09 Created By BaoXinjian