首页 > 其他分享 >C语言基础知识学习(7)

C语言基础知识学习(7)

时间:2024-11-03 13:51:03浏览次数:3  
标签:调用 函数 形参 代码 基础知识 学习 数组 实参 C语言

大家好啊,本期和大家分享C语言函数相关知识。

1.函数的概念

我们早在数学中就接触过函数,比如:一次函数y=ax+b,a、b都是常数,给定任意一个x就可以得到y。在C语言中也引入函数(function)概念,更准确的翻译应该为:子程序。C语言中函数就是完成某一特定功能的一段代码。

一个大的任务可以分成许多窖小的函数完成。如果一个函数能完成某项特定的任务的话,这个函数是可以复用的,提升了软件的开发效率。

C语言函数分为两类:

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

1.1库函数 

  1.1.1标准库和头文件

C语言的国际标准ANSI C规定了一些常用的函数的标准,被称为标准库,不同的编译器厂商根据ANSI C提供的C语言标准给出了一系列函数的实现,这些函数被称为库函数。C语言并不提供库函数,它规定了C语言的各种语法规则。

我们在前文中学到的printf和scanf都是库函数,库函数也是函数,不过这些都是现成的,可以直接使用,一些常见的功能就不需要程序猿自己实现了,一定程度上提高了效率。

各种编译器的标准库中提供了一系列的库函数,这些函数根据功能的划分,都在不同的头文件中进行了声明。

库函数相关头文件可以访问c/c++官方链接查找:https://zh.cppreference.com/w/c/header

  1.1.2库函数使用举例

例如:sqrt()函数,它的作用是计算平方根。使用它要包含math.h头文件,代码如下:

运行结果:

1.2自定义函数

了解了库函数,现在我们聚焦到自定义函数,自定义函数其实更加重要,也能给程序猿写代码更多的创造性。

 1.2.1自定义函数语法

自定义函数语法形式如下:

我们可以把函数想象成一个工厂,工厂得输入原料,经过工厂加工生产出产品。函数也是一样,函数一般会输入一些值(可以是0个也可以是多个),经过函数计算得出结果。

函数返回类型可以是int、char,也可以是void(什么都不返回),可以理解为工厂加工后的产品类型。

函数名就是为了我们方便调用函数而起的名字,名字尽量有意义,方便调用。

形式参数相当于送进工厂中的原料,函数的参数也可以是void,表示函数没有参数。如果有要表明参数的类型和个数。

函数体就是函数的计算过程,相当于工厂的加工过程。

1.2.2自定义函数举例

例如:写一个乘法函数,用来计算两个整型变量的乘法。代码如下:

运行结果:

根据我们要完成的功能,给函数取名ride,函数ride需要接受两个整型的参数,函数计算结果也是整型。未来我们可以根据需要设计函数,函数名、参数、返回类型都是可以灵活多变的。

2.形参和实参

在函数的使用过程中,把函数的参数分为实参和形参。看下我们前面写的代码:

第5~8行是ride函数的定义,有了函数后,在第13行调用。

2.1实参

我们把第13行调用ride函数时,传递给函数的参数x和y称为实际参数,简称实参

实际参数就是真实传递给函数的参数。

2.2形参

在上面代码第五行定义函数的时候,函数名ride后的括号中的x和y,称为形式参数,简称形参

为什么叫形参呢?事实上,如果只定义ride函数,而不调用的话,ride函数的参数x和y只是形式上存在,不会向内存申请空间,也就是不是真实存在,所以叫形式参数。

形式参数只有在函数被调用的过程中为了存放实参传递过来的值,才会向内存申请空间,这个过程就是形参的实例化

2.3形参和实参的关系

实参是传递给形参的,二者是有联系的,但形参和实参各自是独立的空间。我们可以通过对上面代码调试来观察:

&是取地址符,可以查看变量地址。从调试结果我们可以观察到,x和y确实得到了a和b的值,但是和a、b地址不同,所以我们可以理解为形参是实参的一份临时拷贝。由于二者不是同一块内存空间,名字也可以相同,对形参的修改也不会影响实参。

例如我们将上面代码中的x、y改成a、b:

结果依然正确:

3.return语句

