指针的基本概念

指针是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;
}

编译运行:

此作者没有提供个人介绍
最后更新于 2024-09-30