|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
在C语言关键字中const举足轻重,我们今天就深度聊一聊const的定义和实际应用,让它不再是迷。
5 i2 j4 l% [: k0 R I0 `( A- {& z5 O
C语言中const关键字是constant的缩写,是恒定不变的意思。通常翻译为常量、常数等,我们一看到const关键字马上就想到了常量。这是不精确的,精确来说应该是只读变量,其值在编译时不能被使用,因为编译器在编译时不知道其存储的内容。那么const推出的初始目的正是为了取代预编译指令,消除它的缺点,同时继承它的优点。
4 Q: R( S+ Z9 |
) C' \# K7 U' J" o9 v! u事实上在C语言中const功能很强大,它可以修饰变量、数组、指针、函数参数等。
/ u& `! o6 U* d' T
' k3 v1 `8 [0 a" M+ G' M+ _# a1 E1、const 修饰的只读变量:
; z! @9 U4 ^1 VC语言中采用const修饰变量,功能是对变量声明为只读特性,并保护变量值以防被修改。8 _% w8 b% F3 _& q1 h+ }0 \$ X
9 Q" O2 H/ J( W/ d ~3 Z例如:% ?. f# ^: s7 z& B6 B- L7 U3 i
const int Max = 100;- q( c; @: Y; w4 y. ]) i- O; D
int Array[Max];! w/ A3 W% n0 w) x" J Z
4 B, l I# G3 p1 G, h0 i5 p5 H
这个大家可以在Visual C++6.0创建一个.c文件测试一下,你会发现在.c文件中编译器会提示出错。我们知道定义一个数组必须指定其元素的个数,这也从侧面证实在C语言中const修饰的Max仍然是变量,只不过是只读属性罢了。; ?5 D" C3 ~5 ^+ D/ g
! e* L0 l9 t& g
还有值得注意的是,定义变量的同时,必须初始化,并且不能再重新赋值。: Y2 X- o" J5 H% M. n
0 W( g9 V% o0 [9 O- I5 s2、节省空间,避免不必要的内存分配,同时提高效率
) d. c6 s3 E% H. N' v. d编译器通常不为普通const只读变量分配存储空间,而是将他们保存在符号表中,这使得它成为一个编译期间的值,没有了存储与读内存的操作,使得它的效率也很高。# O$ B/ f$ N* l
1 V4 b& L6 @ K7 J w7 g( W例如:
" T9 t' \% C! E a9 v5 U#define M 3 //宏常量
7 V1 ^. w" l! J2 I7 t- sconst int N= 5; //此时并未将N放入内存中
$ Z8 l- m4 k7 cint i = N; //此时为N分配内存,以后不再分配1 x& e8 y7 ]6 g8 H ?8 J7 k
int I = M; //预编译期间进行宏替换,分配内存, n0 ]3 C0 n7 e0 B3 e3 f& e
int j = N; //没有内存分配
h9 A# Y9 }* e1 F% H8 u9 [6 Fint J = M; //再进行宏替换,又一次分配内存
# t6 A; u- Z: p% }0 m) a p, b- ~+ I) U3 F }
const定义的只读变量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数。所以,const定义的只读变量在程序运行过程中只有一份备份(因为它是全局的只读变量,存放在静态区),而#define定义的宏常量在内存中有若干个备份。#define宏是在预编译阶段进行替换,而const修饰的只读变量是在编译的时候确定其值。#define宏没有类型,而const修饰的只读变量具有特定的类型。
2 J7 p( t( \. B: `' a( F! g5 [9 f! R# A
3、修饰一般变量
0 N! w7 ?: F% K0 |1 @+ ?! I$ q! c一般变量是指简单类型的只读变量。这种只读变量在定义时,修饰符const可以用在类型说明符前,也可以用在类型说明符后2 M7 A0 g1 Q& D
$ l0 n% {; a, Z例如:6 D* v& x( S% W
int const i = 2; 或 const int i = 2;2 Z/ j: ?8 j2 D) s* X% h
+ F) [. w t {( h5 z4、修饰数组8 W( x- Y, I0 o7 r
C语言中const还可以修饰数组,举例如下:
; T8 X/ G+ x4 ^& U. @" {const int array[5] = {1,2,3,4,5};
; h8 T6 J& C4 q$ m9 u. k: zarray[0] = array[0]+1; //错误/ N {) q& G" o& k
数组元素与变量类似,具有只读属性,不能被更改;一旦更改,如程序将会报错。
4 }! {& S4 _- Z# z: \" `0 y" e5 c3 \; N! X w, S
5、 修饰指针$ {, U* c: j& X" U# _ P
C语言中const修饰指针要特别注意,共有两种形式,一种是用来限定指向空间的值不能修改;另一种是限定指针不可更改。举例说明如下:- J) Q" y9 G: u1 z' R' ] r" W7 h; f
; X* \- T4 ?# P2 m; K8 o; i
Const离谁近修饰谁的原则
- o; x+ e+ w l
6 w* N5 e+ P8 q5 a: V: v例如:
( w [" o k0 j/ u+ n4 W3 Mconst int * p1; //定义1,p1可变,p1指向的对象不可变
, L- g2 Z+ a' x# x1 F9 @% |int * const p2; //定义2,p2不可变,p2指向的对象可变 [+ V3 ?9 J T$ F
) A$ }+ y: r: T% z' K上面定义了两个指针p1和p2。: k/ u' r! y. t3 @
在定义1中const限定的是*p1,即其指向空间的值不可改变,若改变其指向空间的值如*p1=20,则程序会报错;但p1的值是可以改变的,对p1重新赋值如p1=&k是没有任何问题的。2 A- f. E" C& d9 c4 g& y) p
在定义2中const限定的是指针p2,若改变p2的值如p2=&k,程序将会报错;但*p2,即其所指向空间的值可以改变,如*p2=80是没有问题的,程序正常执行。* A4 M3 A3 L! U$ w
/ |- T ?6 g! @" p
6、修饰函数参数0 x3 \8 l0 @4 h J4 u+ ^0 M
const修饰符也可以修饰函数的参数,当不希望这个参数值在函数体内被意外改变时使用。所限定的函数参数可以是普通变量,也可以是指针变量。
5 `) f" F% d( q0 f. b; `2 ?! @* Z. Z) y. }) }2 g( ~9 j+ I1 ]1 R
举例如下:5 k% i1 u+ p5 w1 c" K, N6 g
void fun1(const int i){其它语句……i++; //对i的值进行了修改,程序报错其它语句}2 L! r0 ~$ f$ G! v$ m/ h( B
. {5 V" @4 m0 d) S {7 m! A告诉编译器i在函数体中不能改变,从而防止了使用者的一些无意或者错误的修改。
' E9 ]) i% N. u
; p/ z5 f, V' l8 c0 evoid fun2(const int *p){其它语句……(*p)++; //对p指向空间的值进行了修改,程序报错其它语句}8 |8 F$ x* U* y: b( Z! n" H1 L
$ ^0 W; e# s$ u. O, f
7、修饰函数的返回值
% i: J1 U; ^3 `6 S {) OConst修饰符也可以修饰函数的返回值,返回值不可被改变。
( z; _$ M$ d& H! {
2 Q4 @1 | S A) ~Const int Fun(void);1 {- X+ _- t" ?) h4 Q9 V
! Q1 N3 h+ B8 J& k) w
9 G. y# W% i7 g: j5 \9 F0 h. i
|
|