函数——“C”

news2024/11/16 22:51:08

各位CSDN的uu们新年快乐呀,祝大家越来越开心,越来越优秀。那行,让我们进入今天的正题,来了解了解函数,函数是什么,C语言中函数是如何分类的,函数参数,函数调用等一系列小知识点,就让我们一起进入函数的世界吧

 为什么要使用函数

  函数是什么

 C语言是模块化程序设计语言。一个C程序可由一个主函数和若干个其他函数构成。一个较大的程序可分为若干个程序模块,每一个模块用来实现一个特定的功能。在高级语言中用子程序实现模块的功能。子程序由函数来完成。

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

 函数间的调用关系:由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。


C语言中函数的分类:

    1.库函数

    2.自定义函数

库函数

为什么会有库函数?

1. 我们知道在我们学习C语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想 把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格 式打印到屏幕上(printf)。

2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作(strcpy)

3. 在编程是我们也计算,总是会计算n的k次方这样的运算(pow)

像上面我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到, 为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。 那怎么学习库函数呢?

   我们可以用到MSDN,这是一个专门查询库函数的软件

    我们还可以用到cplusplus,也是可以查询库函数的使用功能以及函数的实现

 

 

 这些工具可以让我们更加方便地了解库函数,但是,有一个问题,就是这些网站一般都是全英文,那么我们还是要把英语学好的,把英语学好尤为重要,小雅兰的目标就是赶紧把英语四六级证书拿到手啦,其余的也不敢奢求,哈哈哈,收!

自定义函数

怎样定义函数

 为什么要定义函数

       函数必须“先定义,后使用”。

       定义函数包括以下几个内容:

            (1)指定函数的名字

            (2)指定函数的类型

            (3)指定函数的参数名字和类型

            (4)指定函数应当执行什么操作

怎样定义无参函数

  定义无参函数的一般形式为:

       类型名 函数名()

      {

           声明部分

           语句部分

      }

怎样定义有参函数

  定义有参函数的一般形式为:

       类型名 函数名(形式参数表列)

       {

             声明部分

             语句部分

       }

  下面,我来给大家举个例子看一下,以便我们更好地理解如何定义有参函数

int max(int x,int y)
{
  int z;//函数体中的声明部分
  z=x>y?x:y;
  return z;
}

定义空函数

  定义空函数的一般形式为:

      类型名 函数名()

      {}

  我还是来给大家举个例子看一下

   dummy()

   { }

 主调函数调用空函数时,只表明这里要调用一个函数,但函数本身什么工作也不做,等以后扩充函数功能时补充上。


我们来举个例子,写一个函数来交换两个整型变量的内容

我们首先肯定会这样想

#include<stdio.h>
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);
   printf("交换前:a=%d b=%d\n",a,b);
   swap(a,b);//实际参数
   printf("交换后:a=%d b=%d\n",a,b);
   return 0;
}

我们来运行一下我们刚刚写的代码,发现,结果怎么和我们预想的不一样呢?

我们仔细来想想,a和b是有自己的空间的,x和y也是有自己的空间的,x和y的的确确交换了,但是,实参传递给形参的时候,形参是实参的一份临时拷贝,对实参的修改是不会影响实参的。 所以,a和b不会交换。

事实证明,我们这样的做法肯定是不行,那我们不用这个传值调用的方法,又该怎么做呢?不如,我们传它的地址试试吧

#include<stdio.h>
void swap(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);
   printf("交换前:a=%d b=%d\n",a,b);
   swap(&a,&b);
   printf("交换后:a=%d b=%d\n",a,b);
   return 0;
}

来,我们一起来运行一下此代码

 哦豁,结果发现,传地址的方法果然可以,a和b的果真交换了,此方法称为传址调用


函数的参数

实际参数(实参)

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

实参可以是:常量、变量、表达式、函数等。

无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形 参。

形式参数(形参)

形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内 存单元),所以叫形式参数。

形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

上面的*pa,*pb就是形式参数,a,b就是实际参数


函数的调用

