04.函数

news2024/11/28 15:46:58

一、 函数

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

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

二、C语言中函数的分类:

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

1.库函数

//标准库-提供C语言的库函数

C语言常用的库函数都有:
IO函数--input output scanf printf getchar putchar
字符串操作函数--strlen strcmp
字符操作函数--memcpy memove memset
内存操作函数--time
时间/日期函数--time
数学函数--pow sqrt
其他库函数

注: 但是库函数必须知道的一个秘密就是:

使用库函数,必须包含 #include 对应的头文件。 

cppreference.com (中文版)

//strcpy(arr1,arr2)//把arr2的字符拷贝到arr1 

//返回的是地址

#define _CRT_SECURE_NO_WARNINGS 1

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

int main()
{
	//字符串拷贝的时候
	//hello bit
	char arr1[20] = { 0 };
	char arr2[] = "hello bit";

	//把arr2中的字符串拷贝到arr1中
	char* ret = strcpy(arr1, arr2);
	printf("%p\n", ret);
	printf("%s\n", ret);//通过地址也可以打印字符串
	return 0;
}

2.自定义函数

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

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

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

#include <stdio.h>
//get_max函数的设计
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;
}

2.写一个函数可以交换两个整形变量的内容。

#include <stdio.h>
//实现成函数,但是不能完成任务
void Swap1(int x, int y)
{
 int tmp = 0;
 tmp = x;
 x = y;
 y = tmp;
}
//正确的版本
void Swap2(int *px, int *py)
{
 int tmp = 0;
 tmp = *px;
 *px = *py;
 *py = tmp;
}
int main()
{
 int num1 = 1;
 int num2 = 2;
 Swap1(num1, num2);
 printf("Swap1::num1 = %d num2 = %d\n", num1, num2);
 Swap2(&num1, &num2);
 printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
 return 0;
}

三、函数的参数

1.实际参数(实参):


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

2.形式参数(形参): 

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

上面 Swap1 和 Swap2 函数中的参数 x,y,px,py 都是形式参数。在main函数中传给 Swap1 的 num1 ,num2 和传 给 Swap2 函数的 &num1 ,&num2 是实际参数。

//当函数调用的时候,实参传递给形参,这时候形参是实参的一部份

//临时拷贝,对形参的修改并不影响实参

//只要不改变值,不交换,就可以从形式参数直接传递到实参

//可以通过地址建联系

EG:交换两个数

1.直接交换

//写一个函数可以交换两个整形变量的内容。

int main()
{
	int a = 0;
	int b = 0;
	//输入
	scanf("%d %d", &a, &b);
	//交换
	printf("交换前:a=%d b=%d\n", a, b);

	int tmp = 0;//第三个变量

	tmp = a;
	a = b;
	b = tmp;

	//输出
	printf("交换后:a=%d b=%d\n", a, b);

	return 0;
}

 2.通过定义函数

1)错误方法

//当函数调用的时候,实参传递给形参,这时形参是实参的一份
//临时拷贝,对形参的修改不影响实参。
void Swap(int x, int y)
{
	int tmp = x;
	x = y;
	y = tmp;
}

int main()
{
	int a = 0;
	int b = 0;
	//输入
	scanf("%d %d", &a, &b);//3 5 
	//交换
	printf("交换前:a=%d b=%d\n", a, b);
	Swap(a, b);
	//输出
	printf("交换后:a=%d b=%d\n", a, b);

	return 0;
}

 2)正确方法,通过地址建立联系

void Swap2(int* pa, int* pb)
{
	int tmp = *pa;//tmp = a;
	*pa = *pb;    //a=b
	*pb = tmp;    //b=tmp
}

int main()
{
	int a = 0;
	int b = 0;
	//输入
	scanf("%d %d", &a, &b);//3 5 
	//交换
	printf("交换前:a=%d b=%d\n", a, b);
	Swap2(&a, &b);
	//输出
	printf("交换后:a=%d b=%d\n", a, b);

	return 0;
}

//地址无法进行交换,交换的为地址所对应的数据

//函数可以作为实参 

//自定义函数名一定要有意义

//函数内部不可以定义函数

//函数的访问是链式访问--printf("%d\n",strlen("abcdef"))--先进行strlen,后进行printf

EG:

int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

 

 四、函数的调用

1.传值调用

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

2.传址调用

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

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

函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的。


1.嵌套调用

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

函数可以嵌套调用,但是不能嵌套定义。 

2.链式访问

