彻底搞定C指针
前言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 pi16
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
如上图所示,内存只不过是一个存放数据的空间,就好像我的看电影时的电影院中的座位一样。电影院中的每个座位都要编号,而我们的内存要存放各种各样的数据,当然我们要知道我们的这些数据存放在什么位置吧!所以内存也要象座位一样进行编号了,这就是我们所说的内存编址。座位可以是遵循“一个座位对应一个号码”的原则,从“第 1 号”开始编号。而内存则是按一个字节接着一个字节的次序进行编址,如上图所示。每个字节都有个编号,我们称之为内存地址。好了,我说了这么多,现在你能理解内存空间这个概念吗?
我们继续看看以下的 C/C++语言变量声明:
int i;
char a;
每次我们要使用某变量时都要事先这样声明它,它其实是内存中申请了一个名为 i 的整型变量宽度的空间(DOS 下的 16 位编程中其宽度为 2 个字节),和一个名为 a 的字符型变量宽度的空间(占 1 个字节)。
图中可看出,i 在内存起始地址为6 上申请了两个字节的空间(我这里假设了 int 的宽度为 16 位,不同系统中int 的宽度可能是不一样的),并命名为 i。 a在内存地址为 8 上申请了一字节的空间,并命名为 a。这样我们就有两个不同类型的变量了。
2.赋值给变量
再看下面赋值:
i = 30;
a = ’t’;
你当然知道个两个语句是将 30 存入 i 变量的内存空间中,将“t”字符存入 a 变量的内存空间中。我们可以利用这样的形象来理解啦:
3.变量在哪里?(即我想知道变量的地址)
好了,接下来我们来看看&i 是什么意思? 是取 i 变量所在的地址编号嘛!我们可以这样读它:返回 i 变量的地址编号。你记住了吗?
我要在屏幕上显示变量的地址值的话,可以写如下代码: printf("%x", &i);
以上图的内存映象为例,屏幕上显示的不是i 值 30,而是显示 i 的内存地址编号 6 了。当然,在你的实际操作中,i变量的地址值不会是这个数了。
这就是我所认为的作为初学者应该能够想象到的变量存储的实质了。请这样理解吧!
最后总结代码如下:
main()
{
int i = 39;
printf(“%d\n”, i); /*①*/
printf(“%d\n”, &i); /*②*/
return(0);
}
现在你可知道①、②两个printf 分别在屏幕上输出的是i 的什么东西啊?
好啦!下面我们就开始真正进入指针的学习了。
1.指针是什么东西
指针,想说弄懂你不容易啊!我们许多初学指针的人都要这样感慨。我常常在思索它,为什么呢?其实生活中处处都有指针,我们也处处在使用它。有了它我们的生活才更加方便了。没有指针,那生活才不方便。不信?你看下面的例子。 这是一个生活中的例子:比如说你要我借给你一本书,我到了你宿舍,但是你人不在宿舍,于是我把书放在你的2 层 3 号的书架上,并写了一张纸条放在你
的桌上。纸条上写着:你要的书在第2 层 3 号的书架上。当你回来时,看到这纸条,你就知道了我借与你的书放在哪了。你想想看,这张纸条的作用,纸条本身不是书,它上面也没有放着书。那么你又如何知道书的位置呢?因为纸条上写着书的位置嘛!其实这张纸条就是一个指针了。它上面的内容不是书本身,而是书的地址,你通过纸条这个指针找到了我借给你的这本书。 那么我们C/C++中的指针又是什么呢?请继续跟我来吧,下面看一条声明一个指向整型变量的指针的语句:
int *pi;
pi 是一个指针,当然我们知道啦,但是这样说,你就以为 pi 一定是个多么特别的东西了。其实,它也只过是一个变量而已。与上一篇中说的变量并没有实质的区别。不信你看下面图:
(说明:这里我假设了指针只占 2 个字节宽度,实际上在 32 位系统中,指针的宽度是4 个字节宽的,即 32位。) 由图示中可以看出,我们使用“int *pi”声明指针变量 —— 其实是在内存的某处声明一个一定宽度的内存空间,并把它命名为 pi。你能在图中看出pi 与前面的i、a 变量有什么本质区别吗?没有,当然没有!pi 也只不过是一个变量而已嘛!那么它又为什么会被称为“指针”?关键是我们要让这个变量所存储的内容是什么。现在我要让 pi 成为具有真正“指针”意义的变量。请接着看下面语句:
pi = &i;
你应该知道 &i 是什么意思吧!再次提醒你啦:这是返回 i 变量的地址编号。整句的意思就是把 i 地址的编号赋值给 pi,也就是你在 pi 里面写上 i 的地址编号。结果如下图所示:
你看,执行完 pi=&i 后,在图示中的内存中,pi 的值是 6。这个 6 就是i变量的地址编号,这样 pi 就指向了变量 i了。你看,pi 与那张纸条有什么区别?pi 不就是那张纸条嘛!上面写着 i的地址,而 i 就是那个本书。你现在看
懂了吗?因此,我们就把pi 称为指针。所以你要记住,指针变量所存的内容就是内存的地址编号!好了,现在我们就可以通过这个指针 pi 来访问到 i 这个变量了,不是吗?看下面语句:
printf("%d", *pi);
那么*pi 什么意思呢?你只要这样读它:pi 的内容所指的地址的内容(嘻嘻,看上去好像在绕口令了),就是 pi 这张“纸条” 上所写的位置上的那本 “书”—— i 。你看,Pi 的内容是 6,也就是说 pi 指向内存编号为 6 的地址。*pi嘛,就是它所指地址的内容,即地址编号6上的内容了,当然就是30 这个“值”了。所以这条语句会在屏幕上显示30。也就是说 printf("%d", *pi)等价于printf("%d", i) ,请结合上图好好体会吧!各位还有什么疑问?
到此为止,你掌握了类似&i、*pi 写法的含义和相关操作吗?总的一句话,我们的纸条就是我们的指针,同样我们的 pi 也就是我们的纸条!剩下的就是我们如何应用这张纸条了。最后我给你一道题:程序如下。
char a,*pa;
a = 10;
pa = &a;
*pa = 20;
printf("%d", a);
你能直接看出输出的结果是什么吗?如果你能,我想本篇的目的就达到了。好了,就说到这了。Happy Study! 在下篇中我将谈谈“指针的指针”即对
int **ppa;
中 ppa 的理解。
完整的pdf格式文档51黑下载地址(共46页):
彻底搞定C指针.pdf
(328.7 KB, 下载次数: 788)
|