彻底搞定C语言指针详解(整理后)

上传人:飞*** 文档编号:53592017 上传时间:2018-09-03 格式:PDF 页数:20 大小:31.44KB
返回 下载 相关 举报
彻底搞定C语言指针详解(整理后)_第1页
第1页 / 共20页
彻底搞定C语言指针详解(整理后)_第2页
第2页 / 共20页
彻底搞定C语言指针详解(整理后)_第3页
第3页 / 共20页
彻底搞定C语言指针详解(整理后)_第4页
第4页 / 共20页
彻底搞定C语言指针详解(整理后)_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《彻底搞定C语言指针详解(整理后)》由会员分享,可在线阅读,更多相关《彻底搞定C语言指针详解(整理后)(20页珍藏版)》请在金锄头文库上搜索。

1、1.语言中变量的实质要理解 C 指针,我认为一定要理解C 中“变量”的存储实质,所以我就从“变量”这个东西开始讲起吧!先来理解理解内存空间吧!请看下图:内存地址67 8910111213 - 。 。 。|.。- - 如图所示,内存只不过是一个存放数据的空间,就好像我的看电影时的电影院中的座位一样。每个座位都要编号,我们的内存要存放各种各样的数据,当然我们要知道我们的这些数据存放在什么位置吧!所以内存也要象座位一样进行编号了,这就是我们所说的内存编址。座位可以是按一个座位一个号码的从一号开始编号,内存则是按一个字节一个字节进行编址,如上图所示。每个字节都有个编号,我们称之为内存地址。好了,我说了

