指针运用(限于NOIP层面)

来源:互联网 发布:餐饮收银软件 编辑:程序博客网 时间:2024/06/05 23:58

指针NOIP时常会考,而且一考就是程序阅读,于是乎决定是时候揭开它的真面目了。(对指针的认识仅限于NOIP考试范围内)

先引用一段百度介绍:

在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。[1] 在高级语言中,指针有效地取代了在低级语言,如汇编语言与机器码,直接使用通用暂存器的地方,但它可能只适用于合法地址之中。指针参考了存储器中某个地址,通过被称为反参考指针的动作,可以取出在那个地址中存储的值。作个比喻,假设将电脑存储器当成一本书,一张内容记录了某个页码加上行号的便利贴,可以被当成是一个指向特定页面的指针;根据便利粘贴面的页码与行号,翻到那个页面,把那个页面的那一行文字读出来,就相当于是对这个指针进行反参考的动作。
在信息工程中指针是一个用来指示一个内存地址的计算机语言的变量或中央处理器(CPU)中寄存器(Register)【用来指向该内存地址所对应的变量或数组】。指针一般出现在比较接近机器语言的语言,如汇编语言或C语言。面向对象的语言如Java一般避免用指针。指针一般指向一个函数或一个变量。在使用一个指针时,一个程序既可以直接使用这个指针所储存的内存地址,又可以使用这个地址里储存的函数的值。
另外,指针也指钟表中用来指示对应时间的部件。

其实不是那么好理解,通俗点说,指针就是一个存放地址的变量,而别的变量都是存着值(那为什么还要指定类型呢?现在回想一下为什么其它变量要指定地址呢,因为它要知道开多大的空间去存放值,例如int为32位,longlong为64位等,而不同的类型所占地址的长度也是不同的,所以它也需要知道所存变量类型),那*这又是一个什么符号呢?为什么别的变量没有?因为指针里面存的是地址,而地址里又有值,所以可以直接透过地址去得到值。
(有点绕,慢慢看吧,不懂私我||–)
现在还是看真题吧:

#include<bits/stdc++.h>using namespace std;void fun(int *x,int *y){    int *k;    k=x;    x=y;    y=k;}int main(){    int a=0,b=3;    int *x=&a,*y=&b;    cout<<a<<" "<<b<<endl;    fun(x,y);    cout<<a<<" "<<b<<endl;    return 0;}

忘了是哪一年的了,反正差不多。读者先自行猜测输出的结果。(在公布答案之前首先阐明系统里的swap函数不等价于此处的fun函数,后面会解释。)

直接截图了:
这里写图片描述
读者可能很好奇为什么里面的值没有变化,不是都说指针传地址吗,不是改了值也会改变值吗?其实从本质来说,这句话是有问题的,但为什么没有改变值,个人认为还是这程序写得太假了(即是错的,当然也是故意设置的坑)。

那这个函数究竟干了什么事情呢,我们接下来一步步模拟这个retarded(智障)程序:

  1. 首先,设了一个a,b变量并给它们赋值,接下来又设一个了x指针和y指针,x存的是a的地址,y存的是b的地址。
  2. 然后输出一下a,b的值,这个显然0,3不解释
  3. (重点)接着调用了fun函数,传入了*x,*y(其实也是形参)真实发生的事情是这样的:传了x,y指针进去,计算机又开了两个指针变量,把x中的地址赋值给第一个,y中地址赋值给第二个(因为是形参,变量名不冲突,所以我直接称其为*x和*y)下一句设了一个k指针,把x中的地址赋值给了k,此时k中就存着a变量的地址,接着把y中的地址赋值给x,所以此时x中存的是b变量的地址,再把k中的地址赋值给y变量,所以y中存的是a变量的地址(是不是觉得很绕口,只要牢牢记住,指针变量自己里面存的是别人地址,而不涉及别人的值,自己的地址是用&取出),但发现一直是地址之间的转化,并没有涉及地址里的值,所以地址里的值没有发生变化。

而真正的换值函数是(即系统的swap函数):

#include<bits/stdc++.h>using namespace std;void swap(int *x,int *y){    int k;    k=*x;    *x=*y;    *y=k;}int main(){    int a=0,b=3;    int *x=&a,*y=&b;    cout<<a<<" "<<b<<endl;    swap(x,y);    cout<<a<<" "<<b<<endl;    return 0;}

输出如下:
这里写图片描述

试道真题(NOIP2015):

#include<bits/stdc++.h>using namespace std;void fun(char *a,char *b){    a=b;    (*a)++;}int main(){    char c1,c2,*p1,*p2;    c1='A';    c2='a';    p1=&c1;    p2=&c2;    fun(p1,p2);    cout<<c1<<c2<<endl;    return 0;}

老规矩,先自行猜测答案吧。。。
这里写图片描述
你猜对了吗?–

原创粉丝点击