【C语言】 函数

2023-11-20

函数

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

C语言中函数的分类

  1. 库函数
  2. 自定义函数

C语言早期没有库函数

如果每个人都定义一个printf,那么

1.代码冗余

2.开发效率低

3.不标准

所以厂商就把常用的一些功能实现成函数,集成为库,由C语言直接提供。

C语言标准就可以规定库函数的标准

int strlen(const char* str);

功能:求str 指向的字符串的长度。

所有的编译器都遵循此规则。

Cplusplus

可以在上面这个网站找到所有库函数。

  • IO函数
    字符串操作函数
    字符操作函数
    内存操作函数
    时间/日期函数
    数学函数
    其他库函数

如何使用文档?

在这里插入图片描述

#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[] = "abcdef";
	char arr2[20] = "XXXXXXXXXXXXXX";
//能把arr1中的abcdef拷贝到arr2;
	strcpy(arr2,arr1);
	printf("%s",arr2);
	return 0;
}

在这里插入图片描述

//  memory set
//内存设置
//size_t  -> unsigned int
#include<stdio.h>
#include<string.h>

int main()
{
	char arr[] = "hello sfy";
	//设置内存的时候是以字节为单位的
	//每个字节的内容都是一样的
	memset(arr,'x',5);
	printf("%s",arr);
	return 0;
}

自定义函数

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

但是不一样的是这些都是我们自己来设计。

在这里插入图片描述

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

int Max(int a,int b)
{
	return (a>b)?(a):(b));
}

写一个函数可以交换两个整形变量的内容。
在这里插入图片描述

x y 的修改不影响 ab

当实参传给形参时,形参是实参的一份临时拷贝,对形参的修改不会影响实参。

在这里插入图片描述

正确版本:

// *(&a) == a
void Swap(int *a,int *b)
{
	int tmp = 0;
	tmp = *a;
	*a = *b;
	*b = tmp;
}
//改int传int的地址,int*接收,解引用修改

这两张图很重要

在这里插入图片描述在这里插入图片描述

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

传值调用
函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。

传址调用
传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操
作函数外部的变量。

练习:

  1. 写一个函数可以判断一个数是不是素数。
int is_prime(int val)//返回1是素数,返回0表示不是素数
{
	int i = 0;
	if (val == 1)
	{
		return 0;
	}
	for (i = 2; i <= val - 1; ++i)
	{
		if (val % i == 0)
		{
			return 0;
		}
	}
	return 1;
}
int main()
{
	printf("%d",is_prime(3));

	return 0;
}

TDD 测试驱动开发

test driven development

先想函数怎么使用—-测试

测试场景想好之后,设计函数

写一个函数判断一年是不是闰年

int is_leap_year(int y)
{
	return (((y%4 ==0) &&(y%100!=0))||(y%400==0));
}

设计函数的时候,功能足够单一!

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

int binary_search(int arr[],int val,int sz)//找到了返回下标,找不到返回-1
{
	int begin = 0;
	int end = sz-1;
	int mid = left+(right-left)/2;
	int i =0;
	while(left<=right)
{
		if(arr[mid]>val)
		{
			right = mid-1;
		}
		else if(arr[mid]<val)
		{
			left = mid+1;
		}
		else
			return mid;
}
return -1;
}

数组在传参时,传的是首元素地址。

写一个函数,每调用一次这个函数,就会将 num 的值增加1。

int Plus(int *p)
{
	(*p)++;
}

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

#include <stdio.h>
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 = strlen("abc");
	printf("%d",len);
}
printf("%d", printf("%d", printf("%d", 43)));

4 3 2 1

函数的声明和定义

告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
声明决定不了。
2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
3. 函数的声明一般要放在头文件中的。

在这里插入图片描述

只有一个文件的时候,把函数定义放到调用前面

分文件书写

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以把文件编译成一个静态库
在这里插入图片描述

把.h 和 .lib文件给别人就可以使用这个函数 然后点生成解决方案

要放在当前文件目录里

引别人的头文件 直接添加现有项

在这里插入图片描述

lib使用
在这里插入图片描述

