C语言集合(函数)

一、函数分类

函数定义:一般有输入参数和返回值,对过程进行封装和隐藏。

(一)库函数

  1. 库函数由编译厂商提供函数名、输入参数和返回值形式一般相同内部细节不同
  2. 一般使用库函数,必须包含#inclued的头文件,例如#include <stdio.h>。
  3. 库函数查询:库函数
    库函数

(二)自定义函数

自定义函数组成:函数名参数(定义类型)返回值

  1. 交换数字
void swap(int *a, int *b)
{
	int n = 0;
	n = *a;
	*a = *b;
	*b = n;
}


int main()
{
	int a,b = 0;
	while (scanf("%d %d", &a, &b) != EOF)
	{
		swap(&a,&b);
		printf("%d %d\n", a, b);
	}
	return 0;
}

因为形参是实参的一份临时拷贝,出函数就会销毁,如果不传地址,改变不了值。

  1. 判断闰年
int is_year(int n)
{
	return ((n % 400 == 0) || (n % 4 == 0 && n % 100 != 0)) ? 1 : 0;
}

int main()
{
	int a,b = 0;
	while (scanf("%d", &a) != EOF)
	{
		is_year(a)? printf("是\n"): printf("否\n");
	}
	return 0;
}

这里用到了三目操作符,形式:(x > y) ? x : y

  1. 判断素数
void is_prime(int n)
{
	int i,flag = 1;
	for (i = 2; i <= sqrt(n); i++)
	{
		if (n % i == 0)
		{
			flag = 0;
			break;
		}
	}
	if (flag == 1)
	{
		printf("%d ", n);
	}
}


int main()
{
	int n = 100;
	for (n = 100; n <= 200; n++)
	{
		is_prime(n);
	}
	return 0;
}

二、函数参数的调用

(一)实参

实参(真实传递给函数的参数)类型:常量、变量、表达式、函数,必须要有确定的值,必须和函数定义时的参数类型一致

(二)形参

形参在函数调用时才会分配内存单一,出函数就会被销毁,形参和实参占有不同内存块,对形参的修改不会影响实参

(三)函数调用

  1. 传值调用(对实参的值进行拷贝,函数调用时,才被分配内存单元)。
  2. 传址调用(内存地址传递给函数参数)

(四)嵌套调用和链式访问

  1. 嵌套调用:在函数内部调用另一个函数,注意不能嵌套定义,即不能在函数内部定义另一个函数
void compare(int a, int b)
{
	int n = (a > b) ? a : b;
	printf("%d", n);
}

int main()
{
	int a, b = 0;
	scanf("%d %d", &a, &b);
	compare(a, b);
	return 0;
}

在compare这个函数中,调用了printf()函数,这个就是嵌套调用。

  1. 链式访问:把一个函数的返回值作为另一个函数的参数
int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

printf()函数先打印数字,返回值为打印数字的个数,最后结果是4321。

三、函数的声明和定义

(一)分文件书写

  1. 函数的声明:告诉编译器函数名称,参数类型,返回类型
  2. 函数的定义:定义函数具体的使用内容
  3. 函数先声明后使用
  4. 一般采用分文件的书写形式,主要为了协作和代码保护,例子如下:

头文件即声明文件(.h)

#pragma once
void print_int(int n);

函数实现文件(.c)

#include <stdio.h>
#define _CRT_SECURE_NO_WARNINGS 1

void print_int(int n)
{
	if (n > 9)
		print_int(n / 10);
	printf("%d ", n % 10);
}

主函数所在文件(.c),注意要包含声明.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "print_int.h"

int main()
{
	print_int(234);
	return 0;
}

在这里插入图片描述

(二)静态库函数调用

为了实现对代码的保护,将解决方案生成改为静态库,静态库可以隐藏代码内容

  1. 点击解决方案属性,将配置类型改为静态库
    在这里插入图片描述
  2. 将生成的**静态库(.lib)和声明文件(.h)**复制到新的项目中(类似出售所写的函数)。
    在这里插入图片描述
  3. 在新项目中创建主函数(.c),包含静态库#pragma comment(lib,"test_20210715.lib") ,即可调用隐藏代码的函数。
#include <stdio.h>
#pragma comment(lib,"test_20210715.lib") 

int main()
{
	print_int(234);
	return 0;
}

三、函数递归

(一)什么是递归

函数在定义中有直接或间接调用自身,将比较复杂的问题转化为较小的问题
由于函数调用需要创建空间,函数递归较深,容易导致溢出

(二)递归条件

  1. 存在限制,当满足条件,函数不再递归
  2. 每次递归越来越接近这个限制

(三)经典代码

  1. 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和。
    例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
    输入:1729,输出:19
int sum(int n)
{
	if (n <= 9)
		return n;
	else
		return n % 10 + sum(n / 10);
}

int main()
{
	int num = 0;
	scanf("%d", &num);
	printf("%d", sum(num));
	return 0;
}
  1. 递归和非递归分别实现strlen。
size_t strlen(char* arr)
{
	if (*(arr + 1) == '\0')
		return 1;
	else
		return 1 + strlen(arr + 1);
}

int strlen2(char* arr)
{
	int i = 1;
	while (*(arr + 1) != '\0')
	{
		i++;
		arr = arr + 1;
	}
	return i;
}

int main()
{
	char arr[] = "abcdefgh";
	printf("%zd\n", strlen(arr));
	printf("%d", strlen2(arr));
	return 0;
}
  1. 递归和非递归分别实现求n的阶乘(不考虑溢出的问题)。
int fac(int n)
{
	if (n == 1)
		return 1;
	else
		return n * fac(n - 1);
}

int fac2(int n)
{
	int count = 1;
	for (int i = 2; i <= n; i++)
	{
		count = count * i;
	}
	return count;
}

int main()
{
	printf("%d\n", fac(3));
	printf("%d", fac2(3));
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值