资讯专栏INFORMATION COLUMN

史上最强C语言教程----函数(1)

A Loity / 1647人阅读

摘要:无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。形式参数当函数调用完成之后就自动销毁了。函数的调用传值调用函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。没有找到找到了下标为

目录

1.  函数是什么?

2.  C语言中函数的分类:

2.1 库函数

2.1.1 为什么要有库函数

2.1.2 什么是库函数

2.1.3 主函数只能是main()吗

2.1.4常见的库函数

2.2 自定义函数

2.2.1自定义函数是什么

2.2.2为什么要有自定义函数

2.2.3函数的组成

2.2.4 举例展示

3. 函数的参数

3.1 实际参数(实参)

3.2  形式参数(形参)

4. 函数的调用

4.1 传值调用

4.2  传址调用

4.3 练习

4.3.1. 写一个函数判断一年是不是闰年。

4.3.2.写一个函数可以判断一个数是不是素数。

4.3.3  写一个函数,实现一个整形有序数组的二分查找。


1.  函数是什么?

提到函数,我们最先想到的肯定是数学中的函数,那么C语言中的函数究竟是什么呢?接下来带大家看一下吧!

维基百科中对函数的定义:子程序

在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组 成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软 件库。

2.  C语言中函数的分类:

2.1 库函数

2.1.1 为什么要有库函数

1. 我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格 式打印到屏幕上(printf)。

2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)。

3. 在编程是我们也计算,总是会计算n的k次方这样的运算(pow)。

像上面我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到, 为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。

2.1.2 什么是库函数

那么什么是库函数呢?举个简单的例子,库函数就是C语言本身给我们已经定义好的函数,作为程序员我们可以直接使用,就像printf()和scanf()。

注意使用库函数必须包含头文件,例如我们使用printf()与scanf()时要引用stdio.h头文件,即我们通常写的#include

2.1.3 主函数只能是main()吗

很多小伙伴就疑惑了,那么主函数是什么呢?主函数为什么叫main函数呢?我们必须使用main()函数吗?接下来给大家解除这个疑惑!

首先给大家一个结论,C语言中默认main作为主函数的名字,但是主函数的名字却不一定一定是main(),实际上,我们可以自己进行设定主函数的名字的,C语言中提供了#pragma comment()可以自己设定主函数的名字,有兴趣的小伙伴可以自己去尝试,在这个地方像哟啊告诉大家,作为程序的入口主函数的名字不一定必须是main(),希望大家可以记住这个!至于主函数为什么叫main()函数,这本身就是C语言默认的,如果硬要强行解释一波的话,main()的英文意识 就是主要的意思。

2.1.4常见的库函数

IO函数

字符串操作函数

字符操作函数

内存操作函数

时间/日期函数

数学函数

其他库函数

这个地方不会展开去讲,后期用到的时候具体讲解。

2.2 自定义函数

2.2.1自定义函数是什么

自定义函数就是程序员自己定义用于首先特定功能的函数!比如我们要完成两个数的相加我们定义的add()函数就属于自定义函数。

2.2.2为什么要有自定义函数

自定义函数和库函数一样,有函数名,返回值类型和函数参数。

但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。

2.2.3函数的组成

