再识C语言 DAY12 【再识函数(上)】

文章目录

  • 前言
  • 一、函数是什么?
  • 二、自定义函数
    • 参数
    • 返回值
      • void修饰函数的返回值和参数
  • 函数不能嵌套定义
    • 形参和实参的区别
    • return的用法
    • 补充if……else if……else……的用法
  • 后面会讲解“函数调用,函数声明以及函数原型,块级变量,归函数”等等内容
  • 如果您发现文章有错误请与我留言,感谢


前言

本文章总结于此文章


一、函数是什么?

函数的本质是一段可以重复使用的代码,这段代码被提前编写好了,放到了指定的文件中,使用时直接调取即可。
例如,strcmp() 是一个用来比较字符串大小的函数,它的用法如下:

#include <stdio.h>
#include <string.h>
int main()
{char str1[] = "http://c.biancheng.net";char str2[] = "http://www.baidu.com";//比较两个字符串大小int result = strcmp(str1, str2);printf("str1  - str2 = %d\n", result);return 0;
}

str1 和 str2 是传递给 strcmp() 的参数,strcmp() 的处理结果赋值给了变量 result

int result = strcmp(str1, str2);

比较字符串大小是常用的功能,一个程序可能会用到很多次,如果每次都写这样一段重复的代码,不但费时费力、容易出错,而且交给别人时也很麻烦,所以C语言提供了一个功能,允许我们将常用的代码以固定的格式封装(包装)成一个独立的模块,只要知道这个模块的名字就可以重复使用它,这个模块就叫做函数(Function)

函数的本质是一段可以重复使用的代码,这段代码被提前编写好了,放到了指定的文件中,使用时直接调取即可。下面我们就来演示一下如何封装 strcmp() 这个函数。

二、自定义函数

  • 函数组成部分
int main()
{
reuturn 0;
}

int :返回值类型
main: 函数名 ==> 标识符 (只是一个名字,随便起)
()= 描述参数
return 0 函数返回值
函数定义的格式
函数返回值类型 函数名(形参)
{
函数体
return 返回值
}

参数

函数的一个明显特征就是使用时带括号( ),有必要的话,括号中还要包含数据或变量,称为参数(Parameter)。参数是函数需要处理的数据,例如:
strlen(str1)用来计算字符串的长度,str1就是参数。
puts(“C语言中文网”)用来输出字符串,"C语言中文网"就是参数。

返回值

既然函数可以处理数据,那就有必要将处理结果告诉我们,所以很多函数都有返回值(Return Value)。所谓返回值,就是函数的执行结果。例如:

char str1[] = "C Language";
int len = strlen(str1);

strlen() 的处理结果是字符串 str1 的长度,是一个整数,我们通过 len 变量来接收。

函数返回值有固定的数据类型(int、char、float等),用来接收返回值的变量类型要一致。

所以到底什么是返回值,如果你感到很懵,先别急,后面会详细讲。

先举一个例子:

#include <stdio.h>
int sum(){int i, sum=0;for(i=1; i<=100; i++){sum+=i;}return sum;
}
int main()
{int a = sum();printf("The sum is %d\n", a);return 0;
}

运行结果: The sum is 5050

我们发现了一个 return sum;字面意思就是返回了 sum 的值,既然她返回了一个值,他去了哪里呢?为什么 int sum() 不和 int main() 一样是return 0;呢?

我们发现把return sum;改为 return 0; 时。运行结果: 0.
把return sum;改为 return 3; 时。运行结果: 3.

不难发现 return sum; 的确返回了 sum函数的值

我们知道函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。

上面的例子明显接收用户传递的数据 sum.

所以说,返回值返回的是变量的值

再来一个例子:

把一个数组中最大的值找出来

