从本章起开始从0学习C++,本章主要内容:

  • 1)C和C++的基本区别
  • 2)C和C++的const区别

1.C++和C区别

1.1 C++更强调语言的实用性,所有变量都可以在需要时再定义

比如:

for(int i=;i<;i++);

1.2 C++不允许定义多个同名全局变量,而C却可以重复定义

1.3 C++的register只是个兼容作用

1.4 C++的所有标识符都必须有声明类型

比如,在C中:

f():  表示默认返回值是int,可以接受任意个int型参数的函数

在C++中:

int f() int f(void)表示都一样,没有参数,返回值为int型的函数

int f(i): 由于i没声明类型,会报错

1.5 结构体升级

例如,在C中定义一个结构体:

typedef student_type student;   //声明
struct student_type{
char *name;
int age;
}; struct student_type student1={"Li",};
/*或者*/
student student2={"Zhang",};

而在C++中,只需要这么写:

struct student_type{
char *name;
int age;
}; student_type student2={"Zhang",}; //不需要strcut再次声明

C和C++的const区别

2. C中的const

2.1 介绍

C语言中的const只是让变量变为只读属性,其本质还是变量,不是真正意义上的常量(只有enum枚举定义的才是常量).

注意:const变量不能被直接赋值,但是可以通过指针来修改const变量.

由于const局部变量会存在栈里,而const全局变量会存在只读存储内存上

所以我们可以通过指针来修改const局部变量,但是修改const全局变量,会使程序崩溃.

2.2修改const实例

1)实例1-通过指针来修改const局部变量

代码如下:

#include <stdio.h>
int main()
{
const int c = ; //const局部变量 int* p = (int*)&c;
*p = ; //通过指针修改const变量 printf("c = %d\n", c);
return ;
}

输出结果:

2)实例2-通过指针来修改const全局变量

代码如下:

#include <stdio.h>
const int c = ; //const全局变量
int main()
{
int* p = (int*)&c;
*p = ; //修改const变量
printf("c = %d\n", c);
return ;
}

输出结果:

由于指针修改只读存储区的数据,所以导致程序崩溃

3. C++中的const

3.1 介绍

在C++中,const变量则是真正的常量了,定义时会将其放入符号表中.

所以编译途中遇到使用const变量时,则直接从符号表中取出常量.

只要当该const变量为全局(使用extern声明过),或者被使用&操作符时,才会被分配存储空间.

接下来,我们以一个例子来分析存储空间

代码如下:

#include <stdio.h>
int main()
{
const int c = ; //const局部变量 int* p = (int*)&c; //使用&操作符,会分配空间 *p = ; printf("c = %d,*p=%d\n", c,*p);
return ;
}

输出结果:

为什么输出结果会有两个不同的值?

这是因为使用&c时,会从符号表中取出c的值,并将0存在一个新的分配空间地址里,所以*p修改的只是分配出来的空间地址内容,而c还是常量.

3.2 const和define区别

是不是感觉C++中的const和 define宏定义一样?其实不一样!

  • const常量:     由编译器处理,它会对const常量进行类型检查和作用域检查
  • define宏定义: 由预处理器处理,直接进行文本替换,不会进行各种检查

(预处理器是执行编译器之前运行的程序,用来删除注释,宏变量转换等)

接下来,我们以一个例子来分析const和define

代码如下:

#include <stdio.h>
void f()
{
#define a 3 //定义宏
const int b = ; //定义局部变量
} int main()
{
f();
printf("a=%d",a); //printf("b=%d",b);
return ;
}

输出结果:

这是因为执行预处理器时,会将遇见到的所有a变为3,所以编译器看到的是printf("a=%d",3);

而取消//printf("b=%d",b); 屏蔽后,程序则会报错,是因为b的作用域只在f()函数里有效.

3.3 指针const

指针const分为两种: 底层const, 顶层const

(普通变量的const(或引用)永远是顶层const,也就是说,const int 和int const本质都一样)

1)底层const(位于*左侧)

常量指针,表示指向的对象是个常量,不能修改其内容,只能更改指针指向的地址.

其实很好理解,比如 const int *p, 修饰*p是个const常量.而*p是指向对象的内容.所以表示指向对象的内容是常量

但是可以通过其它方式修改内容,例如:

int a=,b=;

const int *p=&a;     //底层const

//*p=2;              //错误,无法修改*p指向的a里面内容

a=;                 //正确,通过其它方法来修改*p的内容
printf("%d\n",*p); p=&b; //正确,可以更改指针指向的地址
printf("%d\n",*p);

输出结果:


2)顶层const(位于*右侧)

指针常量,表示不能更改指针指向的地址,只能修改其内容(定义时必须被初始化)

其实很好理解,比如  int * const p, 修饰 p是个const常量.而 p是指向对象的地址.所以表示指向对象的地址是个常量

和引用非常相似,例如:

int a=;
int b=; //int *const p; //错误,没有被初始化 int *const p=&a; //顶层const //p=&b; //错误,不能更改指针指向的地址 *p=; //正确,修改a的值等于2

3.4 顶层const变量可以替代mutable变量

1) mutable介绍

mutable 是为了突破 const 的限制而设置的。被 mutable 修饰的变量,将永远处于可变的状态,即使在一个 const 函数中,甚至结构体变量或者类对象为 const,其 mutable 成员也可以被修改。

示例1:

class Test{