函数调用的一般形式

 函数调用的一般形式为:

     函数名 (实参表列)

 说明:

   (1)如果是调用无参函数,则“实参表列”可以没有,但括弧不能省略

   (2)如果实参表列包含多个实参,则各参数间用逗号隔开。实参与形参的个数应相等,类型应匹配。实参与形参按顺序对应,一一传递数据。

调用函数的方式

 按函数在程序中出现的位置来分,可以有以下三种函数调用方式:

  (1)作为一个函数语句

    把函数调用作为一个语句,这时不要求函数带回值,只要求函数完成一定的操作。如,print_star().

  (2)作为函数表达式的一部分

   函数出现在一个表达式中,这种表达式称为函数表达式。这时要求函数带回一个确定的值以参加表达式的运算。如,c=2*max(a,b);

  (3)作为函数的实参

  将函数调用作为一个函数的实参。

  例如:m=max(a,max(b,c));

   其中max(b,c)是一次函数调用,它的值作为max另一次调用的实参。m的值是a、b、c三者中的最大值。

对被调用函数的声明和函数原型

 1.首先被调用的函数必须是已经存在的函数(是库函数或用户自己定义的函数)。但光有这一条件还不够。

 2.如果使用库函数,还应该在本文件开头用#include命令将调用有关库函数时所需用到的信息“包含”到本文件夹中来。

 3.如果使用用户自己定义的函数,而该函数的位置在调用它的函数(即主调函数)的后面,应该在主调函数中对被调用的函数作声明。

 函数原型的一般形式为:

    1.函数类型 函数名(参数类型1,参数类型2......)

    2.函数类型 函数名(参数类型1,参数名1,参数类型2,参数名2......)

        声明的作用是把函数名、函数参数的个数和参数类型等信息通知编译系统,以便在遇到函数调用时,编译系统能正确识别函数并检查调用是否合法。

注意:

     函数的“定义”和“声明”的区别:

      函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。

      函数的声明的作用则是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时系统按此进行对照检查。


下面,我来给大家举一个例子说明一下

  例:输入两个实数a和b,用一个函数求出a^2+b^2.

#include<stdio.h>
double sum(double x,double y)//定义sum函数
{
   double z=0.0;
   z=x*x+y*y;
   return z;//把变量z的值作为函数值返回
}
int main()
{
   double a=0.0;
   double b=0.0;
   printf("please enter a and b:\n");
   scanf("%lf %lf",&a,&b);
   double c;
   c=sum(a,b);
   printf("sum is %lf\n",c);
   return 0;
}

我们来运行一下结果


 我还想给大家拓展一个知识点

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

  传址调用:传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。

                    这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以                      直接操作函数外部的变量。


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

   嵌套调用就是在调用一个函数的过程中,又调用另一个函数

    例:输入4个整数,找出其中最大的数。用函数的嵌套调用来处理。

#include<stdio.h>
int max2(int a,int b)
{
   if(a>b)
    return a;
   else 
    return b;
}
int max4(int a,int b,int c,int d)
{
  int m=0;
  m=max2(a,b);
  m=max2(m,c);
  m=max2(m,d);
  return m;
}
int main()
{
   int a=0;
   int b=0;
   int c=0;
   int d=0;
   int max=0;
   printf("please enter 4 interfer numbers:\n");
   scanf("%d %d %d %d",&a,&b,&c,&d);
   max=max4(a,b,c,d);
   printf("max=%d\n",max);
   return 0;
}

诶嘿,运行一波走起

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


链式访问:把一个函数的返回值作为另外一个函数的参数。  

#include<stdio.h>
int main()
{
   //注:printf函数的返回值是打印在屏幕上字符的个数
   printf("%d", printf("%d", printf("%d", 43)));
   return 0;
}

此程序的结果应是4321.

首先,打印43,这毋庸置疑,43是两个字符,所以返回2,2是一个字符,然后又返回1.


 好啦,小雅兰今天的内容就到这里了,函数在C语言中真的是很重要的存在,我们要认真学,学会使用上面介绍的那些工具,多刷一点和函数有关的习题,这样才能保证学得更好。

