C语言 函数

引言

C语言的函数分为两类,一类是库函数、另一类是自定义函数。

库函数

库函数即 C语言 官方为我们提供的一类函数,我们可以访问下面的 C++ 官方网站,查看头文件下包含的各种函数。

http://zh.cppreference.com

1-1

类似的,也可以访问下面的网站,用的也较多。

https://cplusplus.com

1-2

一、函数的声明和定义

程序清单:

#include <stdio.h>

int add(int x, int y); // 函数声明
//int add(int, int);

int main() {

	int a = 3;
	int b = 5;

	int result = add(a, b); // 函数调用
	printf("%d\n", result);
	return 0;
}

int add(int x, int y) { // 函数定义

	return (x + y);
}

// 输出结果:8

注意事项:

① 一个标准的 C语言 函数创建包含了三个要素:函数声明、函数定义、函数调用。

② 由于 main 函数作为程序的入口,之后程序是自上而下执行的,所以当我们的函数定义写在了函数调用之后,就需要写函数声明;当我们的函数定义写在了函数调用之前,就不需要写函数声明了。

③ 此外,上面的函数实现了一个加法函数 add,但在工作的时候,我们更多的是以分文件的形式来实现它。【add.h 和 add.c】叫做一个模块,我们可以在主程序中,通过引入头文件的方式来引入函数。如下图所示:

1-3

二、函数实参与形参的区别

程序清单1

#include <stdio.h>

void swap(int x, int y) {
	int tmp = x;
	x = y;
	y = tmp;	
}

int main() {
	int a = 3;
	int b = 5;
	printf("a = %d b = %d\n", a, b);
	swap(a, b);
	printf("a = %d b = %d\n", a, b);

	return 0;
}

输出结果:

1-4

分析:

在程序清单1 中,a, b 为实参,x, y 为形参。

当 a 和 b 传入 swap( ) 函数的时候,x 和 y 确实能拿到 3 和 5 这两个值,但 x 和 y 本身与 a 和 b 拥有不同的地址,这就造成一个结果:在swap() 函数中,只交换了形参 x 和 y 的值,对于实参 a 和 b 来说,毫无影响。

1-5

程序清单2

#include <stdio.h>

void swap(int* pa, int* pb) {
	int tmp = *pa; // 解引用
	*pa = *pb;
	*pb = tmp;
}

int main() {
	int a = 3;
	int b = 5;
	printf("a = %d b = %d\n", a, b);
	swap(&a, &b);
	printf("a = %d b = %d\n", a, b);

	return 0;
}

输出结果:

1-6

分析:

在程序清单2 中,当我们实参传的是 a 和 b 的地址时,情况就完全不一样了,在 swap( ) 函数中,我们形参拿整型指针类型来接收地址,最后再通过解引用符号 " * " 来拿到地址对应的值,即可交换。

这里需要注意: pa 和 pb 存的值是 a 和 b 的地址,然而 pa 和 pb 本身是一个指针变量,既然是变量,它们也有属于自己的地址,前者后者不能搞混了。

1-7

总结

① 形参是实参的一份临时拷贝,形参只在当前函数中有效,出了当前函数,即被销毁,所以改变形参本质上不会影响实参的状态。

② 在 C 语言中,我们可以利用指针接收地址,从而拿到地址对应的值来直接进行改变实参。

三、函数的嵌套调用和链式访问

1. 嵌套调用

函数可以嵌套调用,但是不能嵌套定义。

void test2() {

	printf("hello world\n");
}

void test1() {

	test2();
}

int main() {

	test1();

	//void test() {     // 错误的示范:函数不能嵌套定义
	//
	//}

	return 0;
}

// 输出结果:hello world

2. 链式访问

把一个函数的返回值作为另外一个函数的参数,称为函数的链式访问。

程序清单:

#include <stdio.h>

int main() {

	int len = strlen("abcdef");
	printf("%d ", len);

	printf("%d", strlen("abcdef")); // 链式访问
	return 0;
}

// 输出结果:6 6

程序清单:( printf 返回值是成功打印的字符数 )

#include <stdio.h>

int main() {

	printf("%d", printf("%d", printf("%d", 43))); // 链式访问
	// printf("%d", printf("%d", 2));
	// printf("%d", 1);

	return 0;
}

// 输出结果:4321

四、函数的递归

函数的递归,我之前通过 Java 总结了一篇博客,虽然语言不同,但思想都是一样的。链接如下:

递归的思想

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十七ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值