自己包的不是库里的头文件要用双引号 “ ”

函数递归

程序调用自身的编程技巧称为递归( recursion)
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的但规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的主要思考方式在于:把大事化小

递归

自己调自己,不过这个函数栈溢出了 Stack overflow

在这里插入图片描述

接受一个整型值(无符号),按照顺序打印它的每一位。
例如:
输入:1234,输出 1 2 3 4

在这里插入图片描述

在这里插入图片描述

每次调用函数在栈上开辟空间,消耗很大,栈溢出就是空间不够了,死递归的话。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

递归的必要条件

存在限制条件,当满足这个限制条件的时候,递归便不再继续。
每次递归调用之后越来越接近这个限制条件。

编写函数不允许创建临时变量,求字符串长度。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

int my_strlen(char* str)
{
	if (*str != '\0')
	{
		return 1+my_strlen(++str);
	}
	else
		return 0;
}

int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d", len);

	return 0;
}

return 0返回到上一次的调用

递归与迭代

求n的阶乘的一个递归的方法。

int fac(int n)
{
	if (n <= 1)
	{
		return 1;
	}
	else
		return n*fac(n - 1);
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = fac(n);
	printf("%d", ret);
	return 0;
}

迭代版本

int fac(int n)
{
	int i = 0;
	int ret = 1;
	for (i = 1; i <= n; i++)
	{
		ret *= i;
	}
	return ret;
}

斐波那契数列

1 1 2 3 5 8 13 21 34 55……

前两个数一加,变成第三个数。

在这里插入图片描述

int Fib(int n)
{
	if (n <= 2)
	{
		return 1;
	}
	else
	{
		return Fib(n - 1) + Fib(n - 2);
	}
}

在这里插入图片描述

递归太慢

用非递归算

让abc动,c=a+b,然后后移重复动作

在这里插入图片描述

int Fib(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;

	while (n>2)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}

汉诺塔问题

在这里插入图片描述

青蛙跳台阶
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C语言】 函数 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 创建链表而不将节点声明为指针

    我已经在谷歌和一些教科书上搜索了很长一段时间 我似乎无法理解为什么在构建链表时 节点需要是指针 例如 如果我有一个节点定义为 typedef struct Node int value struct Node next Node 为什么为了
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • keil提示找不到芯片库

    keil提示找不到芯片库 有几种可能 一种是没安装芯片软件包 下载相应芯片包即可 还有一种可能是工程本身是用keil4创建的 而你用的是keil5打开的 此种情况将后缀名uvproj改成uvprojx即可 图1
  • java获取method_从Method中获取完整类名和方法名

    需求假设 假设在包com zhoutao controller下有方法getKey 方法 在JavaEE中 通过AOP获得该方法的的对象method 现在通过该对象的getName方法 仅仅只能获得getKey的结果 现在我需要的是com
  • 性别年龄识别器

    心情 最近比较郁闷 自己的小论文已经投了快8个月了 从去年的AAAI CVPR 到现在在审的TCSVT AAAI由于页数超限被拒 CVPR因为一个正面和2个负面评价被拒 TCSVT还前途未卜 真的很郁闷 心情不好 论文也不太想看 撸撸代码放
  • Idea快速开发SpringBoot项目的方法

    一 常用插件 1 Free Mybatis plugins 针对Mybatis框架提供的插件 自动完成Mapper接口和Mapper xml之间的跳转 2 RestfulTool 自动显示工程中的所有URL接口 进行测试 并且提供检索功能
  • Elasticsearch(十三) ElasticSearch搜索附近的人

    需求 通过指定点搜索附近的人 要求可以过滤年龄 结果按照距离进行排序 并且展示她 他距离你多远 本文参考 es官网文档 https www elastic co guide cn elasticsearch guide current so
  • 面试题:StringBuilder 和 StringBuffer 区别(通俗易懂易背)

    StringBuffer是同步的 线程安全 StringBuilder不是 什么时候用哪一个 StringBuilder 当您需要一个可以修改的字符串 并且只有一个线程正在访问和修改它时 StringBuffer 当你需要一个可以修改的字符
  • sql: Compare Tables

    使用 UNION INTERSECT 或 EXCEPT 运算符合并的所有查询必须在其目标列表中有相同数目的表达式 select from BookInfoList 存在不同的 select BookInfoID BookInfoBarCod
  • VMware安装OpenEuler

    VMware安装OpenEuler 需要考虑的因素 安装系统的用途 桌面开发 服务器 Linux学习使用 磁盘分区规划 最小120G 划分 boot swap 根分区等 网络 是否对外提供服务 NAT模式 桥接模式 仅主机模式 1 下载镜像
  • 前端大屏常用的适配方案

    假设我们正在开发一个可视化拖拽的搭建平台 可以拖拽生成工作台或可视化大屏 或者直接就是开发一个大屏 首先必须要考虑的一个问题就是页面如何适应屏幕 因为我们在搭建或开发时一般都会基于一个固定的宽高 但是实际的屏幕可能大小不一 接下来我们就尝试
  • 安卓10开机时间优化分析

    本文从以下六点分析开机时间 1 软件环境 2 开机时间测试方法 3 开机各阶段重要的时间节点 4 bootchart工具使用说明 5 Android开机时间日志信息 6 开机时间优化方案 一 软件环境 平台 android10 0 qcom
  • Stem教育是探究式的学习方式

    在国家政策的扶持下 STEM教育慢慢进入大众的视野 走近一部分大中小学生的课堂 教育部出台的 教育信息化 十三五 规划 中明确指出有效利用信息技术推进 众创空间 建设 探索STEM教育 创客教育等新教育模式 使学生具有较强的信息意识与创新意
  • virtualbox 3.0.8 下载

    http download virtualbox org virtualbox 3 0 8
  • java命令执行jar包main方法指定相关依赖

    1 准备好工程执行所需的所有依赖jar包 也可以使用maven导出依赖的方法导出 2 将工程打包 此处打成jar包 如上图所示 zookeeper learn 1 0 SNAPSHOT jar 本次需要jdk java命令执行的jar包 3
  • #互联网生活中的隐私保护:用隐私换便利还是花钱护隐私?# 隐私保护与个人信息安全:在便利与隐私之间的取舍

    文章目录 1 看法 2 互联网生存指南 通过哪些方法来加强个人信息保护 2 1 加强个人信息安全意识 2 2 使用强密码和多因素认证 2 3 更新操作系统和软件 2 4 谨慎使用公共Wi Fi网络 2 5 定期备份个人数据 2 6 注意社交
  • Qt之自定义布局管理器(QBorderLayout)

    简述 QBorderLayout 顾名思义 边框布局 实现了排列子控件包围中央区域的布局 具体实现要求不再赘述 请参考前几节内容 简述 实现效果源码 使用 实现 QBorderLayout主要采用QLayout和QWidgetItem实现
  • MySQL 代替in/not in 的sql语句

    1 in和exists in是把外表和内表作hash连接 而exists是对外表作loop循环 每次loop循环再对内表进行查询 一直以来认为exists比in效率高的说法是不准确的 如果查询的两个表大小相当 那么用in和exists差别不
  • Textbooks Are All You Need

    本文是LLM系列文章 针对 Textbooks Are All You Need 的翻译 课本是你全部所需要的 摘要 1 引言 2 训练细节和高质量数据的重要性 3 对CodeExercise进行微调后的模型能力峰值 4 LLM评分对非常规
  • 【Python高级之定时器】

    Python高级之定时器 定时器 定时器 如果需要使用定时器去触发一些事件 Python中通过线程实现定时器timer 定时器的意思也是 一段时间后调用一个函数 用法 import threading def fun timer print
  • …\OBJ\LED.axf: Error: L6218E: Undefined symbol EXTI_Init (referred from exti.o). 错误修改

    OBJ LED axf Error L6218E Undefined symbol EXTI Init referred from exti o 错误修改 今天在移植野火的程序到元子的开发平台上时候 发现自己在中断初话中断函数的时候出现了
  • 【C语言】 函数

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