指针的基本概念
指针是C语言的一种数据结构,使用指针可以对内存地址进行操作。指针是一个程序实体所占用内存空间的首地址。
指针变量:
指针本身也是一个数据,可以使用一个变量来保存,这个变量叫做指针变量。指针变量的格式:
数据类型 *变量名;
例如:
int *p;
*符号前的int说明了从指针变量中地址开始的连续内存空间大小,即改数据类型占用的字节数。
对指针的理解:
p ->数据类型是(int *),P中保存的是地址。
*p ->数据类型是int,*P中保存的是int数据。
指针变量赋值、使用:
指针变量被定义后,必须赋值后才能使用。假如某个整形数据的首地址是0x4460 0000,要赋值给p1,操作为:
int *p1;//定义指针变量
p1 = (int *)0x46600000;//将指针赋值给p1
或者:
int *p1 = (int *)0x46600000;
其中(int *)是强制类型转换,以便通知编译器0x46600000是一个整形数据的首地址。
#include "stdio.h"
int main()
{
int *p;//定义一个整形指针
p = (int *)0x20000000;//将常量0x20000000强制转化为整形地址,用p指向它
*p = 1234;//向该地址写入数据
printf("%d\n",*(int *)0x20000000);//输出0x20000000地址的数据
return 0;
}
另一种写法:
#include "stdio.h"
int main()
{
*(int *)0x20000000= 1234;//将0x20000000强制转化为整形地址(int *)0x20000000,再将1234写入到该地址指向的内容
printf("%d\n",*(int *)0x20000000);//输出该地址的内容
return 0;
}
指针的取值和取址:
使用取址运算符:&
int a;
int *p;
p = &a;
或者
int a;
int *p = &a;
验证:
编写下列代码:
#include <stdio.h>
int main()
{
int *p1;
int a = 5;
p1 = &a;
printf("*p1=%d\n",*p1);
printf("p1=%d\n",p1);
getchar();
return 0;
}

编写编译,链接脚本:
bcc -c -ml -Icbc45include -I. -Lcbc45lib p.c
tlink C:\BC45\LIB\C0l.OBJ p.OBJ ,test,test, C:\BC45\LIB\CL.LIB

运行编译脚本,并执行脚本:


函数指针
函数指针是最重要的C指针之一,她可以指向一个函数。与定义一个变量指针的方法类似,在函数名前加*,则这个函数名变为函数指针变量,函数指针变量的格式:
返回值类型 (*变量名)(参数1类型,参数2类型,…);
例如:
int(*pf)(int,float);
其中int(*)(int,float);是函数指针变量的类型。
若去掉括号:int* pf(int,float);则写法错误,其表示pf函数的返回值是int*
函数指针示例:
编写代码:
#include <stdio.h>
int add(int a,float b)
{
float c;
printf("Function add is called\n");
c = a + b;
printf("%d + %f = %f\n" ,a,b,c);
return 0;
}
int mul(int a,float b)
{
float c;
printf("Function mul is called\n");
c = a * b;
printf("%d x %f = %f\n" ,a,b,c);
return 0;
}
int (*pf)(int a,float b);
int main()
{
pf = add;
pf(1,3.14f);
pf = mul;
pf(2,3.14f);
getchar();
return 0;
}

编写makefile:
TEST.EXE: PF.OBJ
TLINK C:\BC45\LIB\C0l.OBJ PF.OBJ ,TEST,TEST, C:\BC45\LIB\CL.LIB C:\BC45\LIB\EMU.LIB C:\BC45\LIB\FP87.LIB C:\BC45\LIB\MATHL.LIB
PF.OBJ:
bcc -c -ml -Ic:\bc45\include -I.\ -Lc:\bc45\lib pf.c
CLEAN:
del PF.OBJ
del TEST.MAP
del TEST.EXE

编译运行:

函数指针作为函数参数及回调函数:
C语言中任何合法的类型数据都可以作为函数的参数:
Void function(int(*pf)(int,float))
{
pf(1,3.14);
}
对于function函数,只要返回值一样,参数类型一样的函数,都可以作为实参。
举例:
#include <stdio.h>
int add(int a,float b)
{
float c;
printf("Function add is called\n");
c = a + b;
printf("%d + %f = %f\n" ,a,b,c);
return 0;
}
int mul(int a,float b)
{
float c;
printf("Function mul is called\n");
c = a * b;
printf("%d x %f = %f\n" ,a,b,c);
return 0;
}
int sub(int a,float b)
{
float c;
printf("Function sub is called\n");
c = a - b;
printf("%d x %f = %f\n" ,a,b,c);
return 0;
}
int (*pf)(int a,float b);
void function(int (*pf)(int a,float b))
{
pf(5,3.14);
}
int main()
{
function(add);
function(mul);
function(sub);
getchar();
return 0;
}
编译运行:

Comments NOTHING