#include <stdio.h>
int FindMAX(int *array,int Count)
{int i;int max = array[0];for (i = 0; i <Count ; i++)//count函数可以用来统计字符串中某个字符的个数,或数组中某个元素的数量{if (array[i] > max){max = array[i];}}return max;}
int main(void)
{int MAX;int a[] = { 12,6,9,34,21,7 };MAX = FindMAX(a,6);printf("MAX=%d\n", MAX);return 0;
}

注:count函数可以用来统计字符串中某个字符的个数,或数组中某个元素的数量

这里是引用

void修饰函数的返回值和参数

1.void用来作为函数返回值

代码示例1:

#include <stdio.h>
#include <windows.h>
void show()
{
printf("no return value!\n");
}
int main()
{
show();
system("pause");
return 0;
}

输出结果:
在这里插入图片描述
示例2:
在这里插入图片描述
直接返回return 1也是可以通过编译的,且不会有警告

return 0指程序运行结束;
return 1指返回主调函数,程序继续运行。

但如果有变量去接收则会报错
在这里插入图片描述
2.void作为函数参数

如果一个函数没有参数,我们可以不写, 如test1()

代码示例:

//如果一个函数没有参数,我们可以不写, 如test1()
#include <stdio.h>
#include <windows.h>
int test1() //函数默认不需要参数
{
return 1;
}
int test2(void) //明确函数不需要参数
{
return 1;
}
int main()
{
printf("%d\n", test1(10)); //依旧传入参数,编译器不会告警或者报错
printf("%d\n", test2(10)); //依旧传入参数,编译器会告警(vs)或者报错(gcc)
system("pause");
return 0;
}

函数不能嵌套定义

强调一点,C语言不允许函数嵌套定义;也就是说,不能在一个函数中定义另外一个函数,必须在所有函数之外定义另外一个函数。main() 也是一个函数定义,也不能在 main() 函数内部定义新函数。

下面的例子是错误的:

#include <stdio.h>
void func1()
{printf("http://c.biancheng.net");void func2(){printf("C语言小白变怪兽");}
}
int main()
{func1();return 0;
}

有些初学者认为,在 func1() 内部定义 func2(),那么调用 func1() 时也就调用了 func2(),这是错误的。

正确的写法应该是这样的:

#include <stdio.h>
void func2() 
{printf("\nC语言小白变怪兽");
}
void func1() 
{printf("http://c.biancheng.net");func2();
}
int main() {func1();return 0;
}

要想达到「调用 func1() 时也调用 func2()」的目的,必须将 func2() 定义在 func1() 外面,并在 func1() 内部调用 func2()。

形参和实参的区别

形参(形式参数)

在函数定义中出现的 参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数 简称形参。

实参(实际参数)

函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数, 简称实参。

形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。

补充
占位符就是先占住一个固定的位置,等着你再往里面添加内容的符号,广泛用于计算机中各类文档的编辑

请看下面的例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//计算从m加到n的值
int sum(int m, int n){int i;for (i = m+1; i <= n; ++i) {m += i;}return m;
}
int main() 
{int a, b, total;printf("Input two numbers: ");scanf("%d %d", &a, &b);total = sum(a, b);printf("a=%d, b=%d\n", a, b);printf("total=%d\n", total);return 0;
}

在这里插入图片描述

++i先自增1再赋值。 i++先赋值再自增1 在这里用两个都可以。

在这段代码中,函数定义处m、n 是形参 , 函数调用处a、b 是实参。通过 scanf() 可以读取用户输入的数据,并赋值给 a、b,在调用 sum() 函数时这份数据会传递给形参 m、n。

从运行情况看,输入 a 值为 1,即实参 a 的值为 1,把这个值传递给函数 sum() 后,形参 m 的初始值也为 1,在函数执行过程中,形参 m 的值变为 5050。函数运行结束后,输出实参 a 的值仍为 1,可见实参的值不会随形参的变化而变化。

以上调用 sum() 时是将变量作为函数实参,除此以外,你也可以将常量、表达式、函数返回值作为实参,如下所示:

total = sum(10, 98);  //将常量作为实参
total = sum(a+10, b-3);  //将表达式作为实参
total = sum( pow(2,2), abs(-100) );  //将函数返回值作为实参

形参和实参可以同名,因为他们相互独立,互不影响。因为实参在函数外有效,形参在函数内有效。

请看下面的例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//计算从m加到n的值
int yuo(int a, int b)
{int i;for (i=1+a ;i<=b;i++){a += i ;}return a ;
}int main()
{int a, b,sum;printf("请输入两个数字:\n");scanf("%d %d", &a, &b);printf("%d  %d", a, b);sum = yuo(a, b);printf("\ntotal: %d", sum);return 0;
}

运行:
在这里插入图片描述
调用 yuo() 函数后,函数内部的形参 m 的值已经发生了变化,而函数外部的实参 m 的值依然保持不变,可见它们是相互独立的两个变量,除了传递参数的一瞬间,其它时候是没有瓜葛的。

错误示范:

这种情况下,a<=b表达的意思就和我们的想法有误了(a的值并不是每次加一),所以要引进变量 i ,让 i 的值做到每次加一

	for (a ;a<=b;a++){a += a + 1;}return a ;
}

return的用法

函数的返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这个结果通过 return 语句返回。

对C语言返回值的说明:

  1. 没有返回值的函数为空类型,用void表示。例如:
void func()
{printf("http://c.biancheng.net\n");
}

一旦函数的返回值类型被定义为 void,就不能再接收它的值了。例如,下面的语句是错误的:

int a = func();

但我们可以这样用:

#include <stdio.h>
void func()
{printf("http://c.biancheng.net\n");
}
int main ()
{
func();
return 0;
}

是可以输出的:

在这里插入图片描述

函数一旦遇到 return 语句就立即返回,后面的所有语句都不会被执行到了。从这个角度看,return语句还有强制结束函数执行的作用

下面我们举个例子,还是以判断素数为题,并且要使用函数和 void,return:

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
void PUA(int a)
{int i;bool flog = 1;if (a < 0){printf("%d其不是素数",a);return;}for (i = 2;i < a;i++){if (a % i == 0){flog = 0;break;}}if(flog){printf("\n%d其是素数",a);}else{printf("\n%d其不是素数",a);}}int main()
{int num;printf("输入一个数字:");scanf("%d", &num);PUA(num);return 0;
}

运行没问题:

