指针
1指针的概念
1.1定义 在计算机语言中,由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”,意思是通过它能找到以它为地址的内存单元。
指针的本质是一个无符号的整数,代表一个内存单元的单元号,它的长度与机器字长有关。
void main(){
int a=0;
char c=’0’;
void *p;
p=(int *)&a;
printf(“p:0x%x, %d length:%d”,p,*p,sizeof(p));
p=(char *)&c;
printf(“p:0x%x, %c length:%d”,p,*p,sizeof(p));
}
1.2指针与引用的区别
1.从内存上来讲 系统为指针分寸内存空间,而引用与绑定的对象共享内存空间,系统不为引用变量分配内容空间。2指针初始化以后可以改变指向的对象,而引用定义的时候必须要初始化,且初始化以后不允许再重新绑定对象。3.所以引用访问对象是直接访问。指针访问对象是间接访问。4。如果pa是指针,那么*pa就是引用了。
但是两者在作为形参的时候非常相似,区别是指针拷贝副本,引用不拷贝。
#include<stdio.h>
void pt(int * pta,int * ptb){
int *ptc;
ptc=pta;pta=ptb;ptb=ptc;
}
void ref(int &ra,int &rb){
int rc;
rc=ra;ra=rb;rb=rc;
}
void main(){
int a=3;int b=4;
int *pa=&a;int *pb=&b;
pt(pa,pb);
printf("zhizhen: a=%d,b=%d\n",a,b);
ref(a,b);
printf("yinyong: a=%d,b=%d\n",a,b);
}
2.指针的应用
2.1指针与别名
如果有一块内存区域,只想这块内存区域的指针有多个,其中每一个指针都是其他指针的别名。如
int a=200; int *p.*q; p=&a; q=&a;
注意别名其实指向的是同一个变量,注意别名陷阱。如a=2,b=3; a+b=5?
#define a *p; #define b *q;
int x; p=&x; q=&x; a=2,b=3; a+b=?
2.2数组的指针
指针变量同样可以指向一个数组,如int (*p)[10];表示p是一个指针,指向一个数组对象,该数组是一个拥有10个整型元素的数组。那么p+1时,p移动的字节数是sizeof(int)*10
数组指针如何访问数组元素
int a[5]={1,2,3,4,5};
int (*p)[5];
int *ptr;
p=&a;
ptr=(int *)p;
printf(“result:%d”,*(ptr+1));
2.3指针的指针
指针变量的值可以是另一个指针变量的地址,也就是将指向的对象换为指针,就可以定义一个指向指针的指针对象。如
int a; int *p; int **q;
a=100; p=&a; q=&p;
printf(“a:%d p:%x q:%x ”,a,*p,*q)
2.4指针与参数传递
C语言中的函数可以接受参数,参数相当于一个函数内部的局部变量。函数调用时,参数被复制到函数的栈帧空间,当做函数的局部变量使用,因此对参数的修改是不能被调用者看到的。
如果希望调用函数后,对变量的改变在调用者中生效,就需要用到指针了。注意,函数将指针作为参数赋值到了栈帧中,对指针本身的改变后来在调用者看来是不会生效的,但是通过指针修改了指针所指向的内容后,在调用者看来是生效的。
这也就产生了一个问题,如果要修改指针本身,那该怎么办?
传递的参数应当使用指针的指针。
2.5指针的类型
在定义一个指针的时候,往往会同时声明该指针变量指向的数据类型,这个数据类型的作用在于告知编译器需要从该地址处向后取多少个字节,把这些字节当做一个对象来看待。
void*指针表示一个任意类型的指针,可以指向任意一个类型的内存单元。当编译器不清楚用户要把指针所指向的内容做什么用途的时候,void*类型的指针就派上用场了,如调用malloc函数分配一块内存。
指针参与运算时,他们必须指向相同的对象类型。因此在比较一个指针和一个整型数据时,首先要做的就是将整型数据转换为该指针类型。
关于NULL
NULL本身并不是c语言中的一个关键字,而是一个定义在stdio.h文件中的宏: #define NULL (void*)0;在所有的 系统中,0号内存单元都是不允许进行读写操作的因此指向它的指针作为空指针使用。
3.函数指针
函数的指针等于该函数存放其二进制执行代码的内存区域的首地址。函数指针的一般声明形式为:函数的返回值 (*指针变量名)(函数的参数列表);
3.1回调函数
回调函数的一种典型应用就是实现一种泛型算法,也即兼顾不同的数据类型。例如:现在希望实现一个max函数,可以在任意一组对象中找到键码最大的对象,这些对象可能是一些整数,也可能是一些结构体。为了让max函数适用于任何对象需要由调用max函数的调用者自己提供一个比较两个对象的函数作为标准,这个比较两个对象的函数就是回调函数。
它的本质是,使用函数指针,当调用者发现要处理的是int型参数时,就将函数指针指向一个处理int型数据的函数,这样在形式上的调用是不变的。
3.2函数指针数组
C语言中允许出现函数指针的数组,该数组中每一个元素都是一个函数的指针,此与普通数组无异