2、这么多,现在你能理解内存空间这个概念吗?我们继续看看以下的C、C+语言变量申明:int I ;char a;每次我们要使用某变量时都要事先这样申明它,它其实是内存中申请了一个名为i 的整型变量宽度的空间( DOS 下的 16 位编程中其宽度为二个字节),和一个名为a 的字符型变量宽度的空间(占一个字节) 。我们又如何来理解变量是如何存在的呢。当我们如下申明变量时:int I ;char a;内存中的映象可能如下图:内存地址678 910111213 - - 。 。 。 |.。- |i | a | 图中可看出, i 在内存起始地址为6 上申请了两个字节的空间(我这里假设了int 的宽度为16 位

3、,不同系统中int 的宽度是可能不一样的),并命名为i. a 在内存地址为8 上申请了一字节的空间,并命名为a.这样我们就有两个不同类型的变量了。2.赋值给变量再看下面赋值:i=30 a=,t?你当然知道个两个语句是将30 存入 i 变量的内存空间中,将t字符存入a 变量的内存空间中。我们可以这样的形象理解啦:内存地址678910 111213 - - 。 。 。|30| t| |.。- - |i | a | 3.变量在哪里?(即我想知道变量的地址)好了,接下来我们来看看 printf( “%dn”,i); /printf( “%dn”, / 现在你可知道、两个printf 分别在屏幕上输出的

4、是i 的什么东西啊?好啦!下面我们就开始真正进入指针的学习了。4、指针是什么东西想说弄懂你不容易啊!我们许多初学指针的人都要这样的感慨。我常常在思索它,为什么呢?其实生活中处处都有指针。我们也处处在使用它。有了它我们的生活才更加方便了。没有指针,那生活才不方便。不信?你看下面的例子。这是一个生活中的例子:比如说你要我借给你一本书,我到了你宿舍, 但是你人不在宿舍,于是我把书放在你的2 层 3 号的书架上,并写了一张纸条放在你的桌上。纸条上写着:你要的书在第2 层 3 号的书架上。当你回来时,看到这张纸条。你就知道了我借与你的书放在哪了。你想想看,这张纸条的作用,纸条本身不是书,它上面也没有放着

5、书。那么你又如何知道书的位置呢?因为纸条上写着书的位置嘛!其实这张纸条就是一个指针了。它上面的内容不是书本身,而是书的地址,你通过纸条这个指针找到了我借给你的本书。那么我们C,C+ 中的指针又是什么呢?请继续跟我来吧,看下面看一个申明一整型指针变量的语句如下:int * pi ;pi 是一个指针,当然我们知道啦,但是这样说,你就以为pi 一定是个多么特别的东西了。其 实,它也只过是一个变量而已。与上一篇中说的变量并没有实质的区别。不信你看下面图。内存地址 67891011121314 - . | 30|t|,- - 变量| i|a |pi | (说明:这里我假设了指针只占2 个字节宽度,实际上

6、在32 位系统中,指针的宽度是 4个字节宽的,即32 位。 )由图示中可以看出,我们使用int *Pi 申明指针变量;其实是在内存的某处申明一个一定宽度的内存空间,并把它命名为Pi.你能在图中看出pi 与前面的i,a 变量有什么本质区别吗,没有,当然没有!pi 也只不过是一个变量而已嘛!那么它又为什么会被称为指针?关键是我们要让这个变量所存储的内容是什么。现在我要让pi 成为真正有意义上的指针。请接着看下面语句:pi= for (i=0;i=9;i+) printf ( “ %d ” , ai ); 很显然,它是显示a 数组的各元素值。我们还可以这样访问元素,如下int i,a=3,4,5,6

7、,7,3,7,4,4,6; for (i=0;i=9;i+) printf ( “ %d”,*(a+i) ); 它的结果和作用完全一样通过指针访问数组元素int i,*pa,a=3,4,5,6,7,3,7,4,4,6; pa =a;/请注意数组名a 直接赋值给指针pa for (i=0;i=9;i+) printf ( “ %d ” , pai ); 很显然,它也是显示a 数组的各元素值。另外与数组名一样也可如下:int i,*pa,a=3,4,5,6,7,3,7,4,4,6; pa =a; for (i=0;i=9;i+) printf ( “ %d ” , *(pa+i) ); 看 pa=

8、a 即数组名赋值给指针,以及通过数组名、指针对元素的访问形式看,它们并没有什么区别,从这里可以看出数组名其实也就是指针。难道它们没有任何区别?有,请继续。3. 数组名与指针变量的区别请看下面的代码:int i,*pa,a=3,4,5,6,7,3,7,4,4,6; pa =a; for (i=0;i=9;i+) printf ( “ %d ” , *pa );pa+ ;/注意这里,指针值被修改 可以看出,这段代码也是将数组各元素值输出。不过,你把 中的 pa 改成 a 试试。你会发现程序编译出错, 不能成功。 看来指针和数组名还是不同的。其实上面的指针是指针变量,而数组名只是一个指针常量。 这个

9、代码与上面的代码不同的是,指针 pa 在整个循环中, 其值是不断递增的,即指针值被修改了。数组名是指针常量,其值是不能修改的,因此不能类似这样操作:a+.前面 4,5 节中 pai,* (pa+i )处,指针pa 的值是使终没有改变。所以变量指针pa 与数组名a 可以互换。6. 申明指针常量再请看下面的代码:int i, a=3,4,5,6,7,3,7,4,4,6; int * const pa=a;/ 注意 const 的位置:不是const int * pa ,for (i=0;i=9;i+) printf ( “%d ”, *pa );pa+ ;/注意这里,指针值被修改 这时候的代码能成

10、功编译吗?不能。因为pa 指针被定义为常量指针了。这时与数组名a 已经没有不同。这更说明了数组名就是常量指针。但是,int * const a=3 ,4,5,6,7,3, 7,4,4,6 ;/不行int a=3 ,4,5, 6,7,3,7,4,4,6 ;/可以,所以初始化数组时必定要这样。以上都是在VC6.0 上实验。1 int i 说起你知道我们申明一个变量时象这样int i ;这个 i 是可能在它处重新变赋值的。如下:int i=0;/ i=20; /这里重新赋值了不过有一天我的程序可能需要这样一个变量(暂且称它变量),在申明时就赋一个初始值。之后我的程序在其它任何处都不会再去重新对它赋值

11、。那我又应该怎么办呢?用const . /* const int ic =20 ;/ ic=40;/这样是不可以的,编译时是无法通过,因为我们不能对const 修饰的ic 重新赋值的。/这样我们的程序就会更早更容易发现问题了。有了 const 修饰的 ic 我们不称它为变量,而称符号常量,代表着20 这 个数。这就是const 的作用。 ic 是不能在它处重新赋新值了。认识了 const 作用之后,另外,我们还要知道格式的写法。有两种:const int ic=20;与 int const ic=20 ; 。它们是完全相同的。这一点我们是要清楚。总之,你务必要记住const 与 int 哪个写

12、前都不影响语义。有了这个概念后,我们来看这两个家伙: const int * pi 与 int const * pi,按你的逻辑看, 它们的语义有不同吗?呵呵,你只要记住一点, int 与 const 哪个放前哪个放后都是一样的,就好比const int ic ;与 int const ic ;一样。也就是说,它们是相同的。好了,我们现在已经搞定一个“双包胎”的问题。那么int * const pi 与前两个式子又有什么不同呢?我下面就来具体分析它们的格式与语义吧!2 const int * pi 的语义我先来说说const int * pi是什么作用(当然 int const * pi也是一

13、样的,前面我们说过,它们实际是一样的) 。看下面的例子:/*代码开始* int i1=30; int i2=40; const int * pi= pi=/4.注意这里, pi 可以在任意时候重新赋值一个新内存地址i2=80;/5.想想看:这里能用*pi=80; 来代替吗?当然不能printf( “%d”, *pi ) ;/6. 输出是 80 /*代码结束 * 语义分析:看出来了没有啊, pi 的值是可以被修改的。即它可以重新指向另一个地址的,但是,不能通过 *pi 来修改 i2 的值。这个规则符合我们前面所讲的逻辑吗?当然符合了!首先 const修饰的是整个*pi(注意,我写的是 *pi 而

14、不是pi) 。所以 *pi 是常量,是不能被赋值的(虽然pi 所指的 i2 是变量,不是常量) 。其次, pi 前并没有用const 修饰,所以pi 是指针变量,能被赋值重新指向另一内存地址的。你可能会疑问: 那我又如何用const 来修饰 pi 呢?其实, 你注意到int * const pi 中 const 的位置就大概可以明白了。请记住,通过格式看语义。哈哈,你可能已经看出了规律吧?那下面的一节也就没必要看下去了。不过我还得继续我的战斗!3 再看 int * const pi 确实, int * const pi 与前面的 int const * pi 会很容易给混淆的。注意:前面一句的const 是写在 pi 前和 * 号后的, 而不是写在 *pi 前的。很显然, 它是修饰限定pi 的。我先让你看例子:/*

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 资格认证/考试 > 其它考试类文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号