c语言中对初学者来说让人比较头疼的就是指针了,这次对常用的指针做一个总结,希望可以帮助新手对指针有更好的理解。
一、一级指针和二级指针
1.一级指针
int a=10;
int *p=&a;
char *q="hello";//此为指针的定义
a=*p=20;//指针的使用
char *q="hello";
p++;q++;//指针的操作
2.二级指针
int a=10;
int *p=&a;
int **q=&p;//q是二级指针
//a<==>*p<==>**q
//&a<==>p<==>*q
//&p<==>q
二、指针和数组
1.指针和一维数组
int s[5]={1,2,3,4,5};
int *p=s;
//s[i]<==>*(s+i)<==>p[i]<==>*(p+i)
需要注意的是这四个用法虽然可以等价,但是有不同的涵义,p代表的是指针变量,而p是字符串常量,不能被修改,为巩固练习,请做以下判断。
char *p="hello world";
char a[]="hello world"
p++ //正确,指针是变量可以进行操作。
*p++ //正确,取出值后指针指向下一位。
(*p)++ //错误,取出的值是字符串常量,不能修改。
*p='M' //错误,取出的值不允许被修改。
p="hqyj" //正确,指针可以改变,指向另一个字符串。
a++ //错误,a是数组名,是常量。
*a++ //错误,a是数组名,是常量。
*a='M' //正确,等价于a[0]。
a="hqyj" //错误,a是数组名,是常量。
2.数组指针
本质是一个指针,指向二维数组,也叫做行指针。
int s[3][4];
int (*p)[4]=s;//4表示列。
//s[i][j]<==>*(s[i]+j)<==>*(*(s+i)+j)
//<==>p[i][j]<==>*(p[i]+j)<==>*(*(p+i)+j)
3.指针数组
本质是一个数组,数组中每一个元素都是指针。
char *s[4];
//定义了一个s指针数组,其中有4个元素
s[0]="hello";
s[1]="beijing";
char value='M';
s[2]=&value;
三、指针与函数
1.指针函数
本质是一个函数,返回值是一个地址。
如char *strcpy(char *dest, const char *src);
不能返回 | 可以返回 |
局部变量的地址 | static修饰的局部变量地址 |
malloc函数在堆分配的空间地址 | |
全局变量的地址 |
#include <stdio.h>
#if 0
//错误的 不能返回局部变量的地址
int *function1(int x, int y){
int temp = x+y;
return &temp;
}
#endif
int *function2(int x, int y){
static int temp = 0;
temp = x+y;
return &temp;//可以返回static修饰的局部变量的地址
}
int ret = 0;
int *function3(int x, int y){
ret = x+y;
return &ret;//可以返回全局变量的地址
}
int main(int argc, const char *argv[]){
int *p = NULL;
//p = function1(10, 20);
//printf("%d\n", *p);
p = function2(10, 20);
printf("%d\n", *p);//30
p = function3(10, 20);
printf("%d\n", *p);//30
return 0;
}
2.函数指针
本质上是一个指针,指向一个函数
格式:
返回值类型(*函数指针名)(函数的形参表)
多用于将函数作为函数的参数传递。
#include <stdio.h>
#if 0
//错误的 不能返回局部变量的地址
int *function1(int x, int y){
int temp = x+y;
return &temp;
}
#endif
int *function2(int x, int y){
static int temp = 0;
temp = x+y;
return &temp;//可以返回static修饰的局部变量的地址
}
int ret = 0;
int *function3(int x, int y){
ret = x+y;
return &ret;//可以返回全局变量的地址
}
int main(int argc, const char *argv[]){
int *p = NULL;
//p = function1(10, 20);
//printf("%d\n", *p);
p = function2(10, 20);
printf("%d\n", *p);//30
p = function3(10, 20);
printf("%d\n", *p);//30
return 0;
}
函数指针经常被用于回调函数
#include <stdio.h>
int my_add(int x, int y){
return x+y;
}
int my_sub(int x, int y){
return x-y;
}
//将函数指针作为函数的形参,在函数内部通过函数指针p调用函数时
//具体调的是哪一个函数 取决于用户调用jisuan函数时传的第三个参数,
//第三个参数传的是哪个函数 通过p调用的就是哪个函数
//相当于通过p回头去调用用户指定的函数----称之为回调函数
int jisuan(int x, int y, int (*p)(int, int)){
return p(x, y);
}
int main(int argc, const char *argv[]){
int a = 10;
int b = 20;
printf("%d\n", jisuan(a, b, my_add));//30
printf("%d\n", jisuan(a, b, my_sub));//-10
return 0;
}