ret_type fun_name(para1, *){	statement;//语句项}ret_type 返回类型fun_name 函数名para1    函数参数

2.2.4 举例展示

(1)写一个函数可以找出两个整数中的最大值。

#include //get_max函数的设计int get_max(int x, int y){	return (x > y) ? (x) : (y);}int main(){	int num1 = 10;	int num2 = 20;	int max = get_max(num1, num2);	printf("max = %d/n", max);	return 0;}

这个地方给大家解释一下三目运算符,即上面的(x>y)?(x):(y),这个地方表示的是,如果x>y成立,就返回x的值,反之就返回y的值,这样就达到了求最大值的目的!

(2)写一个函数求两个数的和

#include //get_add函数的设计int get_add(int x, int y){	return (x + y);}int main(){	int num1 = 10;	int num2 = 20;	int sum = get_add(num1, num2);	printf("sum = %d/n", sum);	return 0;}

3. 函数的参数

3.1 实际参数(实参)

真实传给函数的参数,叫实参。 实参可以是:常量、变量、表达式、函数等。

注意:为什么可以是函数呢?因为有的函数是由返回值的,所以自然也就能充当实参。

无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形 参。

3.2  形式参数(形参)

形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内 存单 元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

为什么这样说呢?接下来给大家举个例子吧!

例如我们要交换两个变量的值:

#include void swap(int x, int y){	int temp = x;	x = y;	y = temp;}int main(){	int num1 = 10;	int num2 = 20;	swap(num1, num2);	printf("num1 = %d/nnum2 = %d", num1,num2);	return 0;}

下面是代码的运行结果:

很明显,并没有达成交换的目的,这就证明了:形式参数当函数调用完成之后就自动销毁了,即我们把num1和num2传给x和y之后,虽然我们在函数例将x和y交换了,但是由于x和y在swap函数调用完成后就销毁了,即并没有真正实现num1和num2的交换。

所以我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝

4. 函数的调用

4.1 传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。我们上述的交换的例子就是传值调用,即并不能真正达成交换两个变量的值的目的!

4.2  传址调用

传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。

这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操 作函数外部的变量。

同样,我们就以前面的交换两个变量的值的例子来给大家进行举例!

#include void swap(int *x, int *y){	int temp = *x;	*x = *y;	*y = temp;}int main(){	int num1 = 10;	int num2 = 20;	swap(&num1, &num2);	printf("num1 = %d/nnum2 = %d", num1,num2);	return 0;}

这个地方为什么会发生这种情况呢?等后期我们学到指针的那一节的时候将会具体讲解!

4.3 练习

4.3.1. 写一个函数判断一年是不是闰年。

#includeint is_leap_year(int year){	if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)	{		return 1;	}	else	{		return 0;	}}int main(){	int year = 0;	int flag = 0;	scanf("%d", &year);	flag=is_leap_year(year);	if (1 == flag)	{		printf("是闰年!");	}	else	{		printf("不是闰年!");	}	return 0;}

4.3.2.写一个函数可以判断一个数是不是素数。

#include#includeint is_prime_num(int n){	int flag = 0;	int i = 0;	for (i = 2; i <= sqrt(n); i++)	{		if (n % i == 0)		{			return 0;		}	}	return 1;}int main(){	int i = 0;	for (i = 100; i < 200; i++)	{		int flag = 0;		flag=is_prime_num(i);		if (1 == flag)		{			printf("%d ", i);		}		else			continue;			}	return 0;}

4.3.3  写一个函数,实现一个整形有序数组的二分查找。

#includeint find_num(int arr[], int size,int k){	int left = 0;	int right = 0;	right = size - 1;	int mid = 0;	while (left <= right)	{		mid = (left + right) / 2;		if (arr[mid] < k)		{			left = mid + 1;		}		else if (arr[mid] > k)		{			right = mid - 1;		}		else		{			return mid;		}	}	if (left > right)	{		return -1;	}}int main(){	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };	int k = 7;	int size = 0;	size = sizeof(arr) / sizeof(arr[0]);	int ret = 0;	ret = find_num(arr, size,k);	if (-1 == ret)	{		printf("没有找到!");	}	else	{		printf("找到了!下标为%d", ret);	}	return 0;}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123958.html

相关文章

  • 史上最强C语言教程----分支和循环(4)

    摘要:表达式表达式为调整部分,用于循环条件的调整。语句的循环控制变量建议不可在循环体内修改循环变量,防止循环失去控制。建议语句的循环控制变量的取值采用前闭后开区间写法。注意当条件初始化条件判断条件更新都省略后,程序将进入死循环。 目录 3.2 for循环 3.2.1 语法 3.2.2 break与...

    lei___ 评论0 收藏0
  • 史上最强C语言教程----分支和循环(5--终篇)

    摘要:目录循环循环语句的语法语句的语法执行流程执行流程语句的特点语句的特点循环中的和循环中的和练习练习计算的阶乘。多层循环这种情况使用是达不到目的的。它只能从最内层循环退出到上一层的循环。 目录 3.3 do...while()循环 3.3.1 do语句的语法: 3.3.2 执行流程 3.3.3...

    Reducto 评论0 收藏0
  • 深入浅出 Java 中的包装类

    摘要:前阵子,我们分享了中的基本数据类型转换这篇文章,对许多粉丝还是有带来帮助的,今天讲一下包装类的的由来,及自动装箱拆箱的概念和原理。下面是基本数据类型与对应的包装类型。 showImg(https://segmentfault.com/img/remote/1460000016537706); 前阵子,我们分享了《Java中的基本数据类型转换》这篇文章,对许多粉丝还是有带来帮助的,今天讲...

    ytwman 评论0 收藏0
  • Hystrix 停止开发。。。Spring Cloud 何去何从?

    摘要:栈长得到消息,停止开发了。。。是一个轻量级的容错组件,其灵感来自于,主要为和函数式编程设计的看到这里,栈长表示学不动了。。。上面说了,官方推荐替代的开源组件,这个栈长也没有用过,查了下,资料也比较稀少。 showImg(https://segmentfault.com/img/remote/1460000017201104?w=1600&h=1066); 栈长得到消息,Hystrix ...

    陆斌 评论0 收藏0
  • 屌炸天,Oracle 发布了一个全栈虚拟机 GraalVM,支持 Python!

    摘要:前阵子,发布了一个黑科技,号称是一个全新的通用全栈虚拟机,并具有高性能跨语言交互等逆天特性,真有这么神奇简介是一个跨语言的通用虚拟机,不仅支持了等基于的语言,以及等基于的语言,还支持其他像和语言等。原生镜像加速来看这段代码,同样来自官网。 前阵子,Oracle 发布了一个黑科技 GraalVM,号称是一个全新的通用全栈虚拟机,并具有高性能、跨语言交互等逆天特性,真有这么神奇? Graa...

    hiYoHoo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<