【C语言】函数讲解(上)

news2024/12/25 0:12:20

【C语言】函数讲解(上)

  • 1.函数是什么
  • 2.C语言中函数的分类
    • 2.1库函数
      • 2.1.1如何学会使用库函数
    • 2.2.自定义函数
  • 3.函数的参数
    • 3.1实际参数(实参)
    • 3.2形式参数(形参)
  • 4.函数调用
    • 4.1传值调用
    • 4.2传址调用
    • 4.3练习

所属专栏:C语言
博主首页:初阳785
代码托管:chuyang785
感谢大家的支持,您的点赞和关注是对我最大的支持!!!
博主也会更加的努力,创作出更优质的博文!!
关注我,关注我,关注我,重要的事情说三遍!!!!!!!!

1.函数是什么

数学中我们常见到函数的概念。但是你了解C语言中的函数吗?
维基百科中对函数的定义:子程序

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

2.C语言中函数的分类

C语言中把常用的功能,进行了封装,分装成一个个函数,提供出来大家一起使用。
比如我们常写的打印函数printf,输入函数scanf,等等。

注:C语言并不是直接实现库函数的,而是提供了C语言的标准和库函数的约定。
库函数的实现一般是由编译器去实现的。

2.1库函数

为什么会有库函数?

  1. 我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格式打印到屏幕上(printf)。
  2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)。
  3. 在编程是我们也计算,总是会计算n的k次方这样的运算(pow)。
    像上面我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。

也就是说我们把频繁使用的功能代码块分装成一个个的可供大家简单的使用的一个功能,这个功能就是我们的库函数,而我们又把这写功能函数一起分装在我们头文件中,所以一但我们想要使用这个功能函数的时候,就只需要引入头文件就行了。
这就是为什么什么我们每次写代码的时候都需要包含头文件的原因。

注:
但是库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件
这里对照文档来学习上面几个库函数,目的是掌握库函数的使用方法。

2.1.1如何学会使用库函数

为了让大家能够更好的使用库函数以及学习到更多的函数,这里提供一个搜索各种C原因的库函数

  1. 链接: https://cplusplus.com/
    在这里插入图片描述
    打开界面后点击画圈部分(这个是老版本的意思,因为新版本不支持搜索功能)
    在这里插入图片描述
    进入界面后就可以在里面进行搜索了。
  2. http://en.cppreference.com(英文版)
  3. http://zh.cppreference.com(中文版)

以上就是三个学习库函数的网站,大家要好好的学习噢。

2.2.自定义函数

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

所以更加重要的是自定义函数。
自定义函数和库函数一样,有函数名,返回值类型和函数参数。
但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。

函数的组成

ret_type fun_name(para1, * )
{
 	statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1    函数参数

我们来写一个函数试一试:

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
	if(x>y)
 		return x;
 	else if(y>x)
 		return y;
}
int main()
{
 	int num1 = 10;
 	int num2 = 20;
 	int max = get_max(num1, num2);
 	printf("max = %d\n", max);
 	return 0;
}

这里就设计了一个比较大小的函数。
有的同学就会问了,为什么我们不直接把这个比较函数写在我们的主函数里面,这样不是更方便面。但是我想要说的是,如果我们的比较式子不止一个,而是有100个1000个甚至使更多的话那我们不是写更多的代码吗?反而如果我们写函数的话我们只需要调用就行了,然后把参数改一下。
所以函数是用于处理一系列相同类型的表达式或者算法的。

你可以把函数形象成一个工厂,你把参数传过去就相当于个工厂提供原料,你提供不同的原料就可以得到不同的产品,我们的返回值就是我们把生产好的产品给提供会去。

3.函数的参数

3.1实际参数(实参)

真实传给函数的参数,叫实参。
实参可以是:常量、变量、表达式、函数等。
无论实参是何种类型的量,在进行函数调用时,
它们都必须有确定的值,以便把这些值传送给形参。

就像我们上面的比较大小的函数中**int max = get_max(num1, num2);**这里的num1和num2就是我们的实参。