在这里插入图片描述
注:if(x) 当x = 0时 表达式为假,不输出,x 不为0时,表达式为真,可以输出。

补充if……else if……else……的用法

格式:

            if(1)A;        // 如果1成立,执行Aelse if(2)B;        //  如果1不成立,2成立,执行Belse if(3)C;        // 如果1、2不成立,3成立,执行C……elseD;        // 如果1、2、3均不成立,执行D

————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_54110690/article/details/122519943

所以 return 语句是提前结束函数的唯一办法

后面会讲解“函数调用,函数声明以及函数原型,块级变量,归函数”等等内容

如果您发现文章有错误请与我留言,感谢

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

打工人速看!PMP考试值得考吗?PMP项目管理证书含金量高吗?详细解答来了!

当下人才济济的招聘市场&#xff0c;不难发现&#xff0c;拥有更多技能和懂得管理知识的人士永远是招聘市场抢手的香饽饽&#xff01;而作为苦苦求职工作的打工人&#xff0c;总是想自己要是能再优秀点就好了&#xff01; 今天分享的 PMP 项目管理证书就是一个给自己“镀金”的…

如何开通GitHub Copilot

GitHub Copilot 是由GitHub 和OpenAI共同开发的人工智能代码辅助工具&#xff0c;可以自动地生成高质量代码片段、上下文信息等。 通过自然语言处理和机器学习技术&#xff0c;能够通过分析程序员编写的代码、注释和上下文信息&#xff0c;自动生成代码&#xff0c;减轻程序员的…

Python读写EXCEL文件常用方法

python读写excel的方式有很多&#xff0c;不同的模块在读写的讲法上稍有区别&#xff0c;这里我主要介绍几个常用的方式。 用xlrd和xlwt进行excel读写&#xff1b;用openpyxl进行excel读写&#xff1b;用pandas进行excel读写&#xff1b; 一、数据准备 为了方便演示&#xf…

【英语趣味游戏】填字谜(Crossword)第2天

谜题出处 柯林斯字谜大全&#xff08;6&#xff09;&#xff0c;Collins——Big Book of Crosswords (Book 6) Puzzle Number: 115 本期单词 横向 1、Fetch (8) 拿&#xff0c;取&#xff0c;8个字母 答案&#xff1a;Retrieve&#xff0c;取到&#xff0c;拿回 5、Common s…

视频转GIF动图实践, 支持长视频转GIF

背景 找了很多GIF动图制作的工具&#xff0c;比如将视频转成GIF, 或者将一系列图片转成GIF, 增加背景文案等等功能。很多收费或者用的一些三方库有点点卡顿&#xff0c;或者需要安装一个软件&#xff0c;所以就自己做一款纯前端页面级别的 视频转 GIF 动图工具。 最开始找到一…

顶象点选验证码

要放假了好颓废。。。。 没啥事儿干&#xff0c;就把之前剩余的顶象点选系列的验证码类型看了下。 之前分享了一篇关于这个顶象的滑块的 DX算法还原_dx算法还原_逆向学习之旅-CSDN博客&#xff0c;感兴趣可以去看看。 咱们以文字点选为例&#xff1a; def get_image_arry(s…

堆宝塔

L2-1 堆宝塔 分数 25 作者 陈越 单位 浙江大学 堆宝塔游戏是让小朋友根据抓到的彩虹圈的直径大小&#xff0c;按照从大到小的顺序堆起宝塔。但彩虹圈不一定是按照直径的大小顺序抓到的。聪明…

浏览器内存泄漏排查指南

1、setTimeout执行原理 使用setInterval/setTimeOut遇到的坑 - 掘金 2、Chrome自带的Performance工具 当我们怀疑页面发生了内存泄漏的时候&#xff0c;可以先用Performance录制一段时间内页面的内存变化。 点击开始录制执行可能引起内存泄漏的操作点击停止录制 如果录制结束…

三、防御保护---防火墙安全策略篇

三、防御保护---防火墙安全策略篇 一、什么是安全策略二、安全策略的组成1.匹配条件2.动作3.策略标识 三、防火墙的状态检测和会话表1.会话表2.状态检测技术 四、ASPF--隐形通道五、用户认证1.用户认证的分类2.认证方式3.认证策略4.认证域 一、什么是安全策略 传统的包过滤防火…

【代码随想录】刷题笔记Day56

前言 26回了老家参加二姨的婚礼&#xff0c;还逛了几圈亲戚&#xff0c;回来就接家教的活&#xff0c;想到还要刷题开组会&#xff0c;回家注定是没法怎么休息啦&#xff0c;可恶 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 暴力解法&#xff08;双指针优化&#xf…

自然语言nlp学习四

5-5 BMTrain--ZeRO_哔哩哔哩_bilibili 5-6 BMTrain--Pipeline Parallel (流水线并行)_哔哩哔哩_bilibili 5-12 BMCook--背景介绍_哔哩哔哩_bilibili

基于JAVA的河南软件客服系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、系统展示四、核心代码4.1 查询客户4.2 新增客户跟进情况4.3 查询客户历史4.4 新增服务派单4.5 新增客户服务费 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的河…