Linux高级C
本系列是基于入门学完的基础上,为了更好的玩机体验,对一些知识点的进一步延伸与扩展。
注意啦:以下是本人介绍哦
📕作者简介:S学长,致力于C/C++、嵌入式。从事嵌入式行业,热爱健身,身体倍棒的一位博主。
📗本文收录于Linux高级C系列,大家有兴趣的可以看一看
📘相关专栏C语言嵌入式开发、C语言入门系列等,日常Bug集期待你的指导。
📙Linux爱上Ubuntu系列正在发展中,喜欢嵌入式的朋友们可以关注一下哦!
1、指针函数
概念:返回地址的函数称为指针函数。
基础c讲解过函数,下面结合对不同的区域的数据操作来理解指针函数。
代码示例:指针函数的返回。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * fun1(void)
{
char *p = "hello world";
return p; //可以返回.rodata中的地址,只读数据,不能被修改
}
char * fun2(void)
{
char p[] = "hello world";
return p; //不能返回.statck中的地址,存储期在函数结束时
}
char * fun3(void)
{
static char p[] = "hello world";
return p; //可以返回.data中的地址,且数据可读可写
}
char * fun4(void)
{
char *p = (char*)malloc(100);
strcpy(p,"hello world");
return p; //可以返回.heap中的地址,且读数据可以读写
}
void fun(void)
{
printf("hello world\n");
}
typedef void(*FUNP_T)(void);
//void (*fun5(void))(void)
FUNP_T fun5(void)
{
return fun; //可以返回.text中的地址,只读空间,不能修改
}
int main(void)
{
#if 0
char *str;
str = fun();
*str = 'H';
printf("str = %s\n",str);
#else
void (*p)(void);
p = fun5();
p();
#endif
return 0;
}
运行结果:
2、递归函数
概念:如果一个函数的函数体中调用自己,这样的函数称为递归函数
递归函数必须具备以下几点:
1> 必须具备两个阶段:递推阶段和回归阶段
2> 必须有递推终止条件
代码示例:
void fun(int n)
{
printf("n = %d\n",n);
if(n > 0)
fun(n-1);
}
3、回调函数
概念:间接调用的函数称为回调函数
通常会结合指针函数
代码示例:
#include <stdio.h>
//回调函数
void fun1(void)
{
printf("hello S学长\n");
}
void fun3(void)
{
printf("点赞!收藏! 关注!\n");
}
void fun2(void (*p)(void))
{
p();
}
int main(void)
{
void (*p)(void) = fun3;
fun1(); //直接调用
fun2(fun3);
p(); //通过函数指针调用
fun2(fun1); //回调
return 0;
}
运行结果:
4、内联函数
通常函数调用需要一定的时间开销。这意味着执行调用时花费了时间用于函数调用、传递参数、跳转到函数代码段并返回。使用类函数宏的一个原因就是可减少执行时间。
内联函数:通过把一个函数声明为内联类型,将建议编译器尽可能快速地调用该函数。上述建议的效果由实现来定义。
定义内联函数的方法是在函数声明中使用函数说明符inline。
例如:
inline int max(int i, int j)
{
return (i>j)?i:j;
}
因为内联函数没有预留给他的单独代码块,所以无法获得内联函数的地址。
函数返回数据的方式
结合下面代码理解。
1.通过return语句返回
int fun1(int a,int b)
{
int sum;
sum = a + b;
return sum;
}
int fun2(int a,int b)
{
int sub;
sub = a - b;
return sub;
}
int main(void)
{
int a,b;
int sum,sub;
printf("pls input a and b:");
scanf("%d%d",&a,&b);
sum = fun1(a,b);
printf("%d + %d = %d\n",a,b,sum);
sub = fun2(a,b);
printf("%d - %d = %d\n",a,b,sub);
return 0;
}
运行结果:
2.通过传地址返回
代码示例:求两数和/差
#include <stdio.h>
void fun(int a,int b,int*x,int*y)
{
*x=a+b;
*y=a-b;
}
int main(void)
{
int a,b;
int sum,sub;
scanf("%d%d",&a,&b);
fun(a,b,&sum,&sub);
printf("%d+%d=%d\n",a,b,sum);
printf("%d-%d=%d\n",a,b,sub);
return 0;
}
运行结果:
总结
上面说了那么多函数,总结一下函数调用的过程。调用函数的时,1.将程序返回地址压入栈中,2.找到调用函数的入口地址。3.从函数入口地址执行程序。4.执行完程序释放栈中数据的空间5.弹出栈中返回地址6.跳转到返回地址出继续程序执行。
如果这份博客对大家有帮助,希望各位给S学长一个免费的点赞👍作为鼓励,并评论收藏一下⭐,谢谢大家!!!
制作不易,如果大家有什么疑问或给S学长的意见,欢迎评论区留言。