3.2形式参数(形参)

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

上面的比较函数中==int get_max(int x, int y)==这里的x和y就是我们的形参。

现在如果我想要你使用一个函数交换两个变量的值,该这么做呢?
你可能会这么交换:

void swap(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}
int main()
{
	int m = 10;
	int n = 20;
	printf("m=%d,n=%d\n", m, n);
	swap(m, n);
	printf("交换后的值\n");
	printf("m=%d,n=%d", m, n);
	return 0;
}
}

代码结果:
在这里插入图片描述

你会发现他们并没有交换,这是为什么讷?
我们先看一下它们在内存发分布:
在这里插入图片描述
我们看到了虽然我们在执行到函数的内部的时候我们的x和y的值确实式交换了值,但是你会发现函数部分形参的地址与实参的地址是不同的,而我们之前也提过了变量的作用域的概念(进入生命周期创建,出了生命周期销毁)也就是所虽然我们在函数里面确实是交换了值,但是一旦出了函数x和y变量所在的内存空间就销毁了,而回到了main函数里面,但是销毁了x和y并没有影响到我们的m和n,所以他们的值并没有发生改变。

而正确的写法是传地址过去:

void swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}
int main()
{
	int m = 10;
	int n = 20;
	printf("m=%d,n=%d\n", m, n);
	swap(&m, &n);
	printf("交换后的值\n");
	printf("m=%d,n=%d", m, n);
	return 0;
}

代码展示:
在这里插入图片描述
这里传地址过去涉及到了指针的概念,这里我们先简单的讲一点指针的只是,到后面会有详细的指针讲解。

我们取出地址的是&(取地址符号),如果我们要定义一个指针,所谓指针同样也是一个变量叫做指针变量,既然是变量那么就有类型,指针的类型是指针变量用一个 * 号表示。
如果是int型那就是:int * m。如果是double型的那就是 double * m;
上述的m和n的类型是int型的,所以他们的指针变量的类型就是int ,所以形参的类型也是如此。
如果我们想要通过地址找到里面的址的话就要通过接应用操作来拿到里面的值
(接应用操作)

这是因为形参是实参是一份临时拷贝。
==对形参的修改不会影响实参。 ==

这里之所以需要传地址,是因为我们通过传地址,通过解引用操作直接通过地址找到这块地址所指向的的值。这样就可以改变了这块地址所指向的值了。

传地址你可以认为是我给一个工厂提供原料,工厂给我生产产品,工厂生产完产品是在我给他们送回的地址之后才开始做到,不然他们就算做好了产品也不知道要把这个产品送到哪里去。

4.函数调用

4.1传值调用

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

传值顾名思义就是将一个值传过去。
特点:形参是实参的一份临时拷贝,形参的改变不会影响实参。

4.2传址调用

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

传址顾名思义就是把地址传过去,这个时候解引用操作会改变实参。

4.3练习

  1. 写一个函数判断是否是素数:
#include <stdio.h>
#include <math.h>
int isPrime(int num)
{
	int i = 0;
	for (i = 2; i < sqrt(num); i++)
	{
		if (num % i == 0)
			return 0;
	}
	return 1;
}
int main()
{
	int i = 0;
	scanf("%d",&i);
	int ret=isPrime(i);
	if (ret == 1)
		printf("是素数\n");
	else
		printf("是素数\n");
	return 0;
}
  1. 写一个函数判断一年是否是润年:
#include <stdio.h>
int isLeap(int year)
{
	if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
		return 1;
	return 0;
}
int main()
{
	int year = 0;
	printf("请输入年份:>");
	scanf("%d", &year);
	int ret = isLeap(year);
	if (ret == 1)
		printf("是闰年\n");
	else
		printf("不是闰年\n");
	return 0;
}
  1. 写一个函数,实现一个整数有序数组的二分查找。
#include <stdio.h>
int binary_number(int arr[], int k, int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left <= right)
	{
		int mid = left + (right - left) / 2;
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else
		{
			return mid;
		}
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 8;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = binary_number(arr, k, sz);
	if (ret >= 0)
	{
		printf("下标是%d\n", ret);
	}
	else
	{
		printf("找不到\n");
	}
	return 0;
}

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

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

