主题:[原创]C++第四讲―――指针
某一天,我们开始学习编程,书上的第一讲告诉我们计算机可以表示整数,用这样的语句来写。
int i=2008;
当时我们也挺高兴,呵呵,int据说叫类型,i代表一个实际的数字,那就是2008了。以后我们写程序用i就是用2008了。
某一天,我们又开始学习了指针,又出现了同样的语句:
int i=2008;
老师说i在内存中存放,有一个地址问题,我们可以找出i的地址,用这样的符号来描述:&i;
这下算迷糊了?迷迷糊糊的一章也就学完了,以后给我们留下了一个印象,指针不太好学,不就是个地址吗?说着容易,理解着真难。
本人这样认为,在学习一般变量的时间,没有学习指针变量,就为以后学习指针创造了难度。指针一般是最后来讲。这样在学习的时间造成了一个对比心理。习惯理解了一般变量,就不想在接受指针变量。就相当于吃惯了馒头的人,很难接受改吃大米一样(况且这大米产地很多)。也证明了一个道理,人类的思维是有惯性的。
我们可以考虑一下,人类生活在地球上,每一个人都有自己的家园。可以说,如果人类是一个程序,那么地球就是人类的内存。每一个人的家园都有地址,这个地址也堪称指针了。就我们的程序而言,int i=2008;i在内存中也应该有地址,那我们怎么知道呢,是编译器给i主动存放地址的。当然编译器知道了,编译器是也是程序呀?程序这样规定,每一个一般变量前面加上&,就是变量在地址的内存。所以,在以后我们声明一般变量后,变量前加上&符号,就是该变量的地址了。
通过地址可以找到变量吗,就相当于知道某个人的家园找到某个人一样,编译器可以,编译器这样规定,在地址符前面加上*号,就OK了。你不要再去管编译器怎么通过地址找到地址中存储的值了。如果编译器连这个本领都没有,那还叫编译器吗?
看如下程序:
void main()
{
int i=2008;
printf(“%d\n,&i);//变量在内存中的地址
printf("%d\n",*&i);//呵呵,看起来有些不伦不类的,内存中具体存放的值
printf("%d\n",i);//这个不用说了吧
}
上面程序说明:找到内存中存储的某个变量的值,可以通过变量名字,也可以通过地址去找。
也许有人又问了,上面呢是编译器主动开辟内存空间,如果我想自己开辟空间怎么办呢,我不想让编译器给我开辟空间,我就想自己开辟。那你这样写就可以了。
void main()
{
int *i=new int;//要求开辟一个空间
*i=2008;//给这个空间放入数值
printf("%d\n",i);//打印开辟的内存的地址
printf("%d\n",*i);//打印该内存中存放的数值
}
好像又有了这样一个道理,自己主动开辟内存空间存储数值,要使用new(从前我们用malloc,这个不好用,现在改为new了,可以达到同样的效果)开辟内存。它在内存中的地址是i,,回想上面的程序,是&i;表示数值为*i, 而上面的程序可以用i或者*&i来表示内存中的数值。这是不同的方式造成的结果。呵呵,挺痛苦吧,我猜测,编译器这么设计,开发编译器的工程师也够痛苦的。
某一天,我们又见到了这样一个程序:看的又出了一身汗:
看如下程序:
void main()
{
int i=2008;
int *p=&i;
printf("%d\n",i);//变量的数值
printf("%d\n",&i);//变量在内存中的地址
printf("%d\n",p);//保存在指针中的地址
printf("%d\n",*p);//指针中的地址指向的值
printf("%d\n",&p);//变量p在内存中本身的地址呀
}
看到这个指针变量没有开辟空间,因为什么呢???这里的指针存储的是一个地址,不需要开辟空间,这是C的指针的规定呀。如果要存储一个具体的值(该值不代表地址),那就要开辟空间了。可要注意呀,否则就痛苦了。
这里面怎么这么多地址呀???,其实就2个,一个是变量i在内存中的地址,一个存放变量i的指针变量,它也是个变量,当然有地址了,是这种形式:&p,^_^,可以注意呀。
变量i的地址传给了p进行保存,所以呀,我们可以打印p,也就是打印了i的地址。
既然p代表i的地址,那么*p就找到了i的值了,所以*p=2008了。
以上是指针变量的3种基本形式:一般变量的指针形式,存储数值(非地址)的指针形式,存储地址的指针形式。望读者多加斟酌。
后记,指针是C语言上的难点,本篇偏重于原理讲述。由于本论坛不能发图,所以不能通过图形文字结合了,否则效果要好很多。
下一讲我们要讲什么呢?你猜猜?
另记:本套讲义是对准初学者,强调通俗易懂。笔者肯定,在C++本身的概念里,有些概念是相互排斥的,所以不去做争论。纵然有些特殊的使用可以妙笔生花,但是那不适合初学者。望有些读者谅解。