《C语言中const的用法.pdf》由会员分享,可在线阅读,更多相关《C语言中const的用法.pdf(7页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、(1)可以定义 const 常量 (2)const 可以修饰函数的参数、返回值.详细内容:1、什么是 const 常类型是指使用类型修饰符 const 说明的类型,常类型的变量或对象的值是不能被更新的。(当然,我们可以偷梁换柱进行更新:)2、为什么引入 const const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。3、cons 有什么主要的作用 (1)可以定义 const 常量,具有不可变性。例如:const int Max=100;int ArrayMax;(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。例如:void f(const
2、int i).编译器就会知道 i 是一个常量,不允许修改;(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变!如(1)中,如果想修改 Max 的内容,只需要:const int Max=you want;即可!(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。还是上面的例子,如果在函数体内修改了 i,编译器就会报错;例如:void f(const int i)i=10;.void f(int i).;(6)可以节省空间,避免不必要的内存分配。例如:#define PI .double i=Pi;.;这样,在调用函数 Fu
3、n 时就不能修改类里面的数据 (9)在另一连接文件中引用 const 常量 extern const int i;抽象 const 对于关键字 const 的解释有好几种方式,最常见的就是位元 const 和 抽象 const。下面我们看一个例子:class A public:.A f(const A&a);.;如果采用抽象 const 进行解释,那就是 f 函数不会去改变所引用对象的抽象值,如果采用位元 const 进行解释,那就成了 f 函数不会去改变所引用对象的任何位元。我们可以看到位元解释正是 c+对 const 问题的定义,const 成员函数不被允许修改它所在对象的任何一个数据成员
4、。为什么这样呢因为使用位元const 有 2 个好处:最大的好处是可以很容易地检测到违反位元 const 规定的事件:编译器只用去寻找有没有对数据成员的赋值就可以了。另外,如果我们采用了位元 const,那么,对于一些比较简单的 const 对象,我们就可以把它安全的放入 ROM 中,对于一些程序而言,这无疑是一个很重要的优化方式。(关于优化处理,我们到时候专门进行讨论)当然,位元 const 也有缺点,要不然,抽象 const 也就没有产生的必要了。首先,位元 const 的抽象性比抽象 const 的级别更低!实际上,大家都知道,一个库接口的抽象性级别越低,使用这个库就越困难。其次,使用位
5、元 const 的库接口会暴露库的一些实现细节,而这往往会带来一些负面效应。所以,在库接口和程序实现细节上,我们都应该采用抽象 const。有时,我们可能希望对 const 做出一些其它的解释,那么,就要注意了,目前,大多数对 const 的解释都是类型不安全的,这里我们就不举例子了,你可以自己考虑一下,总之,我们尽量避免对 const 的重新解释。(3)放在类内部的常量有什么限制 看看下面这个例子:class A private:const int c3=7;.;你认为上面的 3 句对吗呵呵,都不对!使用这种类内部的初始化语法的时候,常量必须是被一个常量表达式初始化的整型或枚举类型,而且必须
6、是 static 和 const 形式。这显然是一个很严重的限制!那么,我们的标准委员会为什么做这样的规定呢一般来说,类在一个头文件中被声明,而头文件被包含到许多互相调用的单元去。但是,为了避免复杂的编译器规则,C+要求每一个对象只有一个单独的定义。如果 C+允许在类内部定义一个和对象一样占据内存的实体的话,这种规则就被破坏了。(4)如何初始化类内部的常量 一种方法就是 static 和 const 并用,在内部初始化,如上面的例子;另一个很常见的方法就是初始化列表:class A public:A(int i=0):test(i)private:const int i;;还有一种方式就是在外
7、部初始化,例如:class A public:A()private:static const int i;.void f(int i).;上面是重载是没有问题的了,那么下面的呢 class A .void f(int i).;这个是错误的,编译通不过。那么是不是说明内部参数的 const 不予重载呢再看下面的例子:class A .void f(int&).;这个程序是正确的,看来上面的结论是错误的。为什么会这样呢这要涉及到接口的透明度问题。按值传递时,对用户而言,这是透明的,用户不知道函数对形参做了什么手脚,在这种情况下进行重载是没有意义的,所以规定不能重载!当指针或引用被引入时,用户就会对
8、函数的操作有了一定的了解,不再是透明的了,这时重载是有意义的,所以规定可以重载。(8)什么情况下为 const 分配内存 以下是我想到的可能情况,当然,有的编译器进行了优化,可能不分配内存。A、作为非静态的类成员时;B、用于集合时;C、被取地址时;D、在 main 函数体内部通过函数来获得值时;E、const 的 class 或 struct 有用户定义的构造函数、析构函数或基类时;。F、当 const 的长度比计算机字长还长时;G、参数中的 const;H、使用了 extern 时。不知道还有没有其他情况,欢迎高手指点:)(9)临时变量到底是不是常量 很多情况下,编译器必须建立临时对象。像其
9、他任何对象一样,它们需要存储空间而且必须被构造和删除。区别是我们从来看不到编译器负责决定它们的去留以及它们存在的细节。对于 C+标准草案而言:临时对象自动地成为常量。因为我们通常接触不到临时对象,不能使用与之相关的信息,所以告诉临时对象做一些改变有可能会出错。当然,这与编译器有关,例如:vc6、vc7 都对此作了扩展,所以,用临时对象做左值,编译器并没有报错。(10)与 static 搭配会不会有问题 假设有一个类:class A public:.static void f()const .;我们发现编译器会报错,因为在这种情况下 static 不能够与 const 共存!为什么呢因为stat
10、ic 没有 this 指针,但是 const 修饰 this 指针,所以.(11)如何修改常量 有时候我们却不得不对类内的数据进行修改,但是我们的接口却被声明了 const,那该怎么处理呢我对这个问题的看法如下:1)标准用法:mutable class A public:A(int i=0):test(i)void SetValue(int i)const test=i;private:mutable int test;/这里处理!;2)强制转换:const_cast class A public:A(int i=0):test(i)void SetValue(int i)const cons
11、t_cast(test)=i;/这里处理!private:int test;;3)灵活的指针:int*class A public:A(int i=0):test(i)void SetValue(int i)const *test=i;private:int*test;/这里处理!;4)未定义的处理 class A public:A(int i=0):test(i)void SetValue(int i)const int*p=(int*)&test;*p=i;/这里处理!private:int test;;注意,这里虽然说可以这样修改,但结果是未定义的,避免使用!5)内部处理:this 指针
12、 class A public:A(int i=0):test(i)void SetValue(int i)const (A*)this)-test=i;/这里处理!private:int test;;6)最另类的处理:空间布局 class A public:A(int i=0):test(i),c(a)private:char c;const int test;int main()A a(3);A*pa=&a;char*p=(char*)pa;int*pi=(int*)(p+4);/利用边缘调整 *pi=5;/此处改变了 test 的值!return 0;虽然我给出了 6 中方法,但是我只是
13、想说明如何更改,但出了第一种用法之外,另外 5 种用法,我们并不提倡,不要因为我这么写了,你就这么用,否则,我真是要误人子弟了:)(12)最后我们来讨论一下常量对象的动态创建。既然编译器可以动态初始化常量,就自然可以动态创建,例如:const int*pi=new const int(10);这里要注意 2 点:1)const 对象必须被初始化!所以(10)是不能够少的。2)new 返回的指针必须是 const 类型的。那么我们可不可以动态创建一个数组呢 答案是否定的,因为 new 内置类型的数组,不能被初始化。这里我们忽视了数组是类类型的,同样对于类内部数组初始化我们也做出了这样的忽视,因为这涉及到数组的问题,我们以后再讨论。