相关文章

Redis分布式锁实现方案

一、什么是分布式锁&#xff0c;与本地锁有什么区别 本地锁&#xff1a; 解决同一进程内多个线程操作同一资源的问题。 分布式锁&#xff1a; 解决多个进程同时操作同一资源的问题。 二、Redis的SETNX Redis之所以能实现分布式锁&#xff0c;得益于Redis的单线程处理模式&am…

Macbook(苹果电脑) VSCode 创建简单c++程序 配置C++开发环境

1.打开 Terminal 终端&#xff08;Command空格&#xff0c;输入Terminal&#xff09;。 1.1 输入如下指令&#xff0c;查看是否显示版本信息。 clang --version 1.2 如果出现版本信息&#xff0c;则跳过&#xff0c;否则输入 xcode-select --install 2. 为 VS Code 安装插件 …

docker中的四种网络模式

docker中的四种网络模式 实现原理四类网络模式host模式container模式none模式bridge模式 实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Con…

MySQL_第06章_多表查询

第06章_多表查询 讲师&#xff1a;尚硅谷 - 宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a; http://www.atguigu.com 多表查询&#xff0c;也称为关联查询&#xff0c;指两个或更多个表一起完成查询操作。 前提条件&#xff1a;这些一起查询的…

【Python】darts包(Python时序预测库的安装方法)+conda环境和库的建立

一、介绍 "darts"是一个Python编程语言中的数据处理和时间序列分析工具包。它提供了一系列用于处理、建模和分析时间序列数据的功能&#xff0c;包括时间序列的预处理、特征工程、模型训练和预测等。darts包含了许多常用的时间序列模型&#xff0c;如ARIMA、Prophet…

Linux权限 - 概念与管理 | 文件权限的修改与转让 【详解】

目录 Linux权限 Linux权限的概念 Linux权限的基础操作 (1).实现用户账号的切换 (2).仅提升当前指令的权限 Linux权限管理 1、文件访问者的分类&#xff08;人&#xff09; 2、文件类型和访问权限&#xff08;事物属性&#xff09; 3、文件权限值的表示方法 4、文件访…

数据结构与算法基础(王卓)(28):排序概述(分类)、直接插入排序思路

目录 排序分类&#xff1a;&#xff08;本章目录&#xff09; 按数据存储介质&#xff1a;&#xff08;学习内容&#xff09; 内部排序&#xff1a; 外部排序&#xff1a; 按比较器个数&#xff1a;&#xff08;学习内容&#xff09; 串行排序&#xff1a; 并行排序&…

arduino学习笔记2

一.蜂鸣器输出实验 1.源代码 int buzzer2;//设置控制蜂鸣器的数字口对应板子上2口 void setup() { pinMode(buzzer,OUTPUT);//设置对应的输出模式 } void loop() { unsigned char i,j;//定义变量while(1) { for(i0;i<50;i)//输出一个频率的声音{ digitalWrite(buzzer,H…

2023年4月的12篇AI论文推荐

GPT-4发布仅仅三周后&#xff0c;就已经随处可见了。本月的论文推荐除了GPT-4以外还包括、语言模型的应用、扩散模型、计算机视觉、视频生成、推荐系统和神经辐射场。 1、GPT-4 Technical Report Sbastien Bubeck, Varun Chandrasekaran, Ronen Eldan, Johannes Gehrke, Eric…

密码技术知识总结

密码技术知识总结 1. 密码技术简介 对称密码&#xff1a;加密和解密时使用同一密钥的方式公钥密码&#xff1a;加密和解密时使用不同密钥&#xff0c;也称非对称密码单向散列函数&#xff1a;保证数据的完整性&#xff0c;检测数据是否被篡改过 散列值&#xff1a;又称哈希值…

k8s 控制器---Statefulset