另外,函数中十分重要的内容——递归。我们留到下一篇文章中再去详细讲,我自认为,递归是一个很难的东西,确实挺耗费时间,可只要弄明白了这个问题,以后多数题目都可以利用递归来解,几行代码就可以解决非常复杂的问题。下一篇文章,我们会讲解函数递归和著名的青蛙跳台阶,敬请uu们期待!!!

最后,我还是要说,新年快乐,冲冲冲!

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

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

相关文章

文件操作详解-IO

目录 1.认识文件 2.文件的类型 3.java对文件的操作 针对文件系统操作 针对文件内容操作 字节流 字符流 字节流的使用 字符流的使用 4.文件IO小程序练习 示例1 示例2 1.认识文件 狭义的文件指的是硬盘上的文件和目录 广义的文件泛指计算机中的很多的软硬件资源,操…

3小时精通opencv(二)图片的常用操作

3小时精通opencv(二)图片的常用操作 参考视频资源:3h精通Opencv-Python 文章目录3小时精通opencv(二)图片的常用操作灰度图像高斯滤波边缘检测膨胀函数腐蚀函数整体代码灰度图像 img cv2.imread(Resources/lena.png) imgGray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.im…

【C++】位图 | 布隆过滤器

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;哈希函数…

添加选课模块分析

1 模块需求分析 1.1 模块介绍 本模块实现了学生选课、下单支付、学习的整体流程。 网站的课程有免费和收费两种&#xff0c;对于免费课程学生选课后可直接学习&#xff0c;对于收费课程学生需要下单且支付成功方可选课、学习。 选课&#xff1a;是将课程加入我的课程表的过…

论文投稿指南——中文核心期刊推荐(水利工程)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

大展宏图、首创基于.NET 7强大内核-Zoomla!逐浪CMS v8.7.0发布

2022年底&#xff0c;微软 .NET Conf 在线活动正式开幕。作为微软开源、跨平台开发平台&#xff0c;.NET 7 现已推出首个正式版&#xff0c;这也代表微软的“统一工作”终于完成。 使用 .NET 7 可以轻松地将 .NET 7 项目容器化&#xff0c;在 GitHub 操作中设置 CI / CD 工作流…

拔高法三视图

拔高法最主要的就是俯视图&#xff0c;是三视图的根基&#xff0c;看主视图和侧视图&#xff0c;顶点位置在底面(俯视图)范围内&#xff0c;不在则不能拔高&#xff1b;俯视图有虚线不能拔高 首先标出俯视图所有结点&#xff0c;并且画出俯视图所对应的直观图。用斜二测画法 …

Spring Cloud 中的OpenFeign+Ribbon详解

1 spring cloud 远程调用没有看过的小伙伴可以点击传送门先去了解Nacos。有了Nacos做注册中心后&#xff0c;我们就可以获取其他服务的地址进行调用了。远程调用就需要用到我们今天的主角OpenFeign&#xff0c;如果被调用服务存在多个实例就需要进行负载均衡&#xff0c;负载均…

给定两个数组x和hp,长度都是N。 x数组一定是有序的,x[i]表示i号怪兽在x轴上的位置 hp数组不要求有序,hp[i]表示i号怪兽的血量

题目描述 给定两个数组x和hp&#xff0c;长度都是N。 x数组一定是有序的&#xff0c;x[i]表示i号怪兽在x轴上的位置 hp数组不要求有序&#xff0c;hp[i]表示i号怪兽的血量 为了方便起见&#xff0c;可以认为x数组和hp数组中没有负数。 再给定一个正数range&#xff0c;表示如果…

Vue 快速入门(二)

1、Vue浏览器插件安装 安装地址 https://devtools.vuejs.org/guide/installation.html下载完后&#xff0c;直接将vuejs-devtools.crx文件拖到Chrome浏览器扩展程序中去即可。如图&#xff1a; 2.安装完成后&#xff0c;试试效果&#xff0c;我们打开之前写的hello.html页面看…