把一个函数的返回值作为另外一个函数的参数。

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "hello";
 int ret = strlen(strcat(arr,"bit"));//这里介绍一下strlen函数
 printf("%d\n", ret);
 return 0;
}
#include <stdio.h>
int main()
{
    printf("%d", printf("%d", printf("%d", 43)));
    //结果是啥?
    //注:printf函数的返回值是打印在屏幕上字符的个数
    return 0;
}

//函数的访问是链式访问--printf("%d\n",strlen("abcdef"))--先进行strlen,后进行printf

EG:

int main()
{
	printf("%d", printf("%d", printf("%d", 43)));
	return 0;
}

 

六、函数的声明和定义

1.函数声明:

1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数 声明决定不了。

2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。

3. 函数的声明一般要放在头文件中的。

//头文件.h要放函数的声明 

//.c函数的实现

test.c 

add.c

add.h

电脑可以自动把三个文件整合起来

//int a;//变量的声明

//int Add(int x,int y)&int Add(int,int)二者的声明格式都可以

//int a=0;//变量的定义 

//全局变量不初始化的时候,默认是0

//函数的声明都放在头文件中.h

//函数的定义都放在源文件中.c 

七、函数递归 

//函数内自己调用自己

//栈溢出,把栈耗干了

//递归:

//递-递推

//归-回归

1.递归的定义

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

2.递归的两个必要条件

//上到下递推

//下到上回归

存在限制条件,当满足这个限制条件的时候,递归便不再继续。

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

//每一次函数调用都会为本次喊出调用分配的内存空间(是在内存的栈区)

//在本次函数调用分配的内存空间叫做被称为这次函数调用的栈帧空间 

//递归容易栈溢出,这时把递归的算法改为循环

//递归速度很慢 

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

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

相关文章

ctfshow学习记录-misc入门(图片篇-颜色通道50-59)

目录misc50misc51misc52misc53misc54misc55misc56misc57misc58misc59misc51-52的wp和脚本参考的是csdn博主&#xff1a;z.volcano 九某人的碎碎念&#xff1a;这篇一更&#xff0c;说明近期是真的没有时间写wp了。虽说好多都是之前做过的题&#xff0c;但是wp整理起来还是比较耗…

OpenCV-Python 颜色识别(红色)并拟合矫正目标区域

OpenCV版本&#xff1a;4.6.0.66 算法实现思路&#xff1a; 颜色识别(红色)形态学去噪轮廓检测多边形拟合透视矫正代码实现&#xff1a; import cv2 import numpy as np# 可视化 def img_show(name, img):cv2.namedWindow(name, 0)cv2.resizeWindow(name, 1000, 500)cv2.imsh…

Java内存模型与volatile

Java内存模型 Java内存模型Java Memory Model&#xff0c;简称JMM&#xff0c;本身是一种抽象的概念并不真实存在它仅仅描述的是一组约定或规范&#xff0c;通过这组规范定义了程序中(尤其是多线程)各个变量的读写访问方式并决定一个线程对共享变量的写入何时以及如何变成对另…

白鹭群优化算法(ESOA)附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

单调区间能写成并吗?【基于间断区间的讨论】

不能。 问题 在做到一道题的时候&#xff0c;发现了两个减区间&#xff0c;于是就用并∪连接到一起了&#xff0c;但是答案是要用和连接。于是想要辨析一下这个并和和的区别。 区别 并&#xff1a;并的意思是将多个区间看成一个并起来的整体&#xff0c;在整个区间上仍然是…

按照 STAR 法则介绍自己做过的项目

大家好啊&#xff0c;我是大田 介绍项目注意两点&#xff1a;1、自己真的做过 2、逻辑表达能力 为什么推荐你用 STAR 法则说呢&#xff1f; STAR 法则是结构化面试中非常重要的理论。 面试官通过这样的描述全面了解你的测试知识、经验、技术能力的掌握程度&#xff0c;通过你发…

本地pycharm连接到远程服务器(超级详细)

本地pycharm连接到远程服务器&#xff08;超级详细&#xff09; 文章之前&#xff0c;你需要做的是 1.服务器需要创建好虚拟环境 2.你的本地安装好pycharm 目的是 同步服务器上的文件 在本地进行debug&#xff0c;并将修改后的文件进行更新 一般是将文件代码上传到服务器上面&…

【微服务】Sentinel 控制台

目录 1. 概述 2. 启动控制台 2.1 获取 Sentinel 控制台 2.2 启动 3. 客户端接入控制台 3.1 引入JAR包 3.2 配置启动参数 3.3 触发客户端初始化 4. 查看机器列表以及健康情况 5. 监控 5.1 "簇点链路"中显示刚刚调用的资源&#xff08;单机实时&#xff09; …

