指针的概念与使用
程序运行时,程序中使用的变量和数组等数据都是存储于内存之中,内存中每一个字节都有一个唯一的地址(地址是一个整数值),指针变量用于存储一个内存地址,当一个指针变量存储了一个变量的地址时,我们可以说是这个指针指向了这个变量,通过指针也可以访问这个变量的值。
指针变量的定义
类型 *变量名; 例如: int *p;
给指针变量赋值
- 用&运算符求变量的地址: int a,*p=&a;
- 指针指向数组: int a[10],b[5][10],*p=a,*k=b[1];
- 指针引用字符串: char *s="how are you?";
通过指针访问变量的值(* 运算符)
*指针变量 例如: *p=100;
移动指针
int a[10],*p=a;
p++;p=p+3;
p--;
整形指针每次移动4个字节,字符型指针每次移动1个字节,其他类型同理。
指针数组
int *a[10]; //一次定义了10个整型指针变量a[0]~a[10];指针与函数
指针作为函数参数
通过指针可以将主程序中的变量地址传给子程序中的指针,达到在子程序中访问主程序中的变量的目的。例如:编写函数交换两个整型变量的值。
void swap(int *a,int *b){
int c;
c=*a;*a=*b;*b=c;
}
调用时 swap(&a,&b); ,利用指针可以解决子函数需要返回多个值的问题。
指针作为函数返回值
int * ppp(); //函数返回一个整型指针
注意:函数运行结束后,函数内的局部变量占用的空间都会收回(静态变量或者动态分配内存除外)。
指向函数的指针
函数时一段代码,也是存储于内存中,这段代码有一个起始地址,程序从这里开始运行。函数名就是函数代码在内存中的起始地址。让一个指针变量存储函数的地址,这个指针就指向了这个函数,然后可以通过指针来调用这个函数。定义函数指针的格式如下:
返回类型 (*指针变量名)(参数类型,参数类型);
int (*p)(int,int);
定义一个函数指针p,只能指向返回值为整型,带两个整型参数的函数。
通过指针调用函数
int ppp(int a,int b); p=ppp; (*p)(10,20);
动态内存分配
动态分配内存
void * malloc(unsigned int size);
分配指定字节数的连续动态内存空间,返回空间首地址。
void * calloc(unsigned n,unsigned size);
分配n个size字节大小的连续动态内存空间,例如:分配能存100个整数的内存空间:calloc(100,4);
释放动态分配的内存
void free(void *p);
释放指定地址的内存空间,必须与分配时返回的地址相同。
void型指针
void型指针仅适合保存内存地址,建议强制转换成其他类型指针再使用。
指向指针的指针
一个指针变量存储另一个指针变量的地址,就是指向指针的指针。很少需要用到这种情况。定义和使用方法如下:
定义:类型 **变量名;
使用: **变量名
int **p,*x,a=10;
x=&a;
p=&x;
printf("%d",**p);
当需要在子函数中修改主函数中的指针变量时,需要用到指向指针的指针。
课堂练习
编写子函数,让主函数中的字符串指针指向下一个非字母字符。
char *s="how are you";
ppp(&s);