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

目录

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. 写一个函数判断一年是不是闰年。

#include
int 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
#include
int 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  写一个函数,实现一个整形有序数组的二分查找。

#include
int 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;
}

你可能感兴趣的:(史上最强C语言,c语言)