彻
彻
底
底
搞
搞
定
定
C
C
指
指
针
针
(
(
完
完
全
全
版
版
·
·
修
修
订
订
增
增
补
补
版
版
)
)
著
著
=
=
姚
姚
云
云
飞
飞
修
修
订
订
=
=
丁
丁
正
正
宇
宇
前言
姚云飞先生的大作《彻底搞定 C 指针》是互联网上中文 C/C++界内为数不
多的专门阐述 C 指针问题的优秀文献资源之一。
正如书名所示,对于那些学习了 C 基础知识却始终对 C 指针不得要领的读
者,或者那些已经长期被 C 指针困扰的读者,作者致力于彻底解决他们在这方
面的难题。为了达到这个目的,作者运用了许多生动与亲切的例子,深入浅出地
讲透了 C 指针的原理与机制,并辅以编程实践中最常用的惯例和技巧作为示范。
《彻底搞定 C 指针》是互联网上下载次数最多的针对 C 指针问题的中文资
源之一。现在,经由修订者的重新修订、编辑与排版,本书的《完全版·修订增
补版》全新登场。新版本中的技术用语更加清楚严谨,行文的结构层次更加分明,
例子中的程序代码均通过编译以测试其精准性。修订者希望这份新的成果能够令
各位读者在 C 编程方面获得更多的益处,同时也期待着读者们宝贵的反馈信息。
再次向姚云飞先生致敬!
1
目 录
前言 ..................................................................................................................................................1
目 录 ................................................................................................................................................2
修订说明...........................................................................................................................................3
A类:规范化............................................................................................................................3
B类:更正................................................................................................................................3
C类:明晰化............................................................................................................................4
D类:编译器............................................................................................................................4
第壹篇 变量的内存实质.................................................................................................................5
1.先来理解C语言中变量的实质 ..........................................................................................5
2.赋值给变量.........................................................................................................................6
3.变量在哪里?(即我想知道变量的地址).....................................................................7
第贰篇 指针是什么?.....................................................................................................................8
1.指针是什么东西.................................................................................................................8
第叁篇 指针与数组名...................................................................................................................11
1. 通过数组名访问数组元素................................................................................................11
2.通过指针访问数组元素...................................................................................................11
3.数组名与指针变量的区别...............................................................................................12
4.声明指针常量...................................................................................................................13
第肆篇const int *pi与int *const pi的区别...............................................................14
1. 从const int i 说起 ...................................................................................................14
2. const int *pi的语义..............................................................................................15
3. 再看int *const pi.....................................................................................................16
4.补充三种情况...................................................................................................................18
第伍篇 函数参数的传递...............................................................................................................20
1.三道考题...........................................................................................................................20
2. 函数参数传递方式之一:值传递....................................................................................23
3. 函数参数传递方式之二:地址传递................................................................................26
4. 函数参数传递方式之三:引用传递................................................................................27
第陆篇 指向另一指针的指针.......................................................................................................30
1. 回顾指针概念....................................................................................................................30
2.指针的地址与指向另一指针地址的指针.......................................................................31
3. 一个应用实例....................................................................................................................32
第柒篇 函数名与函数指针...........................................................................................................37
1. 通常的函数调用................................................................................................................37
2.函数指针变量的声明.......................................................................................................38
3.通过函数指针变量调用函数...........................................................................................38
4.调用函数的其它书写格式...............................................................................................39
5.定义某一函数的指针类型...............................................................................................42
6. 函数指针作为某个函数的参数........................................................................................44
2
修订说明
A类:规范化
A1. C 程序的代码段,以及行文中的代码的字体,均统一调整为 Courier New,例如:
- 类型说明符“int”、变量名“a”、地址表达式“&a”、函数名“Exchg1”
等等均作调整。
A2. 行为中的代码段,按一般行文处理缩进;代码段内部规整缩进。
A3. 规整 C 语句,例如:
- 语句中形如“a=b+c(x,y)”的,将调整为形如“a = b + c(x, y)”的
新样式,即在运算符、用来间隔参数的逗号等的旁边补足空白,令语句的可读
性更强。
- 补全语句结尾的“;”。
A4. 规整行文语序,令其更加通顺。
A5. 规整术语写法,例如:
- “C、C++”调整为“C/C++”。
B类:更正
B1. 更正术语,例如:
- “申明”调整为“声明”。
B2. 规整 C 技术用语,例如:
- “一个声明一整型指针变量的语句”调整为“一条声明一个指向整型变量
的指针的语句”。
B3. 规整 C 程序,例如:
- 补全定义函数时的类型说明符“void”。
3
- 补全 main()程序段中的“return(0);”。
B4. 规整行文,例如:
- “真正有意义上的指针”调整为“具有真正‘指针’意义的变量”。
B5. 更正标点符号,例如:
- 将行文里面中文/英文标点符号(全角/半角)混用、前后抵牾的情况进行
更正。
- 将程序里面有编程代码意义的符号(如双引号“"”)中被错误地录入为
中文标点符号(全角)的,调整为英文(半角)的。
B6. 更正一些外语行文。
C类:明晰化
C1. 初次介绍(不一定是初次出现)专业术语时,用黑体字。
C2. 需要突出重点的地方,用粗体字。
C3. 重整程序,例如:
- 原作中某处的例 1 中的函数被定义名为“Exchg1()”,例 2 中的函数被
定义名为“Exchg2()”,那么,将例 3 中的函数名在定义中调整为
“Exchg3()”,使它们的逻辑关系更为明晰,易于读者阅读和理解。
- 循环体中的“printf("%d", a[i]);”调整为“printf("%d\n",
a[i])”。
C4. 规整行文分段,令其更合乎逻辑。
D类:编译器
D1. 著者声明相关代码“都是在 VC6.0 上实验”,而修订者则是使用 gcc 3.4.2 编译器测
试相关代码。
4
第壹篇 变量的内存实质
1.先来理解C语言中变量的实质
要理解 C 指针,我认为一定要理解 C 中“变量”的存储实质,所以我就从
“变量”这个东西开始讲起吧!
先来理解理解内存空间吧!请看下图:
内存地址→ 6 7 8 9 1 0 1 1 12 13
-------------------------------------------------------------------------------------------------------
··· | | | | | | | | ···
------------------------------------------------------------------------------------------------------
如上图所示,内存只不过是一个存放数据的空间,就好像我的看电影时的电
影院中的座位一样。电影院中的每个座位都要编号,而我们的内存要存放各种各
样的数据,当然我们要知道我们的这些数据存放在什么位置吧!所以内存也要象
座位一样进行编号了,这就是我们所说的内存编址。座位可以是遵循“一个座位
对应一个号码”的原则,从“第 1 号”开始编号。而内存则是按一个字节接着一
个字节的次序进行编址,如上图所示。每个字节都有个编号,我们称之为内存地
址。好了,我说了这么多,现在你能理解内存空间这个概念吗?
我们继续看看以下的 C/C++语言变量声明:
int i;
char a;
每次我们要使用某变量时都要事先这样声明它,它其实是内存中申请了一个
名为 i 的整型变量宽度的空间(DOS 下的 16 位编程中其宽度为 2 个字节),和
一个名为 a 的字符型变量宽度的空间(占 1 个字节)。
5