关于指针(指针常量/常量指针、指针数组/数组指针、指针函数/函数指针)

指针常量(常指针):char * const p const位于星号右侧,const修饰指针本身,即指针本身是常量,指针指向地址不可改变,但所指地址变量值可以改变。
常量指针(指向常变量的指针):const char *p cosnt位于星号左边,const修饰指针所指向的变量,即指针本身指向的地址可以改变,但它所指的内容不可以被修改。
指针函数:函数的返回值是一个指针类型。
函数指针:指向一个函数入口地址的指针。
指针数组:它是数组,数组每个元素都是指针。
数组指针:它是指针,指向数组地址的指针。

int *p[n];——指针数组,每个元素均为指向整型数据的指针。
int (*)p[n];——数组指针,指向一维数组的指针。
int *p();——指针函数,函数带回指针,指针指向返回的值。
int (*)p();——函数指针,p为指向函数的指针。

数组指针与指针数组
1. 数组指针定义

//1.先定义数组类型,再定义数组指针变量
typedef int ARRARY[10];
ARRARY *p;
//2.先定义数组指针类型,再定义数组指针变量
typedef int(*ARRARY)[10];
ARRARY p;
//3.直接定义数组指针变量
int(*p)[10]; 

int arr[10];    //定义数组变量
p = &arr;       //赋值

2.指针数组

int *arr[10];
//一维数组做函数参数退化为一级指针,因此需要指定数组大小
//二维数组(多维数组)做函数参数,退化为数组指针
注意arr与arr[0]的区别:arr不能为左值

指针函数与函数指针
如下两个例子
1. int* lpfun(int,int);
2. int (*lpfun)(int,int);
第一种是我们熟悉的指针函数,()优先级比*高,它是函数,返回类型是指针,即函数的返回值为int类型的指针

第二种一定要用括号把*号和lpfun括起来,这种类型与第一种不一样,是指向一种函数地址的指针。这个函数的返回类型是int型,实参也为int型。

函数指针的定义

//1.先定义函数类型,根据类型定义指针变量
typedef int FUN(int a); //FUN函数类型
FUN *p1 = NULL;     //函数指针变量
//2.先定义函数指针类型,根据类型定义指针变量
typedef int (*PFUN)(int a);
PFUN p2 = fun;      //p2指向fun函数
//3.直接定义函数指针
int (*p3)(int a) = fun; //定义并赋值

int fun(int a) {
    //...
}
p = fun;    //赋值
p(10);      //调用

函数指针的应用
1.函数指针数组与指针数组的结合

//函数指针数组
void(*fun[5])() = { add, minus, multi, divide };
//指针数组
char *buf[] = { "add", "min", "mul", "div" };


for(int i = 0; i < 5; i++) {
    if( 0 == strcmp(cmd, buf[i]) ) {
        fun[i]();
        break;
    }
}
  1. 回调函数
//函数的参数是变量,也可以是函数指针变量
void fun(int x, int y, int (*p)(int a, int b) ) {
    //...
    p(x, y);        //回调函数
}
//好处:新增加的函数可以直接赋值给函数指针变量,原有框架不用改变,可实现多态的特性
#include <stdio.h>

int* lpfun1(int,int);  //声明一个返回指针为int类型的函数
int lpfun2(int,int);  //普通函数
typedef int (*lpfunPointer)(int,int); //声明一个函数指针类型,用于保存它要指向的函数地址
void main()
{
  int *result=lpfun1(10,20);
  printf("%d\n",*result);
  if(result != NULL) {
      delete result;  //删除堆中的指针
      result = NULL;     //使指针无效
  }

  lpfunPointer p = lpfun2;  //保存lpfun2函数的地址,函数名也是一种指针
  printf("%d\n", p(12,60));  //调用带参的函数

}
/***********************************************************************************************
  lpfun1过程说明:
    如果我们在此函数中这样写: int *p=NULL;
                             *p=x+y;
                             return p;
  这样的写法是错误的,因为在函数中声明的变量在函数执行完后就不存了,即此时p不存了,是个无效指针,就不能得到这个返回值。
 而如果在堆中开辟一小内存来存放,并在完成后由手工来释放,则我们可以用int* p=new int;来创建,这样即使函数没了,但
这个p指向的内存还是存在于堆中的,由此我们会看到在main()中用了一个int *result=lpfun1(10,20)把堆中的p指针指向内存的地址赋给result指针,再
手工释放。 这样就不会内存泄露了。

谨记:永远不要从函数中返回局部自动变量的地址。
******************************************/
int* lpfun1(int x,int y)
{
    int *p=new int(0);
    *p=x+y;
    return p;
}

int lpfun2(int x,int y) 
{
    return x+y;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值