C语言之正确使用Const
基本解释
; C8 q4 A' V/ [" }: u7 K f电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站我爱电脑技术社区--打造最好的电脑技术自学交流平台8 P* T( `2 d6 F$ ~
const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的健壮性,另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。
# x1 P% N) Y! h( G* E我爱电脑技术社区--打造最好的电脑技术自学交流平台8 \ _+ C; k/ r7 ?
虽然这听起来很简单,但实际上,const的使用也是c语言中一个比较微妙的地方,微妙在何处呢?请看下面几个问题。打造最好的电脑自学交流论坛! ~7 s- Z% [% E7 l, c, K6 q4 F+ C
8 {: X7 u! Y# O, o* {9 t打造最好的电脑自学交流论坛 问题:const变量 & 常量
5 [6 @# P# ~# A, s8 F" f8 kwww.520diannao.com
: ~' `+ m. n% L! w6 {电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 为什么我象下面的例子一样用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?www.520diannao.com+ n+ x X9 V; z7 h9 h6 C
" k. m2 [2 f4 ^$ V1 ~3 D3 v我爱电脑技术社区--打造最好的电脑技术自学交流平台 const int n = 5;打造最好的电脑自学交流论坛8 R9 t* g, P8 x; e% V, {
int a[n];
+ \) i7 M* Y) v5 D8 q6 }. @我爱电脑技术论坛www.520diannao.com' s$ r9 h0 S& A. N* H2 r( ^
答案与分析:电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站0 i% |3 h0 o* p: k* G; `: `5 d2 u! S
www.520diannao.com1 [9 k O7 d+ O' |. X' U( m2 {
1)、这个问题讨论的是“常量”与“只读变量”的区别。常量肯定是只读的,例如5, “abc”,等,肯定是只读的,因为程序中根本没有地方存放它的值,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时维度必须是“常量”,“只读变量”也是不可以的。我爱电脑技术论坛: z: ]6 q9 B: R, Q
打造最好的电脑自学交流论坛. w4 g0 A5 B+ _, C" K, R2 l7 y
2)、注意:在ANSI C中,这种写法是错误的,因为数组的大小应该是个常量,而const int n,n只是一个变量(常量 != 不可变的变量,但在标准C++中,这样定义的是一个常量,这种写法是对的),实际上,根据编译过程及内存分配来看,这种用法本来就应该是合理的,只是ANSI C对数组的规定限制了它。
( l; i& Y6 E2 I电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
7 D' R; @" a: Z' O+ D0 _0 ?电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 3)、那么,在ANSI C 语言中用什么来定义常量呢?答案是enum类型和#define宏,这两个都可以用来定义常量。6 X9 G6 ] L; t3 B. ? K
$ N# V. _% x% v" L6 g+ L7 Qwww.520diannao.com 问题:const变量 & const 限定的内容
* y4 t! e3 x/ Q2 z& P我爱电脑技术社区--打造最好的电脑技术自学交流平台
4 f8 k0 g7 C( {9 p3 K打造最好的电脑自学交流论坛 下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢?我爱电脑技术论坛, s5 T; H. i) {$ G
1 v/ c' a5 S) h# Y打造最好的电脑自学交流论坛 typedef char * pStr;电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站( A, w4 h" K- h8 l" C
char string[4] = "abc";
: z% h7 u2 ?5 p' |3 Y; b我爱电脑技术社区--打造最好的电脑技术自学交流平台 const char *p1 = string;
. v; `3 {' N' P" u" J) K我爱电脑技术社区--打造最好的电脑技术自学交流平台 const pStr p2 = string;
/ {" @% G% l0 c4 K电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 p1++;
- T5 g% o* \/ s9 r( j; F我爱电脑技术论坛 p2++;
" V, w2 x5 h% i1 o- h我爱电脑技术社区--打造最好的电脑技术自学交流平台打造最好的电脑自学交流论坛+ T5 y% S7 S3 Z$ W2 k1 p% _
答案与分析:
8 a0 ~! x& x/ B& T. p电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
' \1 A# W/ j: O, x& V* j我爱电脑技术社区--打造最好的电脑技术自学交流平台 问题出在p2++上。电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站& U8 K) j4 O5 Q$ S1 ?, _9 ~ _
9 k" x: r/ a) d6 F8 o 1)、const使用的基本形式: const char m;1 i! L- _9 w- T. g1 z$ T2 c
我爱电脑技术社区--打造最好的电脑技术自学交流平台! n( ?( N0 ~0 J- L0 U0 J
限定m不可变。
& ]5 R, ~) w1 k) s9 {2 @电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
v+ H }/ P: z/ ^ C打造最好的电脑自学交流论坛 2)、替换1式中的m, const char *pm;我爱电脑技术社区--打造最好的电脑技术自学交流平台% q# a( X" J6 E/ N1 ^4 U6 p: M7 \
, G! N0 n ]2 y3 r电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 限定*pm不可变,当然pm是可变的,因此问题中p1++是对的。我爱电脑技术社区--打造最好的电脑技术自学交流平台% u, |& V+ [7 k4 R" o
+ m4 k$ l7 D3 I我爱电脑技术社区--打造最好的电脑技术自学交流平台 3)、替换1式char, const newType m;www.520diannao.com# J' Z- @ b8 N
3 y, b- B- Y2 h' K) T打造最好的电脑自学交流论坛 限定m不可变,问题中的charptr就是一种新类型,因此问题中p2不可变,p2++是错误的。
( K( j7 z/ j" f打造最好的电脑自学交流论坛8 s, P+ ?9 A. J( a
问题:const变量 & 字符串常量
9 u6 F7 u7 o7 X4 i$ l. Z Zwww.520diannao.com
! _! O* L$ X5 z! t; J; Q我爱电脑技术论坛 请问下面的代码有什么问题?8 d* a1 {1 {5 e+ p7 i1 d R2 {- s) h
: }+ m- n4 D, q8 Zwww.520diannao.com char *p = "i'm hungry!";
& A f. |" W" m0 a* | p[0]= 'I';
* t* ` j- {4 e, k3 ?$ s5 b" j我爱电脑技术论坛" e* E' V% p% k" ~, Y
答案与分析:电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站- [4 `+ }7 O3 F' |5 X7 L& K
& U$ h$ }; L/ B, { V' o4 H( R我爱电脑技术论坛 上面的代码可能会造成内存的非法写操作。分析如下, “i'm hungry”实质上是字符串常量,而常量往往被编译器放在只读的内存区,不可写。p初始指向这个只读的内存区,而p[0] = 'I'则企图去写这个地方,编译器当然不会答应。
+ G F- E+ J% H: x9 N% j" s我爱电脑技术社区--打造最好的电脑技术自学交流平台我爱电脑技术社区--打造最好的电脑技术自学交流平台( _' Q/ q6 @$ N' b2 h
问题:const变量 & 字符串常量2电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站1 \ A- `4 z; @0 l1 I, m$ c' h
' H4 R3 p S$ u. s) l8 p! X打造最好的电脑自学交流论坛 请问char a[3] = "abc" 合法吗?使用它有什么隐患?我爱电脑技术社区--打造最好的电脑技术自学交流平台2 s( D2 Q8 G" Z# t9 T' E& J
我爱电脑技术论坛! `& h) S7 ?( `" H% z. `
答案与分析:打造最好的电脑自学交流论坛; o" {% i: n W; ^& B
我爱电脑技术社区--打造最好的电脑技术自学交流平台( a- m' ?/ x) @7 d5 K( y
在标准C中这是合法的,但是它的生存环境非常狭小;它定义一个大小为3的数组,初始化为“abc”,,注意,它没有通常的字符串终止符'\0',因此这个数组只是看起来像C语言中的字符串,实质上却不是,因此所有对字符串进行处理的函数,比如strcpy、printf等,都不能够被使用在这个假字符串上。
/ J" F: Z% n8 ]6 }0 n6 [我爱电脑技术论坛
, z* T b4 H4 d% S1 L5 P/ @电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站 问题5:const & 指针
" V0 a* L! M0 l) @( P# [9 v! Jwww.520diannao.com
! H' Z8 v5 s! ?5 O& e我爱电脑技术社区--打造最好的电脑技术自学交流平台 类型声明中const用来修饰一个常量,有如下两种写法,那么,请问,下面分别用const限定不可变的内容是什么?
N, s% y# U3 z7 @电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站% J9 ~$ m$ d; G5 A }
1)、const在前面我爱电脑技术论坛+ X4 Z8 P: ~6 F7 @
/ E3 [7 Q, C) B打造最好的电脑自学交流论坛 const int nValue; //nValue是const打造最好的电脑自学交流论坛2 s: U: }9 x# O/ ^& k9 \7 c6 U
const char *pContent; //*pContent是const, pContent可变打造最好的电脑自学交流论坛' a: Z. K# k8 m! k
const (char *) pContent;//pContent是const,*pContent可变
( g) c3 H" a0 ?0 r" Q7 xwww.520diannao.com char* const pContent; //pContent是const,*pContent可变我爱电脑技术社区--打造最好的电脑技术自学交流平台% a4 o1 `1 f9 q
const char* const pContent; //pContent和*pContent都是const
8 G8 W8 g! |, p" D) X. Z我爱电脑技术社区--打造最好的电脑技术自学交流平台
8 G" y1 s( r2 j8 a; w J( Jwww.520diannao.com 2)、const在后面,与上面的声明对等8 U. u8 z' {* t+ s5 w. G* {( @
$ u3 m4 z' {* O' [( G我爱电脑技术论坛 int const nValue; // nValue是const打造最好的电脑自学交流论坛5 M$ Q! q6 @/ I. P' a+ g2 @
char const * pContent;// *pContent是const, pContent可变
) l9 {$ H7 p" U! o/ g打造最好的电脑自学交流论坛 (char *) const pContent;//pContent是const,*pContent可变
7 f, `" k8 m. m* {$ U9 ^: }% H$ S我爱电脑技术论坛 char* const pContent;// pContent是const,*pContent可变www.520diannao.com, U. `5 N+ Q6 ?, G; { r: q
char const* const pContent;// pContent和*pContent都是const我爱电脑技术社区--打造最好的电脑技术自学交流平台6 m# w+ Q% S, m' B8 c# n
) m; L) t' h# t+ Z/ [# B
答案与分析:
5 v+ d5 i* ~, ?我爱电脑技术社区--打造最好的电脑技术自学交流平台
# |3 L) A/ O4 E( j0 H我爱电脑技术论坛 const和指针一起使用是C语言中一个很常见的困惑之处,在实际开发中,特别是在看别人代码的时候,常常会因为这样而不好判断作者的意图,下面讲一下我的判断原则:www.520diannao.com1 M* j4 L3 c" S( y
我爱电脑技术社区--打造最好的电脑技术自学交流平台7 \4 q% w! v. J9 [% Y
沿着*号划一条线,const和谁在一边,那么谁就是const,即const限定的元素就是它。你可以根据这个规则来看上面声明的实际意义,相信定会一目了然。% T* D n3 c' V, x2 x* V' f: v
我爱电脑技术论坛; C8 Y) Y% e8 x' V+ f. e
另外,需要注意:对于const (char *) ; 因为char *是一个整体,相当于一个类型(如 char),因此,这是限定指针是const。