C++中const的实现细节介绍(C,C#同理)

1、什么是const? 
常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁换柱进行更新:)

2、为什么引入const? 
const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

3、cons有什么主要的作用?

(1)可以定义const常量,具有不可变性。 例如: 
const int Max=100; int Array[Max];

(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。例如: void f(const int i) { .........} 编译器就会知道i是一个常量,不允许修改; (3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!如(1)中,如果想修改Max的内容,只需要:const int Max=you want;即可!

(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。 还是上面的例子,如果在函数体内修改了i,编译器就会报错; 例如: 
void f(const int i) { i=10;//error! }

(5) 为函数重载提供了一个参考。 
class A { ...... 
void f(int i) {......} //一个函数 
void f(int i) const {......} //上一个函数的重载 ...... 
};

(6) 可以节省空间,避免不必要的内存分配。 例如: 
#define PI 3.14159 //常量宏 
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ...... 
double i=Pi; //此时为Pi分配内存,以后不再分配! 
double I=PI; //编译期间进行宏替换,分配内存 
double j=Pi; //没有内存分配 
double J=PI; //再进行宏替换,又一次分配内存! 
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。

(7) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

4、如何使用const? 

(1)修饰一般常量 一般常量是指简单类型的常量。这种常量在定义时,修饰符const可以用在类型说明符前,也可以用在类型说明符后。 例如: 
int const x=2; 或 const int x=2;

(2)修饰常数组 定义或说明一个常数组可采用如下格式:  
int const a[5]={1, 2, 3, 4, 5};  
const int a[5]={1, 2, 3, 4, 5};

(3)修饰常对象 常对象是指对象常量,定义格式如下: 
class A; const A a; 
A const a; 定义常对象时,同样要进行初始化,并且该对象不能再被更新,修饰符const可以放在类名后面,也可以放在类名前面。

(4)修饰常指针 
const int *A; //const修饰指向的对象,A可变,A指向的对象不可变 
int const *A; //const修饰指向的对象,A可变,A指向的对象不可变 
int *const A; //const修饰指针A, A不可变,A指向的对象可变 
const int *const A;//指针A和A指向的对象都不可变

(5)修饰常引用 使用const修饰符也可以说明引用,被说明的引用为常引用,该引用所引用的对象不能被更新。其定义格式如下:  
const double & v;

(6)修饰函数的常参数 const修饰符也可以修饰函数的传递参数,格式如下: 
void Fun(const int Var); 告诉编译器Var在函数体中的无法改变,从而防止了使用者的一些无意的或错误的修改。

(7)修饰函数的返回值: const修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下: 
const int Fun1(); const MyClass Fun2();

(8)修饰类的成员函数: const修饰符也可以修饰类的成员函数,格式如下: 
class ClassName { 
public:  
int Fun() const; ..... 
};
这样,在调用函数Fun时就不能修改类里面的数据

(9)在另一连接文件中引用const常量 
extern const int i;//正确的引用 
extern const int j=10;//错误!常量不可以被再次赋值 另外,还要注意,常量必须初始化! 例如: const int i=5;

所谓C++编译器,C++编译器是C++中的一个与标准化高度兼容的编译环境,编译器对不同的CPU会进行不同的优化,下面说明C++编译器进行Const常量分配存储空间的说明介绍。

Const 是C++中常用的类型修饰符,有某些微妙的应用场合,如果没有搞清本源,则错误在所难免。本篇中将对const进行辨析。溯其本源,究其实质,希望能对大家理解const有所帮助,根据思维的承接关系,分为如下几个部分进行阐述。C++的提出者当初是基于什么样的目的引入(或者说保留)const关键字呢?,这是一个有趣又有益的话题,对理解const很有帮助。

1. 大家知道,C++有一个类型严格的编译系统,这使得C++程序的错误在编译阶段即可发现许多,从而使得出错率大为减少,因此,也成为了C++与C相比,有着突出优点的一个方面。

2. C++中很常见的预处理指令 #define VariableName VariableValue 可以很方便地进行值替代,这种值替代至少在三个方面优点突出:一是避免了意义模糊的数字出现,使得程序语义流畅清晰。

二是可以很方便地进行参数的调整与修改,如上例,当人数由107变为201时,进改动此处即可,三是提高了程序的执行效率,由于使用了预编译器进行值替代,并不需要为这些常量分配存储空间,所以执行的效率较高。鉴于以上的优点,这种预定义指令的使用在程序中随处可见。

3. 说到这里,大家可能会迷惑上述的1点、2点与const有什么关系呢?,好,请接着向下看来:

预处理语句虽然有以上的许多优点,但它有个比较致命的缺点,即,预处理语句仅仅只是简单值替代,缺乏类型的检测机制。这样预处理语句就不能享受C++严格类型检查的好处,从而可能成为引发一系列错误的隐患。

4.好了,第一阶段结论出来了:

结论: Const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。

现在它的形式变成了:

Const DataType VariableName = VariableValue ;为什么const能很好地取代预定义语句?const 到底有什么大神通,使它可以振臂一挥取代预定义语句呢?

1. 首先,以const 修饰的常量值,具有不可变性,这是它能取代预定义语句的基础。

2. 第二,很明显,它也同样可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。

3. 第三,C++的编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高,同时,这也是它取代预定义语句的重要基础。

这里,我要提一下,为什么说这一点是也是它能取代预定义语句的基础,这是因为,编译器不会去读存储的内容,如果编译器为const分配了存储空间,它就不能够成为一个编译期间的常量了。

4. 最后,const定义也像一个普通的变量定义一样,它会由编译器对它进行类型的检测,消除了预定义语句的隐患。

我们也许学习过const的使用,但是对于const的细致的技术细节却不一定掌握。const的用法在许多的教材上只是简单的介绍,在这里我们对 const进行细致的概念以及用法剖析。const 是由c++采用,并加进标准c中,但是他们的意义完全不同,在旧版本(标准前)的c中,如果想建立一个常量,必须使用预处理器:
#define PI 3.14159

此后无论在何处使用PI,都会被预处理器以3.14159替代。编译器不对PI进行类型检查,也就是说可以不受限制的建立宏并用它来替代值,如果使用不慎,很可能由预处理引入错误,这些错误往往很难发现。

我们也不能得到PI的地址(即不能向PI传递指针和引用)。
c++引入了命名常量的概念,命名常量就像变量一样,只是它的值不能改变,如果试图改变一个const 对象,编译器将会产生错误。 const 和正常变量一样有作用域,所以函数内部的const也不会影响程序的其余部分。在c++中const可以取代预处理器#define来进行值替代, const有安全的类型检查,所以不用担心会像预处理器一样引入错误。

在通常的情况下const同预处理器#define一样只是将所赋值保存入编译器的符号表中(符号表仅仅在编译时存在,在编译过程中编译器将程序中的名字与之在符号表中定义的数值作简单的替换),在使用的时候进行值替换,并不为const创建存储空间。我们将const的定义放进头文件里,这样通过包含头文件,可以把const定义单独放在一个地方并把它分配给一个编译单元,const默认为内部连接(内部连接意味着只对正在编译的文件创建存储空间,别的文件可以使用相同的标示符和全局变量,编译器不会发现冲突,外部连接意味着为所有被编译过的文件创建一片单独的存储空间,一般全局变量和函数名的外部连接通过extern声明,可以通过其他的文件访问)也就是说const仅能被它所定义过的文件访问,在定义一个const时,必须赋一个值给它,除非用extern做出说明:

extern const int a;

这表示const的定义在其他的什么地方,这里仅仅是一个声明,但是这样的做法使const使用了外部连接,也就是说上面的extern强制进行了对const的存储空间分配,这样我们就无法再用const作为常量折叠(在可能的情况下,符号常量的值会代替改名字的出现,这个替代过程叫做常量折叠)使用了,即使我们在其他地方定义了const的值,如:

extern const int a=3;

因为const的值被放入了存储单元,在编译的过程中,编译器不会去读存储单元的内容。如果我们这样做:

int b[a];

编译器就会给我们一个错误信息。

想不为const分配存储空间是不可能的,因为对于复杂的结构,例如集合,编译器不会复杂到将集合保存到它的符号表中,所以必须分配内存空间,这就意味着“这是一块不能改变的存储空间”,当然也就不能在编译期间使用它的值,因为编译器不知道存储的内容:

const int i[]={1,2,3,4};

//float f[i[2]];
//将得到错误信息,编译器提示不能在数组定义里找到一个常数表达式。

因为编译器靠移动栈指针来存储和读取数据。
也因此,由于无法避免为const分配内存,所以const的定义必须默认为内部连接,否则由于众多的const在多个文件中分配内存,就会引起错误。下面我们看一段简单有效的代码来说明const的常量折叠:


代码如下:

#include <iostream.h>
const int a=3;
const int b=a+1;
float *f=(float*)&b;
char c[b+3];
void main()
{
const char gc=cin.get();
const char c2=gc+3;
}

我们可以看到,a是一个编译器期间的const,b是从a中计算出来的,由于a是一个const,b的计算值来自一个常数表达式,而它自身也是一个编译器间的const,接着下面指针f取得了b的地址,所以迫使编译器给b分配了存储空间,不过即使分配了存储空间,由于编译器已经知道了b的值,所以仍然不妨碍在决定数组c的大小时使用b。

在主函数main()里,标识符gc的值在编译期间是不知道的,这也意味着需要存储空间,但是初始化要在定义点进行,而且一旦初始化,其值就不能改变,我们发现c2是由gc计算出来的,它的作用域与其他类型const的作用域是一样的,这是对#define用法的一种改进。

在c++引进常量的时候,标准c也引入了const,但是在c中const的意思和在c++中有很大不同,在c中const的意思是“一个不能改变的普通变量”,const常量总是被分配存储空间而且它的名字是全局符即const使用外部连接。于是在c中:

const int size=100;
char c[size];

得出一个错误。但是在c中可以这样写:

const int size;

因为c中的const被默认为外部连接,所以这样做是合理的。
在c语言中使用限定符const不是很有用,如果希望在常数表达式里(必须在编译期间被求值)使用一个已命名的值,必须使用预处理器#define。

在c++中可以使指针成为const,这很有用,如果以后想在程序代码中改变const这种指针的使用,编译器将给出通知,这样大大提高了安全性。在用带有const的指针时,我们有两种选择:const修饰指针指向的对象,或者const修饰指针自己指向的存储空间。

如果要使指向的对象不发生改变,则需要这样写:

const int *p;

这里p是一个指向const int 的指针,它不需要初始化,因为p可以指向任何标识符,它自己并不是一个const,但是它所指的值是不能改变的,同样的,我们可以这样写:

int const *p;

这两种方法是等同的,依据个人习惯以及编码风格不同,程序员自己决定使用哪一种形式。
如果希望使指针成为一个const必须将const标明的部分放在*右边。

int a=3;
int *const j=&a

编译器要求给它一个初始值,这个值在指针的生命期间内不变,也就是说指针始终指向a的地址,不过要改变它地址中的值是可以的:

*j+=4;

也可以是一个const指针指向一个const对象:
const int *j1=&a;
int const *j2=&a;

这样指针和对象都不能改变,这两种形式同样是等同的。在赋值的的时候需要注意,我们可以将一个非const的对象地址赋给一个const指针,但是不能将一个const对象地址赋给一个非const指针,因为这样可能通过被赋值的指针改变对象的值,当然也可以用类型的强制转换来进行const对象的赋值,但是这样做打破了const提供的安全性。

const也被用于限定函数参数和函数的返回值,如果函数参数是按值传递时,即表示变量的初值不会被函数改变,如果函数的返回值为const那么对于内部类型来说按值返回的是否是一个cosnt是无关紧要的,编译器不让它成为一个左值,因为它是一个值而不是一个变量,所以使用const是多余的,例如:
const int f(){return 1;}
void main(){int a=f();}

但是当处理用户定义类型的时候,按值返回常量就很有意义了,这时候函数的返回值不能被直接赋值也不能被修改。仅仅是非const返回值能作为一个左值使用,但是这往往失去意义,因为函数返回值在使用时通常保存为一个临时量,临时量被作为左值使用并修改后,编译器将临时量清除。结果丢失了所有的修改。
可以用const限定传递或返回一个地址(即一个指针或一个引用):


代码如下:

const int * const func(const int *p)
{ static int a=*p;
return &a;
}

参数内的const限定指针p指向的数据不能被改变,此后p的值被赋给静态变量a,然后将a的地址返回,这里a是一个静态变量,在函数运行结束后,它的生命期并没有结束,所以可以将它的地址返回。因为函数返回一个const int* 型,所以函数func的返回值不可以赋给一个非指向const的指针,但它同时接受一个const int * const和一个const int *指针,这是因为在函数返回时产生一个const临时指针用以存放a的地址,所以自动产生了这种原始变量不能被改变的约定,于是*右边的const只有当作左值使用时才有意义。

const同样运用于类中,但是它的意义又有所不同,我们可以创建const的数据成员,const的成员函数,甚至是const的对象,但是保持类的对象为const比较复杂,所以const对象只能调用const成员函数。

const的数据成员在类的每一个对象中分配存储,并且一旦初始化这个值在对象的生命期内是一个常量,因此在类中建立一个const数据成员时,初始化工作必须在构造函数初始化列表中。如果我们希望创建一个有编译期间的常量成员,这就需要在该常量成员的前面使用static限定符,这样所有的对象都仅有一个实例:


代码如下:

class X
{
static const int size=50;
int a[size];
public:
X();
};

const对象只能调用const成员函数,一个普通对象同样可以调用const成员函数,因此,const成员函数更具有一般性,但是成员函数不会默认为const。声明一个const成员函数,需要将const限定符放在函数名的后面:

void f (void ) const;

当我们运用const成员函数时,遇到需要改变数据成员,可以用mutable进行特别的指定:


代码如下:

class X
{
mutable int i;
public:
X();
void nochange() const;
};

void X::nochange const(){i++;}

const消除了预处理器的值替代的不良影响,并且提供了良好的类型检查形式和安全性,在可能的地方尽可能的使用const对我们的编程有很大的帮助。

小结:

const int i=10;//这个类似宏替换,也就是说,它优化之后可能是放一个符号表里面。所有使用i的地方都用10代替,但是当你对i取址后,没办法,编译器必须为i在常量区找个地方安身。这就是所谓的常量折叠.

内容取自互联网与《C++编程思想》

(0)

相关推荐

  • C#基础:基于const与readonly的深入研究

    •readonly和const都是用来标识常量的[1].•const可用于修饰class的field或者一个局部变量(local variable):而readonly仅仅用于修饰class的field.•const常量的值必定在编译时就已明确并且恒定的:而readonly常量却有一点不同,那就是其值可以在运行时编译,当然,它也必须遵守作为常量的约束,那就是值必须恒定不变.•const常量必须在声明的同时对其进行赋值,并且确保该值在编译时可确定并恒定:而readonly常量则可以根据情况选择在声

  • asp.net TextBox控件设置ReadOnly后,不能回传。

    很奇怪,以前都没有过这样的怪问题,在别人机器上都能正常,想到可能和ASP.NET的版本有关系. 我用的是 ASP.NET 2.0,当改成 ASP.NET 1.0,就正常了,TextBox控件ReadOnly=True,能回传. 在 ASP.NET 1.0 中是ReadOnly=True会回传的. 在 ASP.NET 2.0 中是ReadOnly=True就不会回传了. 解决的方法: <asp:textbox id="Username" runat="server&quo

  • C#中const用法详解

    本文实例讲述了C#中const用法.分享给大家供大家参考.具体用法分析如下: const是一个c语言的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的安全性和可靠性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助.另外const在其他编程语言中也有出现,如c++.php5.c#.net.hc08 c const 一般修饰 的变量为只读变量 const定义应该为在定义的时候初始化 以后不能改变他的值 例: 复制代码 代码如下: c

  • C#中 const 和 readonly 的不同

    const 的概念就是一个包含不能修改的值的变量.常数表达式是在编译时可被完全计算的表达式.因此不能从一个变量中提取的值来初始化常量.如果 const int a = b+1;b是一个变量,显然不能再编译时就计算出结果,所以常量是不可以用变量来初始化的. readonly 允许把一个字段设置成常量,但可以执行一些运算,可以确定它的初始值.因为 readonly 是在计算时执行的,当然它可以用某些变量初始化.readonly 是实例成员,所以不同的实例可以有不同的常量值,这使readonly更灵活

  • ASP.NET中readonly与const的区别详解

    const是一个修饰常量的关键字,它限定一个变量不允许被改变.使用const在一定程度上可以提高程序的安全性和可靠性,它在程序设计中有着非常重要的作用,给开发人员带来非常方便的应用. 下面我们来建一个控制台应用程序作测试: public class Test { public readonly string name = "George"; public const string coname = "ABC Company LLC"; public Test(str

  • 浅谈c#中const与readonly区别

    const 的概念就是一个包含不能修改的值的变量. 常数表达式是在编译时可被完全计算的表达式.因此不能从一个变量中提取的值来初始化常量. 如果 const int a = b+1;b是一个变量,显然不能再编译时就计算出结果,所以常量是不可以用变量来初始化的. readonly 允许把一个字段设置成常量,但可以执行一些运算,可以确定它的初始值. 因为 readonly 是在计算时执行的,当然它可以用某些变量初始化. readonly 是实例成员,所以不同的实例可以有不同的常量值,这使readonl

  • C#基础知识系列八const和readonly关键字详细介绍

    前言 不知道大家对const和readonly这两个关键字的区别有什么了解,原来自己之前还真不清楚它们到底是怎么回事,那么如果你也不是很清楚的话,可以一起来探讨一下.在了解这两个关键字的时候我们先来了解一下静态常量和动态常量. 静态常量:是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值. 而动态常量的值则是在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明的时候就初始化,而可以延迟到构造函数中初始化.现在再来说明const与

  • 深入探讨C#中的const、readonly关键字

    首先不可否认,这些在面试上会经常被面试官问起,但是你回答的让面试官满意吗?当然如果你知道了这些原理,或许你就不 怕了.既然说到了原理,我们还是从MSDN说起. 一:值得推敲的几个地方 1.先来看看msdn上面对const是怎么说的,我们会看到.不能修改,编译时常量这些关键性信息. Q:  const为什么不能被修改. A:这个很简单,很多教科书上面都说,当编译器编译时,会将常量的值保存在该程序集的元数据中,下面我们做个实例 看一看. ①:新建一个projectA. 复制代码 代码如下: // P

  • c#.net中const和readonly的区别

    (1) readonly和const都是用来标示常量的.(2) 初始化赋值不同.const修饰的常量必须在声明的同时赋值.例如: 复制代码 代码如下: public class Class1{    public const int MaxValue = 10;       //正确声明    public const MInValue;                   //错误:常量字段要求提供一个值    public Class1()    {        MinValue = 10

  • C++中const的实现细节介绍(C,C#同理)

    1.什么是const?  常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(当然,我们可以偷梁换柱进行更新:) 2.为什么引入const?  const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点. 3.cons有什么主要的作用? (1)可以定义const常量,具有不可变性. 例如:  const int Max=100; int Array[Max]; (2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患.例如:

  • C++中const修饰符的详解及其作用介绍

    目录 概述 常对象 常对象成员 常成员函数 常数据成员 数据成员访问限制 常对象修改的限制 常指针 指向常变量的指针 指向对象的指针 小结 对象的常引用 总结 概述 const 是 constant 的缩写, 是不变的意思. 在 C++ 中是用来修饰内置类型变量, 自定义对象, 成员函数, 返回值, 函数参数. const 可以帮我们避免无意之中的错误操作. 使用 const, 把有关的数据定义为常量 (常变量 / 常对象 / 常函数). const 既可以使数据在一定范围内共享, 又要保证它不

  • JavaScript中分号的一些细节

    前言 JavaScript 中的分号是可选的,加不加分号主要是个代码风格问题.一种风格是使用分号明确结束语句,即便这些分号不是必需的:另一种风格是尽可能的不加分号,只在必要的情况才加.我个人就不喜欢加分号,当然喜欢加分号的朋友也不少.无论你喜欢哪种风格,都需要了解了解 JavaScript 中的分号的一些细节. 代码中分号的作用 分号的主要作用是:作为语句的断言(EOS)用于结束一个程序语句,目的是让解析器正确解析程序.在很多 C-Style 语言里,用分号明确结束一行语句,主要是为了降低语言编

  • 详解lodash中的cloneDeep使用细节

    目录 正文 支持的数据类型 cloneDeepWith 拷贝算法介绍 structuredClone VS cloneDeep 循环引用处理方法 总结 正文 lodash中的cloneDeep是一个使用频率比较高的方法,然而你真的理解其中的细节处理吗?如果下面几个问题你还有疑惑那么本文对你或多或少有些帮助. cloneDeep中支持拷贝函数.Error对象.DOM节点以及WeakMap对象吗? cloneDeep中使用了哪种算法呢? 浏览器中提供的实现深拷贝的方式除了JSON.parse(JSO

  • C++中const用于函数重载的示例代码

    常成员函数和非常成员函数之间的重载 首先先回忆一下常成员函数 声明:<类型标志符>函数名(参数表)const: 说明: (1)const是函数类型的一部分,在实现部分也要带该关键字. (2)const关键字可以用于对重载函数的区分. (3)常成员函数不能更新类的成员变量,也不能调用该类中没有用const修饰的成员函数,只能调用常成员函数. (4)非常量对象也可以调用常成员函数,但是如果有重载的非常成员函数则会调用非常成员函数. 重载看例子: #include<iostream> u

  • 详解C/C++中const关键字的用法及其与宏常量的比较

    1.const关键字的性质 简单来说:const关键字修饰的变量具有常属性. 即它所修饰的变量不能被修改. 2.修饰局部变量 const int a = 10; int const b = 20; 这两种写法是等价的,都是表示变量的值不能被改变,需要注意的是,用const修饰变量时,一定要给变量初始化,否则之后就不能再进行赋值了,而且编译器也不允许不赋初值的写法: 在C++中不赋初值的表达一写出来,编译器即报错,且编译不通过. 在C中不赋初值的表达写出来时不报错,编译时只有警告,编译可以通过.而

  • C#中const 和 readonly 修饰符的用法详解

    1. 只有C#内置类型(int,double,long等)可以声明为const;结果.类和数组不能声明为const. 2. readonly 是在字段上使用的修饰符,直接以类名.字段访问. 3. const 必须在申明中初始化.之后不能再修改. 4. readonly可以在申明中初始化,也可以在构造函数中初始化,其它情况不能修改. namespace const_and_readonly { class Program { static void Main(string[] args) { Co

  • JavaScript中const、var和let区别浅析

    在JavaScript中有三种声明变量的方式:var.let.const.下文给大家介绍js中三种定义变量的方式const, var, let的区别. 1.const定义的变量不可以修改,而且必须初始化. const b = 2;//正确 // const b;//错误,必须初始化 console.log('函数外const定义b:' + b);//有输出值 // b = 5; // console.log('函数外修改const定义b:' + b);//无法输出 2.var定义的变量可以修改,

  • C/C++中CONST用法总结(推荐)

    1.修饰常量时: const int temp1; //temp1为常量,不可变 int const temp2; //temp2为常量,不可变 2.修饰指针时: 主要看const在*的前后,在前则指针指向的内容为常量,在后则指针本身为常量: const int *ptr; //*ptr为常量: int const *ptr; //*ptr为常量: int* const ptr; //ptr为常量: const int * const ptr; //*ptr.ptr均为常量: 3.const修饰

  • 详解C/C++中const限定符总结

    const限定符 const是一种限定符,被const所限定的变量其值不可以被改变. const的初始化 由于const一旦创建其值就不能够被改变,所以我们必须对其进行初始化 const int a;//错误,const变量必须进行初始化! const int b=10;//正确,编译时初始化 const int c=get_size();//正确,运行时初始化 相同类型的变量相互初始化时,不论变量是否被const限定我们都可以进行随意的相互拷贝.因为在拷贝过程中我们只会用到等式右边变量的右值属

随机推荐