首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >c语言指针学习心得与分享(4)

c语言指针学习心得与分享(4)

作者头像
一个平凡而乐于分享的小比特
发布2026-02-02 15:36:02
发布2026-02-02 15:36:02
390
举报

作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生在读,研究方向无线联邦学习 擅长领域:驱动开发,嵌入式软件开发,BSP开发 作者主页:一个平凡而乐于分享的小比特的个人主页 文章收录专栏:C语言指针总结,C语言指针是C语言部分重难点,也是编程笔试和面试的重灾区,本专栏旨在总结C语言学习过程中的易错点,通过调试代码,分析原理,对指针有更清晰的理解 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

4.数组参数、指针参数

4.1一位数组传参

代码语言:javascript
复制
#include <stdio.h>
void test(int arr[])//用数组名接收,数组名为首元素地址
{}
void test(int arr[10])//和上面方式一样,只是定义了接收数组的大小
{}
void test(int *arr)//此处用指针来接收,数组名为首元素地址,因此相当于二级指针
{}
void test2(int *arr[20])//此处用指针数组来接收,此时数组大小也可以省略
{}
void test2(int **arr)//此处用二级指针接收
{}
int main()
{
    int arr[10] = {0};//arr为整形数组,其中有10个元素
    int *arr2[20] = {0};//arr2整形指针数组,其中有20个元素
    test(arr);//数组名为数组首元素的地址
    test2(arr2);//数组名为数组首元素的地址,arr2为指针数组首元素的地址,相当于二级指针
}

以上传参都是正确的。

4.2二维数组传参

代码语言:javascript
复制
void test(int arr[3][5])//ok
{}
void test(int arr[][])//err,行可以省略,但列不能省略
{}
void test(int arr[][5])//ok
{}
void test(int *arr)//err,arr为整形指针,用来存放整形的地址,不能接受一维数组的地址
{}
void test(int (*arr)[5])//ok,数组指针,arr指向一个一维数组,数组含有5个元素,每个元素为整形
{}
void test(int **arr)//err,arr为二级指针,不能接受一维数组的地址
{}
int main()
{
    int arr[3][5] = {0};//arr为首元素的地址(第一行的地址)
    test(arr);
}

总结:二维数组传参,函数形参的设计只能省略第一个[]的数字。因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。这样才方便运算。

4.3一级指针传参

当一个函数的参数部分为一级指针的时候,函数能接收什么参数?

代码语言:javascript
复制
void test1(int* p)
{}
void test2(char* p)
{}
int main()
{
    int a=10;
    int* p1=&a;
    test1(&a);//ok
    test1(p1);//ok

    char ch='W';
    char* pc=&ch;
    test2(&ch);//ok
    test2(pc);//ok
    return 0;
}

4.4二级指针传参

当函数的参数为二级指针的时候,可以接收什么参数?

代码语言:javascript
复制
#include <stdio.h>
void test(int** ptr)
{
    printf("num = %d\n", **ptr);
}
int main()
{
    int n = 10;
    int*p = &n;
    int **pp = &p;
    test(pp);
    test(&p);
    return 0;
}
代码语言:javascript
复制
void test(char **p)
{}
int main()
{
    char c = 'b';
    char*pc = &c;
    char**ppc = &pc;
    char* arr[10];
    test(&pc);
    test(ppc);
    test(arr);//Ok
    return 0;
}

5.函数指针

数组指针--是指向数组的指针

函数指针--是指向函数的指针--存放函数地址的一个指针

代码语言:javascript
复制
#include <stdio.h>
void test()
{
    printf("hehe\n");
}
int main()
{
    printf("%p\n", test);
    printf("%p\n", &test);
    return 0;
}

由此可以看出&函数名 和 函数名 都是函数的地址

那我们的函数的地址要想保存起来,怎么保存?下面我们看代码:

代码语言:javascript
复制
void test()
{
    printf("hehe\n");
}
void (*pfun1)();
void *pfun2();

首先,能给存储地址,就要求pfun1或者pfun2是指针,那哪个是指针?

答案是:pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void。

接下来,让我们看一个有趣的代码:

代码语言:javascript
复制
代码1:
(*(void(*)())0)();//把0强制类型转换成:void(*)()函数指针类型-0就是一个函数的地址
                  //调用0地址处的该函数
代码语言:javascript
复制
代码2:
void(*signal(int,void(*)(int)))(int);//signal是一个函数声明
                                     //signal函数的参数有2个,第一个是int。第二个是函数指针,该函数指                                      针指向的函数的参数是int,返回类型是void
                                     //signal函数的返回类型也是一个函数指针:该函数指针指向的函数的参                                       数是int,返回类型是void
将其简化:
typedef void(*pfun_t)(int);
pfun_t signal(int,pfun_t);

6.函数指针数组

数组是一个存放相同类型数据的存储空间,那要把函数的地址存放到一个数组中,那这个数组就叫函数指针数组

代码语言:javascript
复制
int(*parr1[10])();//ok
int *parr2[10]();//err,存在语法错误
int (*)()parr3[10];//err,应该将parr3数组放到第一个圆括号里面,参考第一种写法

函数指针数组的应用:

代码语言:javascript
复制
int Add(int x,int y)
{
    return x+y;
}
int Sub(int x,int y)
{
    return x-y;
}
int Mul(int x,int y)
{
    return x*y;
}
int Div(int x,int y)
{
    return x/y;
}
int main()
{
    int* arr[5];//指针数组
    int(*pa)(int,int)=Add;//Sub/Mul/Div
    int(*parr[4])(int,int)={Add,Sub,Mul,Div};//函数指针的数组
    int i=0;
    for(i=0;i<4;i++)
    {
        printf("%d\n",parr[i](2,3));
    }
}

到这里,本片博客就到这里了。希望大家看了我的讲解,还是要在编译器上实操一下,加深理解。能看明白,不一定会写,只有不断反刍,才能转换成自己的东西哦。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-01-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.数组参数、指针参数
    • 4.1一位数组传参
    • 4.2二维数组传参
    • 4.3一级指针传参
    • 4.4二级指针传参
  • 5.函数指针
  • 6.函数指针数组
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档