函数的设计中经常会出现return语句,比如上面例子中的return x*y,作用就是返回x*y的值。以下是使用return语句的注意事项:

  1. return后面可以是一个数值,也可以是一个表达式,如果是表达式则先执行表达式,再返回表达式结果。
  2. return 后面可以什么也没有,这种写法适合函数返回类型是void的情况。
  3. return执行后,函数就彻底返回,后面的代码不再执行。
  4. 如果return返回的值和函数返回类型不一致,系统会自动将返回值转换为函数返回类型
  5. 如果函数中存在分支语句,则要保证每种情况下都有return返回,否则会出现编译错误。
  6. 如果没写函数返回类型,编译器会默认返回类型是int。
  7. 函数写了返回类型,但没有使用return返回值,那么函数的返回值是未知的。

4.数组做函数参数

在使用函数时,有时会将数组作为参数传递给函数,在函数内部进行操作。比如:写下一个函数将一个数组的内容全部置为0,再写一个函数打印数组。这里我们先来了解一些数组传参的知识:

  1. 函数的形参要和实参个数匹配。
  2. 函数的实参是数组,形参也要写成数组。
  3. 形参如果是一维数组,数组大小可以省略。
  4. 形参如果是二维数组,行可以省略,但列不能。
  5. 数组传参,形参不会创建新数组。
  6. 形参操作的数组和实参操作的数组是同一个。

我们可以考虑到代码基本形式应该是这样的:

modify_arr函数能够对数组内容修改,就得把数组作为参数传递给函数,同时能够遍历数组,对每个值进行修改,还要把数组元素个数作为参数传递给modify_arr。printf_arr也是如此,既要传递数组,也要传递数字元素个数。

这样,传参的问题解决了,那这两个函数要如何设计呢?我们可以使用for循环遍历数组:

这样便完成了对modify_arr函数和printf_arr函数的编写,代码整体以及运行结果如下:

5.嵌套调用和链式访问

5.1嵌套调用

顾名思义,嵌套调用就是函数间的相互调用,每个函数就像一个零件,正式由许多个零件精密配合才能做出完美的仪器,正是函数间有效的相互调用,最后写成一个大型程序。

举个栗子:输入年月,计算这一年这一月的天数。我们可以设计两个函数,count_year();根据输入年份确定是否是闰年,count_month();调用count_year();确定是否为闰年后,再计算这个月天数。分析完毕,代码如下:

代码运行,我们输入2033 3,运行结果:

这样这段代码就完成了。请注意:函数之间可以嵌套调用,但是函数不能嵌套定义。

5.2链式访问

所谓链式访问就是将一个函数的返回值作为拎一个函数的参数,像链条一样将函数串起来就是函数的链式访问。

举个栗子:前面我们提到了sqrt()函数,我们可以将它和printf函数一起使用:

运行结果:

再来看一个更有意思的,下面这段代码运行结果是什么呢?

要想弄明白关键在于printf函数返回的是什么,事实上printf函数返回的是打印字符的个数。

上面这个例子,第三个printf打印43,在屏幕上打印两个字符,返回2;第二个printf打印2,返回1;第一个printf打印1.

所以屏幕上最终打印:

6.函数的声明和定义

6.1单文件中函数声明和定义

一般我们在使用函数的时候,直接将函数写出然后调用。例如下面这段代码,判断是否是闰年:

43~53行是函数定义,59行是函数调用。这种是函数定义在调用前,没啥问题,如果我们将函数定义放在调用后呢?

编译代码,会报错:

这是因为C语言编译器对源代码进行编译时,从第一行向下扫描,但遇到第49行函数调用时,没有发现前面有count_year的定义,所以会报错。我们只要在调用前声明一下就可以了,如void count_year(int year);这就是函数声明。代码变成这样就可以正常编译了:

函数的调用一定要满足,先声明后使用。函数的定义也是一种特殊的声明,如果函数定义在调用前也是可以的。

6.2多个文件中函数声明和定义

如果在实际工作中,代码可能会很多,一般不会把所有代码放一个文件中,而是将函数的声明、类型的声明放在头文件(.h)中,函数的实现放在源文件(.c)中。

例如5.1求某年某月的天数问题,我们可以将定义、声明、调用分开:

这是将count_month();函数和count_year();函数在头文件count.h中声明。

这是将函数的实现(函数主体)放在count.c文件中。

在test.c中对函数调用。

有了对函数声明和定义的理解,我们写代码就更加清晰、方便了。

结语

