嵌入式培训之C语言学习(十六)指针(4)指针函数、函数指针、指针的数组、二级指针

目录

一、指针函数

二、动态内存分配

(一)malloc函数

(二)free函数

(三)注意事项

(四)示例

(五)realloc函数

(六)calloc函数

(七)reallocarray函数

三、函数指针

(一)函数指针

(二)回调函数

​编辑(三)qsort函数

(四)小考题

四、指针的数组

五、指针的指针(二级指针)

(一)考点

(二)用例

(三)口诀

(四)例题

一、指针函数

1、指针函数:返回值为指针的函数,绝不能返回局部变量的地址(全局变量、静态变量与传进去的指针地址均可返);

2、用法:

int *foo(int *p)

{

        static int i = 100;

        return p;

}

int main(void)

{

        int i = 10;

        *foo(&i) = 100;//foo(&i)为i的地址,*foo(&i)为i本身

        printf("%d\n",i);//输出i为100

        return 0;

}

二、动态内存分配

(一)malloc函数

1、一般形式:void *malloc(size_t  size);

(1)参数size:   size 表示申请的空间的大小,单位字节; 

(2)返回值:成功返回申请到内存空间的地址;失败返回 NULL。

(3)该函数申请的空间在内存上一定是连续的,返回的是一个指针,指向申请的内存空间(内存空间未初始化全是随机数);

2、malloc函数为内存分配函数(指针型函数),

      使用该函数要包头文件#include<stdio.h>

3、在使用该函数时要判断内存空间是否申请到,申请空间申请不到会返回空指针

(二)free函数

1、释放函数 :释放申请到的内存空间 

2、一般形式:

void free(void *ptr);

3、(1)功能:释放之前申请的堆上的空间 ;
      (2)参数:ptr 一定是之前申请到堆上空间的地址 ;

(三)注意事项

1、在使用整个内存空间的过程中,申请到内存空间的地址不能改变(一定要保存好);

2、不要多次一起使用free函数;

free(p);//交还完后指针变量p变为野指针

free(p);//此时指针变量p为野指针

为防止野指针出现:

free(p);

p = NULL;

free(p);//此时p为空指针,不会出现问题

3、free(p); 写在 return 0;  前无论是否分配到内存空间都可被处理;

4、申请空间后一定要释放(好借好还,再借不难)。

(四)示例

拼接字符串:先申请一个内存空间存放“Hello”字符串,再申请一个内存空间把“Hello”先放进去再把字符串“World!”拼接在后面,释放掉第一次申请的内存空间,输出拼接的字符串后释放掉第二次申请的内存空间。

(五)realloc函数

1、一般形式:void *realloc(void *ptr,size_t size);

void *ptr:原来空间的地址;size_t size:新开的空间需要多大;

2、realloc函数(把原来空间的内容拷过来并释放原来的空间)用于缩容或扩容

3、示例:

(六)calloc函数

一般形式:void *calloc(size_t   nmemb, size_t  size);

申请空间numemb * size 个字节

(七)reallocarray函数

一般形式:void *reallocarray(void *ptr, size_t nmemb, size_t size);

三、函数指针

(一)函数指针

1、指向函数类型的指针;

2、一般形式:

int add(int a, int b)

{

        return a + b;

}

int (*p)(int a, int b);//此时未初始化未赋值,p为野指针;可省略ab明确参数类型,参                                 数名无所谓

p = add;//函数的函数名即为该函数的入口地址

printf("%d\n",  (*p)(10, 20));//也可写成p(10,20)为间接访问

                                             add(10, 20)为直接访问

                                             运行结果为30

3、作用:降低函数耦合性

(二)回调函数

1、回调函数:通过函数指针在函数的参数中调用函数;

 2、用例:前面两个函数为回调函数;


(三)qsort函数

1、一般形式:

2、用例:

(四)小考题

立即跳到0x30001000(地址值,可以理解为函数的入口地址)处开始执行代码:

四、指针的数组

int  *a[10];//定义一个指针数组(该数组存放了10个指针)

printf("%lu\n", sizeof(a));//占80个字节,一个指针占8个字节

其中const char *argv[]为指针数组,通过一堆字符串向主函数传参

用例:

五、指针的指针(二级指针)

(一)考点

以下代码能否正常运行,不能运行崩在哪里?

1、void getMemory(char *p)

2.   {

3.           p = malloc(100);

4.    }

5.    int main(void)

6.    {

7.            char *s;

8.            getMemory(s);//s指针未指向malloc申请的100个字节

9.            strcpy(s, "Hello");//此行代码崩溃,s为野指针(随机数)

10.          puts(s);

11.   }

该程序编译不报错,运行崩溃

正确代码:

1、void getMemory(char **p)//char *为指针的基类型,*为类型说明符,说明p为                                                    指针

2.   {

3.           *p = malloc(100);

4.    }

5.    int main(void)

6.    {

7.            char *s;

8.            getMemory(&s);

9.            strcpy(s, "Hello");

10.          puts(s);

11.   }

(二)用例

(三)口诀

1.二维数组作为函数参数,形参为指向数组的指针

2.指针数组作为函数参数,形参为指向指针的指针

示例1:

int  a[3][4];

int rows = sizeof(a) / sizeof(*a);

foo(&a[0], rows);

void  foo(int(*a)[4], int rows);

示例2:

char *s[3];

int len = sizeof(s) /sizeof(*s);

bar(&s[0], len);

void bar(char **s, int len);

(四)例题

1、指针数组打印;

2、指针数组逆序;

3、指针数组排序;

4、指针数组查找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值