猿创征文|分享一下我的日常开发工具和常用软件

1、Eclipse IDE for Java Developers 这个软件&#xff0c;个人已经用了很多年的免费 Java 开发软件。 1&#xff09;配置JDK 2&#xff09;新建项目 3&#xff09;运行使用 这里注意到有 Run As 和 Debug As ,区别就是后者是调试模式&#xff0c;你可以在代码任意处打断点跟…

element-ui中获取el-divider的组件的ref时为空

element-ui中的el-divider组件是函数式组件,所以当我尝试获取其ref时总是获取不到,因为函数式组件没有this. ![在这里插入图片描述](https://img-blog.csdnimg.cn/496711bf5c2a4dd1bee168e4e2d638d4.png)此时打印this.$refs,控制台输出: 没有h2,翻看el-divider源码发现是函数式…

C++入门学习3-指针与字符数组,函数,指针数组

c入门学习3char型指针的使用p*p*p与p与[整型指针指向整型数组]的区别指针与函数的使用指向函数的指针空指针调用函数从函数中返回指针一维数组和二维数组的类比CHAR型指针数组关于&achar型指针的使用 char型指针可以直接指向一个字符串&#xff0c;如下 char s[]{a,b,c};…

YOLO V7源码解析

1.命令行参数介绍 YOLO v7参数与YOLO v5差不多&#xff0c;我就直接将YOLO v5命令行参数搬过来了&#xff0c;偷个懒 --weights:初始权重--cfg:模型配置文件--data:数据配置文件--hyp:学习率等超参数文件--epochs:迭代次数-imgsz&#xff1a;图像大小--rect&#xff1a;长方…

多目标蜉蝣优化算法(MOMA)附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

统计信号处理基础 习题解答6-6

题目 在本题中&#xff0c;我们扩展标量BLUE的结果。假定 其中θ 是待估计的未知参数&#xff0c;β 是已知常数&#xff0c;数据矢量x 的协方差矩阵是C 。在本题我们定义修正的线性估计量为 证明BLUE为&#xff1a; 另外求最小方差。 解答&#xff1a; 首先确保线性估计量是…

TFT-LCD显示中英文

TFT-LCD显示中英文 在前面编写了屏幕显示ASCII字符和字符串后&#xff0c;本次实现屏幕显示中文字符和中文字符串 中文字符取模 阴码&#xff0c;逐行式&#xff0c;逆向&#xff0c;十六进制数&#xff0c;C51格式&#xff0c; 输入要显示的中文字符&#xff0c;字体选择宋…

【数据结构】搜索二叉树(C++实现)

目录 一、二叉搜索树的概念 二、二叉搜索树的实现 2.1 节点的定义及构造 2.2 树的结构及功能展示 2.3 树的 Insert 2.4 树的中序遍历 2.4 树的 Find 2.5 树的 Erase 2.6 拷贝构造、赋值运算符重载、析构函数 三、递归实现树的增删查 3.1 递归实现 FindR 3.2 递归实…

Vue | Vue.js Composition API(二)

&#x1f5a5;️ Vue.js专栏&#xff1a;Vue.js 初级知识 Composition API(二) &#x1f9d1;‍&#x1f4bc; 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; ✨ 个人主页&#xff1a;CoderHing的个人主页 &#x1f340; 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀…

嘿,朋友,其实 CSS 动画超简单的 - 时间函数篇(贝塞尔曲线、steps,看完还不懂算我输)

分配内存 - new 官方定义&#xff1a;new是一个分配内存的内置函数&#xff0c;第一个参数是类型&#xff0c;而不是值&#xff0c;返回的值是指向该类型新分配的零值的指针。 func new(Type) *Type 我们平常在使用指针的时候是需要分配内存空间的&#xff0c;未分配内存空间…

Java自定义注解

目录 一、什么是自定义注解 1&#xff09;Java注解简介 2&#xff09;Java注解分类 JDK基本注解 JDK元注解 自定义注解 如何自定义注解&#xff1f; 二、自定义注解 1&#xff09;获取类上注解值 2&#xff09;获取类属性上的注解属性值 3&#xff09;获取方法上的注…

WireShark 常用协议分析

WireShark 常用协议分析 1.3 实战&#xff1a;使用 WireShark 对常用协议抓包并分析原理 协议分析的时候 我们 关闭混淆模式&#xff0c; 避免一些干扰的数据包存在。 1.3.1 常用协议分析 - ARP 协议 地址解析协议 &#xff08;英语&#xff1a;Address Resolution Protocol&…