先测试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. 网路总结01-HTTP协议和NSURLConnection

  2. python之函数用法locals()

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法locals() #locals() #说明:查找局部变量,返回一个名字/值对的字典对 ...

  3. C++ 智能指针Auto_PTR 分析

    C++的动态内存的分配与释放是个挺折磨人的事情,尤其异常分支复杂时(比如一堆try catch中,各catch里需要做delete 掉相关的堆上分配的内存),极有可能产生内存泄露的情况.C++中提供了 ...

  4. EasyUI 条件设置行背景颜色

    数据网格(datagrid)的 rowStyler 函数的设计目的是允许您自定义行样式. rowStyler 函数需要两个参数: rowIndex:行的索引,从 0 开始. rowData:该行相应的 ...

  5. xmlhttp.readyState==4 && xmlhttp.status==200的探究

    作为一个后端人员,很惭愧,对Ajax的使用只局限在功能实现层面的交互,对底层通过XMLHttpRequest对象来使用的知识却没有仔细研究过.现总结如下 1. XMLHttpRequest 对象的相关 ...

  6. 用JS实现任意导航栏的调用

    首先设计一个关于导航的层叠样式表如:body{font-size:12px;font-family:Arial,Helvetica,'宋体',sans-serif;color:#333;backgro ...

  7. 【LeetCode】104. Maximum Depth of Binary Tree (2 solutions)

    Maximum Depth of Binary Tree  Given a binary tree, find its maximum depth. The maximum depth is the ...

  8. Java生成唯一GUID

    GUID(Global unique identifier)全局唯一标识符,它是由网卡上的标识数字(每个网卡都有唯一的标识号)以及 CPU 时钟的唯一数字生成的的一个 16 字节的二进制值. GUID ...

  9. pythonl练习笔记——threading线程中的事件Event

    1 事件Event 使用方法:e = threading.Event() Event对象主要用于线程间通信,确切地说是用于主线程控制其他线程的执行. Event事件提供了三个方法:wait等待.cle ...

  10. PO_已交货PO进行退货(流程)

    2014-06-04 Created By BaoXinjian