让大家久等啦,本期我们学习了函数的相关知识,如果有任何需要修改或补充,请即时告诉我。

如果我的文章对您有帮助的话,不妨点个免费的赞和关注叭,以后我也会更加努力更新!!!感谢大家阅读。

标签:调用,函数,形参,代码,基础知识,学习,数组,实参,C语言
From: https://blog.csdn.net/Zhang886674/article/details/143335434

相关文章

  • C++学习笔记
    一、从C转向C++1.1、使用const和inline而不#define使用constconstintm=10;intn=m;上述代码在C中,编译器会先到m的内存中取出数据,再赋值给n;但在C++中,会直接将10赋值给n。C++的常量更类似于#define,是一个替换过程。#define经常不被认为是语言的一部分。define本......
  • 图像纹理基础知识
    正文纹理是物体表面固有的一种特性,所以图像中的区域常体现出纹理性质。纹理可以认为是灰度(颜色)在空间以一定的形式变化而产生的团(模式)。纹理与尺度有密切的关系,一般仅在一定的尺度上可以观察到,对纹理的分析需要在恰当的尺度上进行。纹理还具有区域性质的特点,通常被看做对局部区域......
  • 11.3 学习日志
    今天把tomcat插件弄好了找到了idea一直连接不上我的数据库的原因然后复习了一下隐式转换和强制转换packagetxt;publicclasstest{publicstaticvoidmain(String[]args){inta=2;doubleb=6.9;c=a+b;}}c为double类型;小向大转换;byteshortchar在运算时都会先变......
  • 前端react面试基础知识(II)
    这些问题涵盖了React的很多核心概念和实际应用场景。下面是针对每个问题的详细回答:1.**React项目中,如何动态改变组件的class来切换样式?**  可以通过条件判断或者状态(state)来动态改变组件的class。例如,使用`className`属性与JavaScript表达式结合:  ```jsx......
  • 2024-2025-1 学号20241315《计算机基础与程序设计》第六周学习总结
    作业信息这个作业属于哪个课程2024-2025-1-计算机基础与程序设计这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK06这个作业的目标Polya如何解决问题简单类型与组合类型复合数据结构查找与排序算法算法复杂度递归代码安全作业正文......
  • 第一周学习总结:计算机发展史及liunx系统安装
    #计算机发展相关历史1.第一代(1946-1957年):电子管计算机电子管计算机(1946-1957)这一阶段计算机的主要特征是采用电子管元件作基本器件,用光屏管或汞延时电路作存储器,输入与输出主要采用穿孔卡片或纸带,体积大、耗电量大、速度慢、存储容量小、可靠性差、维护困难且价格昂贵。在软......
  • 【综合算法学习】(第十五篇)
    目录图像渲染(medium)题目解析讲解算法原理编写代码岛屿数量(medium)题目解析讲解算法原理编写代码图像渲染(medium)题目解析1.题目链接:.-力扣(LeetCode)2.题目描述有⼀幅以mxn的⼆维整数数组表⽰的图画image,其中image[i][j]表⽰该图画的像素值⼤⼩。你也被给予三......
  • 代码随想录刷题学习日记
    仅为个人记录复盘学习历程,解题思路来自代码随想录代码随想录刷题笔记总结网址:代码随想录106.从中序与后序遍历序列构造二叉树根据一棵树的中序遍历与后序遍历构造二叉树,假设树中没有重复的元素。提供参数:中序遍历数组inorder,后序遍历数组postorder主要操作:递归三要素1......
  • 2024-2025-1 20241417 《计算机基础与程序设计》第六周学习总结
    这个作业属于哪个课程2024-2025-1-计算机基础与程序设计这个作业要求在哪里2024-2025-1计算机基础与程序设计第六周作业这个作业的目标<Polya如何解决问题,简单类型与组合类型,复合数据结构,查找与排序算法,算法复杂度,递归,代码安全>作业正文https://www.cnblogs.com......
  • 51单片机——蜂鸣器播放提示音(学习记录)
    踩过的坑!!!红外接收模块输出接口和独立按键k3共用的p32引脚,所以有红外的时候单片机会误以为按了k3按键,测试的时候要把红外接收拔掉,蜂鸣器连接的IO口是P25(江科的是P15),之前学习的时候看弹幕说型号选stc89c51rc2(但我这里的代码没改),就一直选的这个,蜂鸣器也能正常播放提示音,但到后......