C语言函数的基本用法(迭代与递归)

先简单介绍一下C语言函数

c语言函数是用来编译c语言,所在库函数为ctype.h,分为库函数和自定义函数。

从表面上看,函数使用时必须带上括号,有必要的话还要传递参数,函数的执行结果也可以赋值给其他变量。

1.库函数与自定义函数

库函数包括 IO函数 字符串操作函数 字符操作函数 内存操作函数 时间/日期函数 数学函数 其他库函数,库是编程的一个基本概念,可以认为它是一系列函数的集合。而自定义函数则根据自己的需要进行编写,使用的时候必须加上头文件 #include "自定义函数“。

库函数用法

#include
#include
int main()
{
	char arr1[] = "bit";
	char arr2[20] = "************";
	strcpy(arr2, arr1);
	printf("%s\n",arr2);
	return 0;
}

自定义函数用法

用法格式:

函数类型 函数名(函数参数)
{
    函数体;
}

示例如下

int get_max(int x,int y)
{
	if (x > y)
		return x;
	else
		return y;
}
int main()
{
	int a = 10;
	int b = 20;
	int max=get_max(a,b);
	printf("max=%d\n", max);
	return 0;
}

下面举一个自定义函数调用的示范题

//通过函数的调用实现两个数的交换
#include
void swap(int* pa, int* pb)
{
	int tmp = 0;
	tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
	swap(&a, &b);
	printf("a=%d b=%d\n", a, b);
	return 0;

2.形参与实参


实参:是真实传递给函数的参数,常量、变量、表达式、函数等。无论实参是哪种类型的量,在进行函数调用时,都必须有确定的值,以便把这些值传给形参。
形参:是指函数名后括号内的变量,因为形参只有在函数调用的过程中才实例化(分配内存单元),所以叫形式参数,形参调用完就自动销毁了。

形参实例化之后相当于实参的一份临时拷贝。

下面举些例子包括函数的调用及形参实参的使用

       1.判断100-200中的素数有哪些(素数是只有1和它本身的约数)

#include  
int is_prime(int n)
{
	int j = 0;
	for (j = 2; j < n; j++)
	{
		if (n % j == 0)
			return 0;
	}
	return 1;
}
int main()
{
	int i = 0;
	for (i = 100; i <= 200; i++)
	{
		if (is_prime(i) == 1)
			printf("%d ",i);
	}
	return 0;
}

       2.判断1000-2000之间的闰年有哪些

#include  
int is_leap_year(int n)
{
	//判断闰年(能被4整除并且不能被100整除的的闰年;能被400整除的是闰年)
	if (n % 4 == 0 && n % 100 != 0 || (n % 400 == 0))
		return 1;
	else 
		return 0;
}
int main()
{
	int year = 0;
	for (year = 1000; year <= 2000; year++)
	{
		if (is_leap_year(year) == 1)
			printf("%d ", year);
	}
	return 0;
}

        3.函数的调用实现二分查找

#include  
int binary_search(int arr[], int k,int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left<=right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//传递过去的是数组arr首元素的地址 4bit/4bit=0
	int ret = binary_search(arr, k, sz);
	if (ret == -1)
	{
		printf("找不到指定的数字\n");
	}
	else 
	{
		printf("找到了,下标是: %d\n", ret);
	}
	return 0;
}

3.函数的嵌套调用和链式访问  

函数与函数之间是可以有机组合的,链式访问是把一个函数的返回值作为另一个函数的参数,示例如下

#include
void new_line()
{
	printf("hehe\n");
}
void three_line()
{
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		new_line();
	}
}
int main()
{
	three_line();
	return 0;
}
int main()
{
	int len = 0;
	//1
	len = strlen("abc");
	printf("%d\n", len);
	//2
	printf("%d\n", strlen("abc"));
}

4.函数的声明和定义

源文件(定义)+头文件(声明) 把函数声明放在头文件,源文件引用函数,添加自定义头文件 #Include"Add"即可

int Add(int, int);//函数声明
int main()
{
	int a = 10;
	int b = 20;
	int sum = 0;
	//函数调用
	sum = Add(a, b);
	printf("%d\n", sum);
	return 0;
}

#include"Add"
int Add(int x, int y)//函数定义
{
	int z = x + y;
	return z;
}

5.函数的递归

递归:程序调用自身的编程技巧为递归,它通常是把一个大型的复杂问题转化为规模较小的问题来解决,可以减少代码的使用量,递归的能力在于用有限的语句来定义对象的无限集合。

使用递归有两个必要条件:

1)存在限制条件,满足限制条件时,便不再继续  ;

2)每次递归调用之后越来越接近这个限制条件。

例如:输入一个数,按位输出

输入123;

输出1 2 3;

#include  
void print(int n)
{
	if (n > 9)
	{
		print(n / 10);
	}
	printf("%d ", n%10);
}
int main()
{
	unsigned int num = 0;
	scanf("%d", &num);
	print(num);
	return 0;
}

2 .不定义数组,实现对字符串的字符数统计  

输入 “world”;(\0)

输出  6  

#include 
int my_strlen(char* str)
{
	if (*str != '\0')
		return 1 + my_strlen(str + 1);
	else
		return 0;
}
int main()
{
	char arr[] = "world";
	//int len = strlen(arr);//求字符串长度
	//printf("%d\n", len);

	//模拟实现了一个strlen函数
	int len = my_strlen(arr);//arr是数组,数组传参,传过去的不是整个数组,而是首元素的地址
	printf("len=%d\n", len);
	return 0;
}

3.利用递归实现n的阶乘

#include 
int Fac(int n)
{
	if (n <= 1)
		return 1;
	else
		return n * Fac(n - 1);
}
int main()
{
	int n = 0;
	int ret = 0;
	scanf("%d", &n);
	ret = Fac(n);
	printf("%d\n", ret);
	return 0;
}

4.利用递归实现斐波那契数列

#include
int Fib(int n)
{
	if (n <= 2)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}
int main()
{
	int n = 0;
	int ret = 0;
	scanf("%d", &n);
	ret = Fib(n);
	printf("ret=%d\n", ret);
	return 0;
}

5.利用递归实现汉诺塔问题

#include
int hanio(int num)
{
	if (num == 1)
	{
		return 1;
	}
	else
	{
		return 2 * hanio(num - 1) + 1;
	}
}
int main()
{
	int num = 0;
	scanf("%d", &num);
	int ret = hanio(num);
	printf("完成%d层的汉诺塔需要移动%d步\n",num,ret);
	return 0;
}

6. 利用递归实现青蛙跳跃问题(剑指Offer经典例题)

#include
int flag(int num)
{
	if (num == 1)
		return 1;
	if (num == 2)
		return 2;
	else
		return flag(num - 1) + flag(num - 2);
}
int main()
{
	int num = 0;
	int ret = 0;
	scanf("%d", &num);
    ret = flag(num);
	printf("到达%d层有%d种跳跃路线\n", num, ret);
	return 0;
}

6.函数的迭代

迭代:利用变量的原值推算出变量的一个新值。

如果递归是自己调用自己的话,迭代就是A不停调用B

大家能使用迭代法就用迭代法,递归法容易造成堆栈的溢出

#include //函数调用一次,num自增1
void Add(int* p)
{
	(*p)++;
}
int main()
{
	int num = 0;
	Add(&num);
	printf("num=%d\n", num);
	Add(&num);
	printf("num=%d\n", num);
	Add(&num);
	printf("num=%d\n", num);
	return 0;
}

因此,适当的使用迭代和递归思想可以更好的解决相对复杂的问题,减小代码量。

 

你可能感兴趣的:(c语言)