32.Isaac教程--操纵运动规划

操纵运动规划 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html Isaac SDK 为机械臂的运动规划提供了以下组件&#xff1a; EndEffectorGlobalPlanner&#xff1a;使用逆运动学将末端执行器的笛卡尔目标转换为关节角度目标。 此小码可以接收笛卡尔…

云原生技能树-容器镜像制作、发布、拉取和运行

创建仓库 请在你自己的 gitcode.net 上创建一个仓库&#xff0c;命名为cloud_native_hello_py&#xff0c;目录结构如下&#xff1a; . ├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md └── src├── main.py└── requirements.txt其中 ma…

avb校验相关与块校验原理

一、启动校验流程 edk2/QcomModulePkg/Library/avb/VerifiedBoot.c DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed %r\n", Status)); in LoadImageAndAuth()edk2/QcomModulePkg/Application/LinuxLoader/LinuxLoader.c DEBUG ((EFI_D_ERROR, "LoadImageAndAu…

docker部署redis后,修改配置文件的requirepass后无效

解决方案 执行docker run命令时不要使用参数–requirepass docker部署redis流程&#xff08;问题复现&#xff09; 1. 启动redis容器 在服务器docker运行时&#xff0c;执行下列命令。&#xff08;会自动在远程仓库下载镜像&#xff09; redis: docker run \ --restartalw…

高等数学【合集】

文章目录极限计算求导计算极限计算 第一步:先看x→value确定类型第一步:先看x \rightarrow value确定类型第一步:先看x→value确定类型 7种未定型:∞∞,00,1∞,0∞,∞0,00,∞−∞7种未定型: \frac{\infty}{\infty},\frac{0}{0},1^{\infty},0^{\infty},\infty^0,0^0,\infty-\inf…

win10开机后桌面无图标问题解决办法

本篇文章主要讲解win10下桌面无图标的问题解决办法。 日期&#xff1a;2023年1月21日 作者&#xff1a;任聪聪 主要原因&#xff1a; 这个问题的原因是资源管理器或者注册表中有垃圾注册数据导致&#xff0c;实际上和显卡没有任何关系&#xff0c;但有些情况是由于驱动问题导致…

OSPF 特殊区域介绍、Stub、Totally Stub、NSSA、Totally NSSA

1.1.0 路由 OSPF 特殊区域介绍、Stub、Totally Stub、NSSA、Totally NSSA 特殊区域的产生和注意事项 产生&#xff1a;OSPF通过划分区域减小网络内路由器的LSDB的规模。对于那些位于AS边界的非骨干区域如果该设备是较为低端的路由器&#xff0c;则无法承受过多的路由条目。为此…

前端学习第一阶段:1-4章

学习总结&#xff1a;前四章学习总体来说不太难理解&#xff0c;如果时间宽裕&#xff0c;一天之内可以学完。 第一章 前端就业班课程导学 第二章 HTML5 CSS3课前导学 第三章 VSCode编辑器的使用 第四章 HTML 4-1 HTML初识 List item 01-基础班学习路线 List item 02-HTML简…

【Linux_】环境变量

【Linux_】环境变量 心有所向&#xff0c;日复一日&#xff0c;必有精进专栏&#xff1a;《Linux_》作者&#xff1a;沂沐沐目录 【Linux_】环境变量 什么是环境变量 常见变量 查看环境变量方法 环境变量相关的命令 通过系统调用获取或设置环境变量 环境变量通常是具有全…

代码随想录算法训练营第22天 二叉树 java :235. 二叉树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

文章目录LeetCode 236. 二叉树的最近公共祖先题目讲解思路LeetCode 701.二叉搜索树中的插入操作题目讲解思路LeetCode 450.删除二叉搜索树中的节点题目讲解思路示图总结既然还是要生活&#xff0c;那么就学会主宰生活LeetCode 236. 二叉树的最近公共祖先 题目讲解 思路 求最小…