嵌入式入门学习笔记,遇到的问题以及心得体会!
DAY14
概述:
1.指针函数
2.函数指针
笔记:
1,指针函数
2,函数指针
1、指针函数:
概念:返回值类型是指针的函数
定义格式:
数据类型 函数名(数据类型1 参数名1,数据类型2 参数名2)
{
函数体;
}
注意:处于返回值类型的位置必须是指针类型
案例:
1 #include <stdio.h>
2
3
4 char * Func()
5 {
6 //定义一个字符数组
7 //char str[20] = {"wangjia"};
8 //static char str[20] = {"wangjia"};
9 char *str = "wangjiajia";
10 return str;
11 }
12 int main(int argc, const char *argv[])
13 {
14 //char *p = Func();
15 char *p = NULL;
16 p = Func();
17 puts(p);
18 return 0;
19 }
分析:
思考:
当在子函数中定义为:char str[20] = {"wangjia}时,此时返回str。为什么看不到该数组中的内容(随机值)?
本质原因:因为返回的数组名是一个局部变量
解决办法:
(1)延长生命周期—》static char str[20] = {“wangjia”}
(2)让指针变量str指向常量区的内容—》char *str = “wangjia”
但是:如果被static修饰完之后,假设程序不终止,那么这片空间将一直被占用,会造成内存空间浪费
---》因此,有没有一种可以动态管理(申请和释放)内存的方法?
通过堆区可以实现!!
堆区: 该空间是由程序员自己管理的—》意味着申请和释放均由自己来完成。
内存管理函数:
头文件:
#include <stdlib.h>
函数原型:
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
分析函数三步走:
第一步:函数功能
第二步:函数参数
第三步:函数返回值
(1)申请:
void *malloc(size_t size);
函数功能:申请一片连续的内存空间
函数参数:所需申请空间所占的字节数
函数返回值:
void *是一个万能指针,如果想用该函数的返回值做什么事情,只需要将其强转即可
如果申请空间成功:则返回值代表该连续空间的首地址
如果申请失败:则用NULL
(2)释放:
void free(void *ptr);
函数功能: 用来释放一片连续的空间
函数参数: 申请成功时的空间首地址
返回值:无返回值void
(3)扩容
void *realloc(void *ptr, size_t size);
函数功能:用来进行扩容
函数参数:
参数1:所需扩容的空间的首地址
参数2:扩容之后的总的字节数(旧+ 新)
函数返回值:
成功则返回扩容之后的空间的起始地址(改地址有可能和之前malloc的一样,也可能不一样)
失败则返回NULL
(4)清空函数:
头文件:
#include <string.h>
函数原型:
void *memset(void *s, int c, size_t n);
函数功能:永来清空一片空间的内容
函数参数:
参数1:所需清空空间的首地址
参数2:所需清空的内容,一般用0或者’\0’都可
参数3:所需清空的字节数
2、函数指针:指向函数的指针
(1)如何定义一个函数指针类型
格式:
返回值类型 (*指针变量名)(数据类型1 ,数据类型2 。。。。。)
pFunc = &add---->*pFunc = add
pFunc = add
add == (*add)
(2)给函数指针类型取别名?
typedef 返回值类型 (* 类型名)(数据类型1,数据类型2);
(3)如何定义一个函数指针数组?
对于函数指针数组的理解:数组元素为函数指针类型的数组
格式:
返回值类型 (*数组名[元素个数])(数据类型1 ,数据类型2 。。。。。)
回调函数:
通过函数指针调用的函数就是回调函数—》在一个函数里面完成对另外一个函数的调用
案例代码:
1.定义一个字符数组,用malloc实现动态申请空间,用来存储一个字符串
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * Func()
{
//定义一个字符数组
//char str[20] = {"wangjia"};
//static char str[20] = {"wangjia"};
//char *str = "wangjiajia";
//用malloc实现动态申请空间,用来存储一个字符串
char *pstr = (char *)malloc(100);
if(NULL == pstr)
{
printf("malloc error!\n");
return NULL;
}
//清空
memset(pstr,'\0',100);
//pstr = "wangjia";相当于直接将pstr的指向改变到指向常量区
strcpy(pstr,"wangjiajia");//完全存储"wangjiajia"中的每一个字符,和数组一样了
return pstr;
}
int main(int argc, const char *argv[])
{
//char *p = Func();
char *p = NULL;
p = Func();
puts(p);
//释放
free(p);
//置空
p = NULL;
return 0;
}
#include <stdio.h>
//定义一个函数,返回值类型int ,形参类型为2个int
int add(int argc1,int argc2)
{
return argc1 + argc2;
}
int main(int argc, const char *argv[])
{
//定义一个函数指针,指向add函数
int (*pFunc)(int,int);
//pFunc = &add;
pFunc = add;
printf("请输入需要计算的两个参数:\n");
int num1,num2;
scanf("%d%d",&num1,&num2);
//add(num1,num2);
printf("add = %d\n",(*pFunc)(num1,num2));
//printf("add = %d\n",pFunc(num1,num2));
/*
int ret = (*add)(12,34);
printf("ret = %d\n",ret);
*/
return 0;
}
#include <stdio.h>
#define N 4
//int (*)(int,int)这个函数指针类型取一个别名叫MFunc
//typedef int (*MFunc)(int,int); //MFunc == int (*)(int,int)
//定义一个函数,返回值类型int ,形参类型为2个int
int add(int argc1,int argc2)
{
return argc1 + argc2;
}
int sub(int argc1,int argc2)
{
return argc1 - argc2;
}
int mul(int argc1,int argc2)
{
return argc1 * argc2;
}
int div(int argc1,int argc2)
{
return argc1 / argc2;
}
int main(int argc, const char *argv[])
{
//定义一个函数指针,指向add函数
//int (*pFunc)(int,int);
//pFunc = &add;
//MFunc pFunc;
//pFunc = &add;
//定义一个函数指针数组
int num1,num2;
scanf("%d%d",&num1,&num2);
//add(num1,num2);
int (*pFunc[N])(int,int) = {add,sub,mul,div};
int i;
for(i=0;i<N;i++)
{
printf("result: %d\n",(*pFunc[i])(num1,num2));
}
//printf("add = %d\n",(*pFunc)(num1,num2));
//pFunc = ⊂
//printf("sub = %d\n")
//printf("add = %d\n",pFunc(num1,num2));
/*
int ret = (*add)(12,34);
printf("ret = %d\n",ret);
*/
return 0;
}
#include <stdio.h>
//给函数指针类型取别名
typedef int (*MFunc)(int,int);
//实现回调函数
int add(int argc1,int argc2)
{
return argc1 + argc2;
}
//回调函数
//int CallBack_Func(int num1,int num2,int (*pFunc)(int,int))
int CallBack_Func(int num1,int num2,MFunc pFunc)
{
return (*pFunc)(num1,num2);
}
int main(int argc, const char *argv[])
{
int argc1,argc2;
printf("please input two numbers:\n");
scanf("%d%d",&argc1,&argc2);
//回调函数的调用接口
int ret = CallBack_Func(argc1,argc2,&add);
printf("ret = %d\n",ret);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//利用字函数实现malloc申请一片连续的空间存储5个整形元素
int * Func_Malloc(int COUNT)
{
int *pArr = (int *)malloc(COUNT * sizeof(int));
if(NULL == pArr)
{
printf("NULL_ERROR!\n");
return NULL;
}
//清空
memset(pArr,0,COUNT*sizeof(int));
//返回首地址
return pArr;
}
//输出函数
int my_outputValues(int *pArr,int COUNT)
{
if(NULL == pArr || COUNT < 0)
{
printf("参数出错啦!\n");
return -1;
}
int i;
printf("输出为:\n");
for(i=0;i<COUNT;i++)
{
printf("%d ",*(pArr+i));
}
putchar('\n');
return 0;
}
int BubbleSort_Func(int *pArr,int COUNT)
{
if(NULL == pArr || COUNT < 0)
{
printf("出错!\n");
return -1;
}
int i,j;
for(i=0;i<COUNT-1;i++)
{
for(j=0;j<COUNT-1-i;j++)
{
if(*(pArr+j) > *(pArr+j+1))
{
//交换---》中间变量
int Temp;
Temp = *(pArr+j);
*(pArr+j) = *(pArr+j+1);
*(pArr+j+1) = Temp;
}
}
}
return 0;
}
int main(int argc, const char *argv[])
{
//定义一个接收字函数的返回值
int *p = NULL;
int count;
printf("请输入存放的数据元素的个数:\n");
scanf("%d",&count);
p = Func_Malloc(count);
int i;
printf("请输入:\n");
for(i=0;i<count;i++)
{
scanf("%d",p+i);
}
int ret = my_outputValues(p,count);
if(-1 == ret)
{
return -1;
}
printf("输出成功!\n");
//冒泡排序
ret = BubbleSort_Func(p,count);
if(ret < 0)
{
return -1;
}
printf("冒泡之后结果为:\n");
ret = my_outputValues(p,count);
if(ret < 0)
{
return -1;
}
//释放空间
printf("释放中....\n");
free(p);
//置空
printf("释放成功!\n");
p = NULL;
return 0;
}
- 这串代码和上面的5有区别,可以对比这来敲
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//利用字函数实现malloc申请一片连续的空间存储5个整形元素
void Func_Malloc(int **ppArr,int COUNT)
{
*ppArr = (int *)malloc(COUNT * sizeof(int));
if(NULL == *ppArr)
{
printf("NULL_ERROR!\n");
}
//清空
memset(*ppArr,0,COUNT*sizeof(int));
//返回首地址
//return pArr;
}
//输出函数
int my_outputValues(int *pArr,int COUNT)
{
if(NULL == pArr || COUNT < 0)
{
printf("参数出错啦!\n");
return -1;
}
int i;
printf("输出为:\n");
for(i=0;i<COUNT;i++)
{
printf("%d ",*(pArr+i));
}
putchar('\n');
return 0;
}
int BubbleSort_Func(int *pArr,int COUNT)
{
if(NULL == pArr || COUNT < 0)
{
printf("出错!\n");
return -1;
}
int i,j;
for(i=0;i<COUNT-1;i++)
{
for(j=0;j<COUNT-1-i;j++)
{
if(*(pArr+j) > *(pArr+j+1))
{
//交换---》中间变量
int Temp;
Temp = *(pArr+j);
*(pArr+j) = *(pArr+j+1);
*(pArr+j+1) = Temp;
}
}
}
return 0;
}
int main(int argc, const char *argv[])
{
//定义一个接收字函数的返回值
int *p = NULL;
int count;
printf("请输入存放的数据元素的个数:\n");
scanf("%d",&count);
Func_Malloc(&p,count);
//扩容
int num;
printf("请输入需要扩容的元素个数:\n");
scanf("%d",&num);
p = realloc(p,(count + num)*sizeof(int));
if(NULL == p)
{
printf("扩容失败!\n");
return -1;//主程序退出即可
}
printf("扩容成功!\n");
//定义一个总个数的变量
int All_Count = count + num;
int i;
printf("请输入:\n");
for(i=0;i<All_Count;i++)
{
scanf("%d",p+i);
}
int ret = my_outputValues(p,All_Count);
if(-1 == ret)
{
return -1;
}
printf("输出成功!\n");
//冒泡排序
ret = BubbleSort_Func(p,All_Count);
if(ret < 0)
{
return -1;
}
printf("冒泡之后结果为:\n");
ret = my_outputValues(p,All_Count);
if(ret < 0)
{
return -1;
}
//释放空间
printf("释放中....\n");
free(p);
//置空
printf("释放成功!\n");
p = NULL;
return 0;
}