C语言中的函数 学习

C函数

函数 即封装功能的容器

  • 定义函数的基本格式:

    return_type function_name( parameter list )
    {
       body of the function
    }
    
  • **返回类型:**一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void

  • **函数名称:**这是函数的实际名称。函数名和参数列表一起构成了函数签名。

  • **参数列表:**参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数 即void 不填默认为void。

  • **函数主体:**函数主体包含一组定义函数执行任务的语句。

  • 如果需要返回值 则在函数最后加入 return 返回值 ; return 会结束整个函数

  • 不需要 则在 返回值类型处填入 void(空类型 )

  • 函数需要被运行则需要 在入口 调用 才会被执行

局部变量:(栈区)

栈区系统自动申请和释放

定义时被称为入栈

释放时被称为出栈

在指定作用域 才能够起作用

  • 例如
    for(int i=0;i<10;i++){
    则 i 只有在for循环内才能够被访问
    在外 如果没有定义i则i不能被使用
    }
    在函数中定义的 变量 在其他函数中也不可以直接被使用

全局变量: (栈区)

在函数体外定义 该方法定义的变量可以被 定义位置 以下的 函数访问程序结束时才被释放

​ !全局变量和局部变量重名时 程序使用最近的变量值

静态变量(处于静态全局区)

静态全局区的变量只会被定义一次 整个程序结束后才会被释放

static int a=b

实验:

int main(void) {
	for (size_t i = 0; i < 10; i++)
	{
		static int a = 10;
		a++;
		printf("%d\n", a);
	}
	return 0;
}

结果image-20221014174036116

可以看出a只被定义了1次 程序不停止则该变量不会被释放

函数的声明

函数需要 先声明函数 再调用即:

void hello_world(void);

int main(void) {
	hello_world();
	return 0;
}

void hello_world(void) {
	printf("hello_world");
}

如果main前方不添加void hello_world(void);的话 则会提示函数未定义

地址

地址: 在定义变量 数组 函数等时系统会给他们分配内存区域(地址) 把这个数据放在这个地址上

取地址 &:&a取a的地址编号

定义一个指针*: char *a; 不一定是char 还可能是 其他类型

指针变量:存储地址的变量

整型变量:存储整数的变量

地址传递

将变量的地址作为参数传递,传递过去的任何操作都会映射到源地址

void change_num(int *b) {
	*b = 100;
}

int main(void) {
	int a = 1;
	change_num(&a);
	printf("%d\n", a);
	return 0;
}

结果:

image-20221014180319914

结论:当地址被传递时 对地址的值进行修改,该修改作用于源于数据

传递数组

	void print_arr(int a[],int len) {

		for (size_t i = 0; i <len; i++)
		{
			printf("%d\n", a[i]);
		}
	}
 			
	int main(void) {

		int b[] = { 1,2,3,654,6,4,98,465,4,64 };
		int c[30] = { 1,65,54,531,56,456,564,654,6,4598,7,89, 		};
		print_arr(b,sizeof(b)/sizeof(b[0]));
		print_arr(c,30);


		return 0;
	}

函数的递归

在一个函数中 重复的调用函数本身

利用递归求阶乘

int  recursion_fun(int a)
{
	if (a == 1) {

		return a;
	}
	return a*recursion_fun(a-1);
}

int main(void) {

	printf("%d",recursion_fun(11));
	return 0;
}

结果

image-20221015000607191

静态变量实验:

void demo_static(void) {
	static int a = 10;
	if (a!=0)
	{
		a--;
		demo_static();
	}
	printf("%d\n", a);
}

int main(void) {
	demo_static();
	return 0;
}

结果:

image-20221015000952356

结论: 因为static在程序运行时只能够被定义一次 即第一次被定义时地址已经被确定 在每一次递归调用时操作的都是 a原来的地址 当a被等于0时 递归结束 函数以此退出并打印 全是0是因为在递归后输出 而不是在递归前输出 当退出时a已经等于0所以每一层的函数打印访问的都是0

猴子偷桃递归

int fun1(int apple) {
	static int day = 1;
	//apple = 1
	//猴子吃桃
	//有桃子若干 猴子每天吃一半的桃子+1个
	// (n/2)-1= -((n/2)-1)/2-1
	//第十天剩一个
	//需要一个统计天数
	//1  (1+1)*2 ((1+1)*2+1)*2
	if (day == 10) {
		return apple;
	}
	day++;
	fun1((apple+1)*2);
}//

int main(void) {
	printf("%d", fun1(1));
	return 0;
}

结果

image-20221015004926517

函数指针

函数指针是指向函数的指针变量。

通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。

函数指针可以像一般函数一样,用于调用函数、传递参数。

函数指针变量的声明:

typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型

例子:

#include <stdio.h>


int add(int a, int b,int c) {

	return a+b+c;
}
double max(double a, double b) {
	return a > b ? a : b;
}
int main(void) {
//	返回类型 指针名	 第一个参数类型	 第二个参数类型    第三个参数类型	   方法名称 &可以不用
	int      (*p)   (	int,			 int,				int) =			& add;
	printf("sum:%d\n", p(1,3,5));

	double (*p2)(double, double) = max;
	printf("sum:%.2lf\n", p2(1, 5));
	return	0;
}

回调函数

函数指针作为某个函数的参数

即函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。

定义格式:

 function_name(typedef1 (*fun_ptr)(typedef2 name2,typedef3 name3 ,...),...)
//typedef1 为函数返回类型
//typedef2 形参1变量类型
//typedef3 形参2变量类型
//*fun_ptr 为函数指针名称
//传递方式   function_name2为函数名称 且不能够带() 否则报错
function_name(function_name2)
#include <stdio.h>

void do_something(int a, int b, int (*add_num)(int a, int b)) {

	printf("%d",add_num(a, b));

}

int get_num_sum(int a, int b) {
	return	a + b;
}


int main(void) {

	do_something(3, 9, get_num_sum);

	return	0;
}

结果:

image-20221015020408996

结论 回调函数即函数指针变种 直接将函数传递给 其他函数 做参数

在被传递的函数中 可以直接使用 该函数指针 即相当于调用该方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值