1. Statefulset 控制器 StatefulSet 是为了管理有状态服务的问题而设计的。 1.1 什么叫有状态服务&#xff1f; StatefulSet 是有状态的集合&#xff0c;管理有状态的服务&#xff0c;它所管理的 Pod 的名称不能随意变化。数据 持久化的目录也是不一样&#xff0c;每一个 Pod …

Unity --- UGUI --- Rect Transform(矩形变换) --- 锚点及其相关应用

1.所有的UI物体都没有Transform组件&#xff0c;取而代之的是Transform组件的派生 --- Rect Transform(矩形变换) 2.Rect Transform和Transform一样都有旋转和缩放&#xff0c;它两之间的区别是&#xff1a; Rect Transform多了&#xff1a;a.Pibot轴心点&#xff1b;b.Ancho…

002 学习鸿蒙应用开发ArkTs语言

目录 一.ArkTs语言介绍 1.ArkTs语言概述 2.ArkTs语言特性 二.基本UI描述 1.基本概念 2.UI描述规范 无参数构造配置 有参数构造配置 属性配置 事件配置 子组件配置 三.状态管理 1.基本概念 2.页面级状态管理 State Prop Link Observed和ObjectLink数据管理 P…

​从底层技术分析如何调教你的ChatGPT?

相信很多人都已经在使用类ChatGPT的工具进行工作或者娱乐了&#xff0c;这里说的类ChatGPT的是指和ChatGPT相同或者相似功能的产品&#xff0c;包括国外的开源平替模型、百度的文心一言等&#xff0c;但是你真的会使用这些工具和应用吗&#xff1f;你使用的方法是正确的吗&…

Java ---内部类

&#xff08;一&#xff09;定义 将一个类 A 定义在另一个类 B 里面&#xff0c;里面的那个类 A 就称为 内部类 &#xff08; InnerClass &#xff09; &#xff0c;类 B 则称为 外部类&#xff08; OuterClass &#xff09;。广泛意义上的内部类一般来说包括这四种&#xff1…

【中级软件设计师】—(针对上午题)软件工程上(三十五)

【中级软件设计师】—&#xff08;针对上午题&#xff09;软件工程&#xff08;三十五&#xff09; 一、CMM 1 2 3 4 5 二、能力成熟度模型集成&#xff08;CMMI&#xff09; 6 7 8 9 三、软件过程模型 &#xff08;一&#xff09;、瀑布模型 &#xff08;二&#xff09;、V模…

第八章 项目进度管理

项目进度有8个过程 1、规划项目&#xff0c;进度管理&#xff08;计划&#xff09; 2、定义活动&#xff08;活动清单&#xff09; 3、排序活动 4、估算活动资源&#xff08;估算人力&#xff09; 5、估算活动时间 6、制定进度计划表 7、控制进度 规划项目进度管理 为实施项目进…

薪资17K是一个怎样的水平?来看看98年测试工程师的面试全过程…

我的情况 大概介绍一下个人情况&#xff0c;男&#xff0c;本科&#xff0c;三年多测试工作经验&#xff0c;懂python&#xff0c;会写脚本&#xff0c;会selenium&#xff0c;会性能&#xff0c;然而到今天都没有收到一份offer&#xff01;从年后就开始准备简历&#xff0c;年…

电容的基本知识

1、电容是电路中重要的元件&#xff0c;种类多、用途广&#xff0c;主要有插件类和贴片类两种。 2、电容主要特性参数:标称容量、耐压、误差、温度 2.1电容容量常用单位有微法《uF)、纳法《nF)、皮法《pF) 单位换算:1uF10^3nF10"6pF《电容的基本单位用法拉…

完成近4亿元C轮融资+自研底盘域控,本土线控制动玩家“拼”了

显然&#xff0c;线控制动赛道已经进入白热化竞争阶段。 高工智能汽车研究院监测数据显示&#xff0c;2022年中国市场&#xff08;不含进出口&#xff09;乘用车前装搭载线控制动系统&#xff08;One-Box&#xff0c;Two-Box&#xff09;上险交付合计497.39万辆&#xff0c;同…