    mutable int mval;
public:
Test():mval()
{
}
void setVal(int num) const
{
mval=num;
cout<<mval<<endl; //打印10,能在const函数中对mutable变量赋值
}
}; int main()
{
const Test t; t.setVal();      }

2)通过const替代后:

class Test{

     int * const mval;
public:
Test():mval(new int())
{
}
void setVal(int num) const
{
*mval=num; //由于mval是const类型,所以修改时不会报错
cout<<*mval<<endl; //打印20
}
}; int main()
{
const Test t;
t.setVal(); }

3.5 volatile const

大家都知道volatile是指对该变量操作时,不能进行优化

1)在c++中,使用volatile const时,编译器不会将其放入常数表,而是以只读变量的形式来定义

例如:

 volatile const int x=;
int *p= (int *)&x; *p=; printf("x=%d\r\n",x);

输出结果:

x=

2) 当使用const时,赋予的值是volatile类型时,也是以只读变量形式,因为编译器不能将该volatile类型的变量优化为一个常量

实例:

volatile  int x=;
const int y=x; //y的值是个volatile型 int *p= (int *)&y; *p=; printf("y=%d\r\n",y);

输出结果:

y=

本章结束,下章来学习:  C++中的bool类型,三目运算符,引用

1.C和C++区别,以及const分析的更多相关文章

  1. [源码解析]HashMap和HashTable的区别(源码分析解读)

    前言: 又是一个大好的周末, 可惜今天起来有点晚, 扒开HashMap和HashTable, 看看他们到底有什么区别吧. 先来一段比较拗口的定义: Hashtable 的实例有两个参数影响其性能:初始 ...

  2. 有关于break,continue,return的区别和代码分析

    今天,用代码和结果直接解释break,continue,return的区别 1.break代码 public static void breakTest() { //break的讲解 for(int ...

  3. String-StringBuffer-StringBuilder的区别和源码分析

    一,String,StringBuffer,StringBuilder三者之间的关系 三个类的关系:StringBuffer和StringBuilder都继承自AbstractStringBuilde ...

  4. 浅谈sql中的in与not in,exists与not exists的区别以及性能分析

    1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的.如果查询的两个表 ...

  5. 第3课 进化后的 const分析

    1.  C语言中的const (1)const修饰的变量是只读的,使得变量具有只读属性,但本质还是变量.所以不是真正的常量,它只是告诉编译器该变量不能出现在赋值符号的左边. (2)const修饰的局部 ...

  6. 三、C++ const分析

    1.C语言中的const: const修饰的变量是只读的,本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在只读存储区分配空间 const只在编译期有用,在运行期无效 c ...

  7. json-lib与Jackson的区别和用法分析

    一.Jackson概述 1.jackson包和版本 Jackson fasterxml和codehaus的区别: 他们是Jackson的两大分支.也是两个版本的不同包名.Jackson从2.0开始改用 ...

  8. 进化后的const分析

    C语言中的const const修饰的变量是只读的,本质还是变量 const修饰的局部变量在栈上分配空间 const修饰的全局变量在只读存储区分配空间 const只在编译期有用,在运行期无用 注意:c ...

  9. oracle中union和union all区别与性能分析

    [ 概要 ] 经常写sql的同学可能会用到union和union all这两个关键词, 可能你知道使用它们可以将两个查询的结果集进行合并, 那么二者有什么区别呢? 下面我们就简单的分析下. [ 比较 ...

随机推荐

  1. bzoj:2331: [SCOI2011]地板

    Description lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西.小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板.现在小L想知道,用 ...

  2. Ugly Numbers(STL应用)

    题目链接:http://poj.org/problem?id=1338 Ugly Numbers Time Limit: 1000MS   Memory Limit: 10000K Total Sub ...

  3. 教你理解微信小程序的生命周期和运行原理

    转自:http://blog.csdn.net/tsr106/article/details/53052879  写微信小程序,他的生命周期不能不知道,不知道小程序就会出现各种bug而无法解决.小助君 ...

  4. 【JSP/Servlet】后台如何获取复选框或可选属性的同名参数

    感觉自己jsp/servlet部分学的太差了--今天突然想到还有这种操作,遂分享之 比如有些时候我们需要使用复选框发送同名数据的时候,后台接收参数是个麻烦事,还有可选属性也是如此 有丰富经验的会想到a ...

  5. 一个php技术栈后端猿的知识储备大纲

    <h1 align="center">Easy Tips</h1><p align="center"><a href= ...

  6. php中PHPMailer发送带附件的电子邮件方法

    摘要: 本文讲的是php中PHPMailer发送带附件的电子邮件方法, .首先到http://phpmailer.worxware.com/ 下载最新版本的程序包 2.下载完成后,找到class.ph ...

  7. ubuontu16.04安装Opencv库引发的find_package()错误信息处理及其简单使用

    在安装完Opencv库之后,打算测试一下Opencv库是否成功安装.下面是用的例子对应的.cpp代码以及对应的CMakeLists.txt代码: .cpp文件: #include <stdio. ...

  8. ThinkPhp 添加模型类

    ----------------------------------------------- <?phpnamespace app\common\model;use traits\model\ ...

  9. xtrabackup全量备份和增(差)量备份

    xtrabackup全量备份和增(差)量备份 1.xtrabackup全量备份和恢复 1)备份: innobackupex --default-file=/PATH/TO/DEFAULT --host ...

  10. JavaScript ECMAScript版本介绍

    1. 介绍 1.1 什么是ECMAScript ECMAScript,简称ES,是由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers ...