C语言函数章--该如何学习函数?阿斗看了都说会学习了

news2024/11/22 16:07:36

前言
👻作者龟龟不断向前
👻简介宁愿做一只不停跑的慢乌龟,也不想当一只三分钟热度的兔子。
👻专栏:C++初阶知识点

👻工具分享

  1. 刷题: 牛客网 leetcode
  2. 笔记软件:有道云笔记
  3. 画图软件:Xmind(思维导图) diagrams(流程图)

在这里插入图片描述

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主🙊,如有不足还请指点,博主及时改正

文章目录

    • 函数
      • 🚀1.函数的概念(维基百科)
      • 🚀2.函数的分类
      • 🚀库函数
        • 🍉库函数的分类总结
        • 🍉库函数的学习方法
        • 🍉关于文档使用的那五板斧
      • 🚀3.自定义函数
        • 🍉函数的组成
        • 🍉函数的参数
          • 🍇实际参数(实参)
          • 🍇形式参数
        • 🍉函数的调用--传址and传址(重要)
      • 🚀4.例题训练
        • 🍉写一个函数可以判断一个数是不是素数
        • 🍉写一个函数判断一年是不是闰年
        • 🍉 写一个函数,实现一个整形有序数组的二分查找
        • 🍉写一个函数,每调用一次这个函数,就会将 `num` 的值增加1。
        • 🍉设计一个函数打印9 9乘法表

函数

🚀1.函数的概念(维基百科)

函数–子程序

  • 在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组 成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性

  • 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

 

 

🚀2.函数的分类

  • 库函数–库里面帮我们写好的函数,我们可以直接使用
  • 自定义函数–自己写的函数

当然啦,自定义函数是有他存在的价值的,因为库函数无法满足我们生活中的所有需求和想法

那些库函数没有的一些功能,就要靠我们程序员自己用自定义函数来实现了

 

 

🚀库函数

  虽然你可能不理解库函数,但你却时时在使用库函数,例如我们刚开始学习C语言时,向世界打招呼使用的printf
它可以实现将数据打印在屏幕上的功能,实质上它就是个库函数!包括scanf ,sqrt,time等,都是库里面提供的函数。
而且就算我们不知道他的原理,我们也可以直接使用。

 

 包含头文件的方式#include<头文件>

 

🍉库函数的分类总结

  主要的库函数可以分为以下基类

  • IO函数 –printf,scanf……
  • 字符串操作函数 –strlen,strcpy……
  • 字符操作函数 –getchar,putcchar
  • 内存操作函数 –malloc
  • 时间/日期函数 –time
  • 数学函数 –sqrt,sin,cos
  • 其他库函数

 

🍉库函数的学习方法

最不现实的方法就是:死记硬背。

最实用的方法就是:查文档

 

这里给大家推荐一个我用的最多C语言库网站:cplusplus.com - The C++ Resources Network

文档是英文版,大家可以结合浏览器翻译去使用

 

下面我们就来使用这个文档来学习一下strcpy怎么使用

 

 

🍉关于文档使用的那五板斧

1.搜索库函数

在这里插入图片描述

 

2.语法,作用介绍

在这里插入图片描述

解释

strcpy—拷贝source指向的C字符串,至destination所指向的C字符串当中,包含\0也会拷贝进去

 

3.函数参数的介绍

在这里插入图片描述

解释

source–需要被拷贝的字符串

destination–需要拷贝至其中的字符串

 

4.返回值的介绍

在这里插入图片描述

 

5.代码用例

在这里插入图片描述

 

这五板斧在文档中介绍的很清楚,而且该网站也很简洁,十分推荐

大家也可以使用上述的步骤,来查一查strcat这个函数怎么用–五板斧

 

 


 

🚀3.自定义函数

  如果库函数能干所有的事情,那还要程序员干什么?

所有更加重要的是自定义函数。 自定义函数和库函数一样,有函数名返回值类型函数参数

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

 

🍉函数的组成

ret_type fun_name(para1, * )
{
 statement;//语句项
}

ret_type 返回类型
fun_name 函数名
para1    函数参数

 

举例–求两个数的最大值

#include<stdio.h>

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;
}

 

解释

在这里插入图片描述

 

 


🍉函数的参数

函数的参数分为:

  1. 实际参数(简称实参)
  2. 形式参数(简称形参)

 

🍇实际参数(实参)

真实传给函数的参数,叫实参。

实参可以是:常量、变量、表达式、函数等。 无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。例如上述的实参num1,num2,并且我们也可以将num1+num2这个表达式作为实参

 

🍇形式参数

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

 

例题–写一个函数实现交换功能

示例1:

#include<stdio.h>

void Swap1(int x,int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 3, b = 5;
    
	printf("交换前\n");
	printf("a = %d b = %d\n", a, b);
	printf("\n");

	Swap1(a, b);
	printf("Swap1交换后\n");
	printf("a = %d b = %d\n", a, b);
	printf("\n");

	return 0;
}

  我们的交换函数就写完了,但是程序输出结果不尽人意–没有达到我们的需求

在这里插入图片描述

解决方法如示例2

 

 

示例2

#include<stdio.h>

void Swap2(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

int main()
{
	int a = 3, b = 5;
	printf("交换前\n");
	printf("a = %d b = %d\n", a, b);
	printf("\n");

	Swap2(&a, &b);
	printf("Swap2交换后\n");
	printf("a = %d b = %d\n", a, b);
	return 0;
}

 

 

解释如下

🍉函数的调用–传址and传址(重要)

示例1属于传值调用

在这里插入图片描述

大家看图即可发现:实参a,b与形参x,y虽然内容相同,但是地址不同,本质上没有建立任何联系

传值调用中,形参只是实参的一份临时拷贝,对形参的改变不影响实参

 

 

示例2属于传址调用

在这里插入图片描述

观察图即可发现:a,b与形参x,y地址不同,但是形参x,y的内容是a,b的地址,他们之间建立的联系

这个时候我们对x,y进行解引用操作,即可找到a,b,然后再进行修改即可达到目的


总结

  1. 设计函数时不需要修改外部变量的值,可以使用传值调用。例如Add函数,Max函数
  2. 若一个函数需要外部变量的值,可以使用传址调用,例如Swap函数

 

 

 

🚀4.例题训练

  1. 写一个函数可以判断一个数是不是素数。
  2. 写一个函数判断一年是不是闰年。
  3. 写一个函数,实现一个整形有序数组的二分查找。
  4. 写一个函数,每调用一次这个函数,就会将 num 的值增加1。
  5. 设计一个函数打印9 9乘法表

 

🍉写一个函数可以判断一个数是不是素数

我们讲过判断一个数是否为素数可以使用试除法,即若2~num的平方根 的数都无法将num整除,那么num就是素数

如果我们要设计一个函数来实现该功能的话,可以如下操作

#include<stdbool.h>//布尔类型的头文件
#include<stdio.h>

bool IsPrime(int n)
{
	for (int i = 2; i <= sqrt(n); ++i)
	{
		if (n%i == 0)
		{
			return false;//如果能被i整除说明不是素数,直接返回false
		}
	}
	return true;//上面已经处理了不是素数的情况,那么剩下就是素数的情况了
}

int main()
{
	for (int i = 101; i < 200; i += 2)
	{
		if (IsPrime(i))
		{
			printf("%d ",i);
		}
	}
	printf("\n");
	return 0;
}

解释

  1. bool类型是布尔类型,布尔类型的值只能是真true(1)或者假false(0)

    而我们函数的思想是如果是素数返回真,如果不是素数返回假,所以返回类型用布尔类型刚刚好

  2. IsPrime(i)这个整体的值—i为素数为真(1),i不为素数为假(0),所以我们可以直接将这个表达式放在条件判断中

 

 

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

我们之前也讲过判断闰年的方法

  1. 如果一年能被4整除,但是无法被100整除,那么是该年闰年
  2. 如果一年能被400整除,那么概念是闰年

实现思路:如果是闰年返回真(true),不是闰年返回假(false)

#include<stdio.h>
#include<stdbool.h>

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

int main()
{
	for (int year = 1000; year <= 2000; year += 4)
	{
		if (IsLeapYear(year))
		{
			printf("%d ", year);
		}
	}
	return 0;
}

解释

由于((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0))的表达式的值刚好也只有真和假,也刚好符合我们的需求,所以可以直接作为返回值

 

 

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

回顾二分查找逻辑:“猜数字”,一个有序数组我们每次猜中间的数字,都可以排除一半的错误数据

函数要求:

  1. 如果找到了,返回该元素的下标
  2. 如果没有找到,返回0

不知道有同学入坑了没?

大家千万注意,如果没找到返回0,那么该函数实现的逻辑是错误的,因为如果要找的元素是第一个元素他的下标也是0

所以,咱们设计成没有找到指定元素,返回EOF(-1)

#include<stdio.h>

int BinSearch(int* arr,int n,int k)//找到了返回该元素下标,没找到返回零
{
	int left = 0;
	int right = n - 1;//n--数组元素个数
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			return mid;//是在这里找到的
		}
	}
	return EOF;
}


int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int sz = sizeof(arr)/sizeof(arr[0]);
	int k = 8;
	int ret = BinSearch(arr, sz, k);

	if (ret != EOF)
	{
		printf("找到了,下标为%d\n", ret);
	}
	else
	{
		printf("没找到");
	}
	return 0;
}

解释

数组的空间大小 = 元素的空间大小 * 元素个数

所以元素个数 = 数组的空间大小/元素的空间大小,这样我们就可以将元素个数直接算出来了

 

 

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

即需要在函数中修改num的值,咱们可以使用传址调用

void Func(int* n)
{
	//.......--其他操作
	++(*n);
}

int main()
{
	int num = 0;
	//调用函数,使得num每次增加1
	Func(&num);
	printf("%d\n", num);
	Func(&num);
	printf("%d\n", num);
	Func(&num);
	printf("%d\n", num);
	Func(&num);
	Func(&num);
	Func(&num);
	printf("%d\n", num);
	Func(&num);
	Func(&num);
	Func(&num);
	printf("%d\n", num);
	return 0;
}

该函数跟前面三个函数不一样,不需要返回值哟

 

 

🍉设计一个函数打印9 9乘法表

当然了我相信大部分同学都会打印九九乘法表,重点是:

  1. 你打印出来的格式是否美观
  2. 不仅仅只是打印九九乘法表,自己输入乘法表的行数
#include<stdio.h>

void MulTable(n)
{
	//n行
	for (int i = 1; i <= n; ++i)
	{
		//i列
		for (int j = 1; j <= i; ++j)
		{
			printf("%2d*%-2d=%-4d", j, i, i*j);
		}
		printf("\n");
	}
}

int main()
{
	int line = 0;
	scanf("%d", &line);
	MulTable(line);
	return 0;
}

在这里插入图片描述

解释

博主使用的是

  1. 第一个操作数是两个宽度,采取右对齐
  2. 第二个操作数是两个宽度,采取左对齐
  3. 第三个操作数是四个宽度,采取左对齐

而且这个函数只实现打印功能,所以没有返回值

 

文章就讲到这,咱们下期见!🐱‍👓

点赞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2541.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Python入门指北】 发邮件与正则表达式

文章目录邮件发送一、群发邮件二、指定用户发邮件正则表达式一、预备知识正则1. 正则介绍2. 陷阱3. 特殊的字符二、 re 模块的方法1 常用方法2. 正则分组总结邮件发送 #第三方模块 yagmail #pip3 install yagmailimport yagmail""" 项目需求 yag yagmail.SMTP(u…

MyBatis Plus实现动态字段排序

利用周末时间&#xff0c;对已有的项目进行了升级&#xff0c;原来使用的是tkmybatis&#xff0c;改为mybatis plus。但是由于修改了返回数据的格式&#xff0c;前端页面字段排序失效了&#xff0c;需要刷新表格才会排序。页面效果如下 easyui的数据表格datagrid支持多字段排序…

【仿牛客网笔记】Spring Boot实践,开发社区登录模块-账号设置,检查登录

首先访问账号设置的页面。 新建一个Controller,用过RequestMapping生成访问路径 上传头像 首先打开配置文件&#xff0c;配置一下将文件配置到哪里。 直接在Controller存了&#xff0c; 更新的时候掉Map&#xff0c;参数为id和路径。 注入日志对象后&#xff0c;通过Val…

SpringBoot项目启动执行任务的几种方式

经过整理后得到以下几种常用方式&#xff0c;供大家参考。 1. 使用过滤器 init() &#xff1a;该方法在tomcat容器启动初始化过滤器时被调用&#xff0c;它在 Filter 的整个生命周期只会被调用一次。可以在这个方法中补充想要执行的内容。 Component public class MyFilter …

CTF竞赛网络安全大赛(网鼎杯 )Web|sql注入java反序列化

CTF竞赛网络安全大赛题目考点 sql注入 java反序列化 网鼎杯解题思路 题目一打开是这样的界面 下载题目的附件,并用jd-gui.exe打开 核心代码如下 Test代码 `` package 部分class;import cn.abc.common.bean.ResponseCode; import cn.abc.common.bean.ResponseResult; impor…

持续交付中流水线构建完成后就大功告成了吗?别忘了质量保障

上期文章我结合自己的实践经验&#xff0c;介绍了持续交付中流水线模式的软件构建&#xff0c;以及在构建过程中的3个关键问题。我们可以看出&#xff0c;流水线的软件构建过程相对精简、独立&#xff0c;只做编译 和打包两个动作。 但需要明确的是&#xff0c;在持续交付过程…

网课查题接口使用方法

网课查题接口使用方法 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 查题校园题库&#xff1a;查题校园题库后台&#xff08;点…

Hadoop面试题汇总-20221031

Hadoop面试题汇总 HDFS部分 1、请描述HDFS的写流程。 答&#xff1a; 首先由客户端向 NameNode 发起文件上传请求&#xff0c;NameNode 检查文件要上传的目录&#xff0c;并鉴权。如果上传用户对此目录有权限&#xff0c;则允许客户端进行上传操作。客户端接收到允许指令后&…

本科毕业论文内容必须有国内外文献综述吗?

不知不觉间整个暑假变过去了&#xff0c;现在大部分的大学生都已经开学了。2023届毕业的学生现在也开始借鉴毕业论文的选题工作。但是无论是现在正在选题的大四的同学们还是还在上大一大&#xff0c;二大三的同学们都对毕业论文这4个字有着天生的恐惧感。因为对于大多数人来说&…

阿里为何禁止在对象中使用基本数据类型

大家好&#xff0c;我是一航&#xff01; 前两天&#xff0c;因为一个接口的参数问题&#xff0c;和一位前端工程师产生了一些分歧&#xff0c;需求很简单&#xff1a; 根据一个数值类型&#xff08;type 取值范围1&#xff0c;2&#xff0c;3&#xff09;来查询数据&#xff…

HTML+CSS+JavaScript七夕情人节表白网页【樱花雨3D相册】超好看

这是程序员表白系列中的100款网站表白之一&#xff0c;旨在让任何人都能使用并创建自己的表白网站给心爱的人看。 此波共有100个表白网站&#xff0c;可以任意修改和使用&#xff0c;很多人会希望向心爱的男孩女孩告白&#xff0c;生性腼腆的人即使那个TA站在眼前都不敢向前表白…

pandas 基本数据

目录 1. pandas 简介 2. pandas 基本数据结构 2.1 Series 类型 2.1.1 索引-数据的行标签 2.1.2 值 2.1.3 切片 2.1.4 索引赋值 2.2 DataFrame 类型 1. pandas 简介 一般导入的形式&#xff1a;import pandas as pd 2. pandas 基本数据结构 python 的数据结构&#xff1a…

python爬虫之Scrapy框架,基本介绍使用以及用框架下载图片案例

一、Scrapy框架简介 Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据&#xff0c;只需要实现少量的代码&#xff0c;就能够快速的抓取。 Scrapy使用了Twisted异步网络框架来处理网络通信&#xf…

Servlet篇 —— 我的第一个Servlet程序

☕导航小助手☕ &#x1f35a;写在前面 &#x1f35c;一、Maven的介绍 &#x1f371;​二、第一个Servlet的创建 &#x1f354;&#x1f354;2.1 创建项目 &#x1f969;&#x1f969;​2.2 引入依赖 &#x1f9aa;&#x1f9aa;​2.3 创建目录 &#x1f363;&#x1f363;2.4…

没想到GoFrame的gcache天然支持缓存淘汰策略

gcache提供统一的缓存管理模块&#xff0c;提供了开发者可自定义灵活接入的缓存适配接口&#xff0c;并默认提供了高速内存缓存适配实现。 先说结论 这篇文章通过结合商业项目的使用场景&#xff0c;为大家介绍了gcache的基本使用、缓存控制以及淘汰策略。 使用gcache做缓存处…

3分钟,快速上手Postman接口测试

Postman是一个用于调试HTTP请求的工具&#xff0c;它提供了友好的界面帮助分析、构造HTTP请求&#xff0c;并分析响应数据。实际工作中&#xff0c;开发和测试基本上都有使用Postman来进行接口调试工作。有一些其他流程的工具&#xff0c;也是模仿的Postman的风格进行接口测试工…

推荐 4 个开源工具

Hi&#xff0c;艾瑞巴蒂&#xff0c;晚上好&#xff01;今天推荐 4 个登上 GitHub 热搜的开源项目&#xff0c;它们分别是&#xff1a;1. 炫酷的 UI 工具&#xff1a;glslViewer2. Textual3. ToolJet&#xff1a;开源的低代码开发框架4. Linux 命令大全搜索工具01炫酷的 UI 工…

程序人生:去了字节跳动,才知道年薪40W的测试有这么多?

今年大环境不好&#xff0c;内卷的厉害&#xff0c;薪资待遇好的工作机会更是难得。最近脉脉职言区有一条讨论火了&#xff1a; 哪家互联网公司薪资最‘厉害’&#xff1f; 下面的评论多为字节跳动&#xff0c;还炸出了很多年薪40W的测试工程师 我只想问一句&#xff0c;现在的…

vue3项目的创建,vite+vue3+ts(3)- router

vue3 有三种写法&#xff1a; 1.compostion API &#xff1a; 还是按照vue2.0写法 2.组合式API: 3. 组合式API 语法糖&#xff08;setup), 语法简洁&#xff08;推荐使用这个&#xff09; 写法&#xff1a; 4. 在.eslintrc.cjs 或者 .eslintrc.js中配置代码&#xff0c;是这个…

聊聊计算机中的寄存器

文章目录前言数据寄存器(DR)地址寄存器(AR)程序状态寄存器(PSW)累加寄存器(AC)乘商寄存器(MQ)程序计数器(PC)指令寄存器(IR)MAR、MDR小结作者&#xff1a;小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功、JAVA底层、面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 前…