当前位置: 首页 > news >正文

c语言函数(详解)

目录

前言

一、函数的基本概念和作用

二、函数的声明和定义

三、函数参数的传递方式

四、函数的递归

五、函数指针

总结


前言

本文主要讲解了c语言函数方面的内容


    • 函数的定义和调用
    • 函数的返回值和参数
    • 函数的作用域和生命周期
  1. 函数的声明和定义

    • 函数声明和函数定义的区别
    • 函数声明的语法规则
    • 函数定义的语法规则
  2. 函数参数的传递方式

    • 值传递
    • 引用传递
    • 指针传递
  3. 函数的递归

    • 递归的基本概念和原理
    • 递归函数的编写和调用
    • 递归和迭代的比较
  4. 函数的重载

    • 函数重载的概念和作用
    • 函数重载的语法规则
    • 函数重载的实际应用
  5. 内联函数

    • 内联函数的概念和作用
    • 内联函数的使用方法
    • 内联函数的优缺点
  6. 函数指针

    • 函数指针的概念和作用
    • 函数指针的声明和使用
    • 函数指针和回调函数的应用
  7. 变长参数函数

    • 变长参数函数的概念和作用
    • 变长参数函数的声明和使用
    • 变长参数函数的应用案例
  8. 常见的标准函数库

    • 数学函数库
    • 字符串处理函数库
    • 文件操作函数库
    • 时间和日期函数库
  9. 错误处理和异常处理

    • 错误处理的概念和目的
    • 错误处理的方法和技巧
    • 异常处理的概念和使用方法

一、函数的基本概念和作用

      函数是一段封装了特定功能的代码块。它们用来组织和重用代码,使程序更易于理解和维护。函数可以接受输入参数,并且可以返回一个值。

        函数的定义是指我们编写的函数代码块,它包括函数名、参数列表、返回类型和函数体。函数名用于标识函数,在调用函数时使用。参数列表指定了函数接受的输入参数的类型和名称。返回类型指定了函数返回值的类型。函数体是实际执行的代码。

       函数的调用是指使用函数名和传递给函数的参数列表来执行函数。调用函数时,程序将跳转到函数体,并执行其中的代码。函数执行完毕后,程序将返回到函数调用的位置继续执行。

         函数的返回值用于将结果从函数传递回调用函数的位置。返回值的类型必须与函数的返回类型相符。在函数体中,我们可以使用关键字return来返回一个值。调用函数时,我们可以将返回值赋值给一个变量,或者直接使用返回值。

       函数的参数是在调用函数时传递给函数的值。参数可以是原始数据类型,也可以是对象或数组等复合数据类型。参数在函数体内部作为变量使用。函数可以有多个参数,它们以逗号分隔。

       函数的作用域是指函数体内部定义的变量的可见范围。函数体内部可以访问外部定义的变量,但是外部不能访问函数体内部定义的变量。函数的作用域可以是全局的,也可以是局部的。

       函数的生命周期是指函数在程序中存在的时间段。函数在定义时创建,调用时执行,执行完毕后销毁。函数的生命周期可以由函数的作用域和调用方式决定。

二、函数的声明和定义

       函数的声明和定义指的是在程序中告诉编译器函数的名称、返回类型和参数列表以便在程序中使用该函数的过程。

       函数声明是在程序中使用函数之前告诉编译器函数的名称、返回类型和参数列表。函数声明只是告诉编译器函数的存在,并没有具体的函数体。

        函数定义是在程序中具体实现函数的功能,包括函数的函数体。函数定义提供了函数的实际操作。

函数声明的语法规则: 返回类型 函数名(参数列表);

函数定义的语法规则: 返回类型 函数名(参数列表) { // 函数体 // 函数的实际操作 }

例如,下面是一个函数声明和定义的例子:

函数声明: int add(int a, int b);函数定义: int add(int a, int b) { return a + b; }

在函数声明中,告诉编译器有一个函数叫做add,返回类型是int,有两个int类型的参数a和b。

在函数定义中,实现了add函数的具体功能,计算a和b的和,并将结果返回。

三、函数参数的传递方式

函数参数的传递方式有三种:

  1. 值传递:将参数的值复制一份传递给函数,在函数内部对参数进行修改不会影响到外部的变量。

  2. 引用传递:将参数的引用(内存地址)传递给函数,函数可以直接修改参数所指向的变量的值,从而影响到外部的变量。

  3. 指针传递:将参数的指针(地址)传递给函数,函数可以通过指针访问并修改参数所指向的变量的值,从而影响到外部的变量。

代码演示:

值传递: #include <stdio.h>void changeValue(int num) { num = 10; }int main() { int num = 5; changeValue(num); printf("%d\n", num); // 打印结果是5,num在changeValue函数中的修改不会影响到外部的变量 return 0; }引用传递: #include <stdio.h>void changeValue(int* numPtr) { *numPtr = 10; }int main() { int num = 5; changeValue(&num); // 传递num的地址 printf("%d\n", num); // 打印结果是10,changeValue函数内部修改了num的值 return 0; }指针传递: #include <stdio.h>void changeValue(int* numPtr) { *numPtr = 10; }int main() { int num = 5; int* ptr = # // 声明一个指向int类型的指针,存储num的地址 changeValue(ptr); // 传递指针ptr的值 printf("%d\n", num); // 打印结果是10,changeValue函数内部通过指针修改了num的值 return 0; }
四、函数的递归

       递归的基本概念和原理: 递归是指一个函数调用自己或者调用其他函数时,该函数又调用该函数的过程。它是一种解决问题的有效方法,它把一个大问题分解成了一个或多个相同或相似的子问题,然后递归地解决这些子问题,最后合并得到原问题的解。

        递归函数的编写和调用: 编写递归函数时,需要定义递归函数的终止条件,即递归的基本情况。当递归函数的输入满足终止条件时,递归停止,返回结果。否则,递归函数调用自身,并将问题规模缩小,直到满足终止条件。

       递归和迭代的比较: 递归和迭代都是循环的方法,但它们的实现方式不同。递归是通过函数的调用来实现循环,而迭代是通过循环结构来实现循环。递归的代码通常比迭代的代码简洁,但它的效率较低,因为每次递归都需要调用函数并保存调用的状态。

代码例子:

#include <stdio.h>int factorial(int n){// 终止条件if(n == 0){return 1;}// 递归调用return n * factorial(n-1);
}int main(){int n = 5;int result = factorial(n);printf("Factorial of %d is %d\n", n, result);return 0;
}

       这段的代码中,factorial函数通过递归的方式计算阶乘。当输入为0时,递归停止,返回结果1。否则,递归调用函数,将问题规模缩小,并与当前的n相乘。最后,递归函数返回结果,得到阶乘的结果。在main函数中,我们调用factorial函数来计算5的阶乘,并打印结果。输出结果为:Factorial of 5 is 120。

五、函数指针

   

      函数指针是指向函数的指针变量。它可以指向特定参数和返回类型的函数,并且可以通过函数指针来调用该函数。函数指针可以被用来作为函数的参数、返回值或者在运行时动态调用函数。

函数指针的声明使用以下语法:

返回类型 (*指针变量名)(参数列表);

其中,指针变量名可以是任意合法的标识符,它指向具有返回类型和参数列表的函数。

函数指针的使用可以通过以下步骤进行:

  1. 声明函数指针,并指定它所指向的函数的返回类型和参数列表。
  2. 将函数的地址赋值给函数指针。
  3. 通过函数指针来调用函数。

代码演示:

#include <stdio.h>int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}int main() {int (*operation)(int, int); // 声明函数指针int result;operation = add; // 将函数地址赋给函数指针result = operation(10, 5); // 通过函数指针调用函数printf("Addition result: %d\n", result);operation = subtract; // 将另一个函数地址赋给函数指针result = operation(10, 5); // 再次通过函数指针调用函数printf("Subtraction result: %d\n", result);return 0;
}

       函数指针和回调函数的应用是在某个函数中传递另一个函数的指针作为参数,然后在需要的时候调用这个函数指针。这种机制可以实现灵活的函数调用,特别适用于事件驱动的程序设计。

代码示例:

#include <stdio.h>// 回调函数的定义
void message() {printf("Hello, World!\n");
}// 接受函数指针作为参数的函数
void printMessage(void (*callback)()) {callback();
}int main() {// 将回调函数的地址传递给函数指针printMessage(message);return 0;
}

       以上代码中,printMessage函数接受一个函数指针作为参数,然后在需要的时候调用这个函数指针。在main函数中,将message函数的地址作为参数传递给printMessage函数,从而实现了回调函数的功能。


总结

 以上就是c语言函数的内容啦,后续我会带来更多实用的内容,感兴趣的可以点个赞支持一下!

相关文章:

c语言函数(详解)

目录 前言 一、函数的基本概念和作用 二、函数的声明和定义 三、函数参数的传递方式 四、函数的递归 五、函数指针 总结 前言 本文主要讲解了c语言函数方面的内容 函数的定义和调用函数的返回值和参数函数的作用域和生命周期 函数的声明和定义 函数声明和函数定义的区别函数声…...

为AI聊天工具添加一个知识系统 之70 详细设计 之11 维度运动控制的应用:上下文受控的自然语言

本文要点 要点 前面我们 讨论了 “维度”及其运动控制原理 以及 维度控制 如何在中台微服务架构中撑起了“架构师”角色的一片天。下面我们从 “维度”运动控制的一个典型应用场景&#xff1a;受控的自然语言 ”开始讨论。 拼块文字型风格: 维度运动控制下的受控自然语言…...

ios打包:uuid与udid

ios的uuid与udid混乱的网上信息 新人开发ios&#xff0c;发现uuid和udid在网上有很多帖子里是混淆的&#xff0c;比如百度下&#xff0c;就会说&#xff1a; 在iOS中使用UUID&#xff08;通用唯一识别码&#xff09;作为永久签名&#xff0c;通常是指生成一个唯一标识&#xf…...

数组,对象解构,forEach方法,filter方法

数组解构 对象结构 遍历数组 forEach方法 筛选数组 filter方法 渲染商品案例 forEach遍历数组&#xff0c;能得到每个数组中的数据&#xff0c;item是对象中的每个元素 将遍历的数组中每个对象 加到 str 中 将 str 字符串中的 8 个 div 添加到 list盒子中 对象解构并渲染 综…...

PSPNet

文章目录 摘要Abstract1. 引言2. 框架2.1 金字塔池化模块2.2 特征提取器的监督2.3 训练细节 3. 创新点和不足3.1 创新点3.2 不足 参考总结 摘要 PSPNet是一个改进了FCN-8s缺点的语义分割模型&#xff0c;它解决了FCN-8s的缺点——分割不够精细以及没有考虑上下文信息。PSPNet的…...

论文阅读的附录(七):Understanding Diffusion Models: A Unified Perspective(二):公式46的推导

Understanding Diffusion Models: A Unified Perspective&#xff08;二&#xff09;&#xff1a;公式46的推导 文章概括要推导的公式1. 条件概率的定义2. 联合分布的分解2.1 联合分布的定义2.2 为什么可以这样分解&#xff1f;2.3 具体意义 3. 分母的分解&#xff1a;边际化规…...

BGP分解实验·12——配置路由反射器

当一个AS包含多个iBGP对等体时&#xff0c;路由反射器&#xff08;Route-Reflector&#xff09;非常有用&#xff0c;因为相对于iBGP路由反射器指定的客户端只需要和路由反射器建立邻居关系&#xff0c;从而降低了iBGP全互连的连接数量。路由反射器&#xff08;RR&#xff09;和…...

PCIe 个人理解专栏——【2】LTSSM(Link Training and Status State Machine)

前言&#xff1a; 链路训练和状况状态机LTSSM&#xff08;Link Training and Status State Machine&#xff09;是整个链路训练和运行中状态的状态转换逻辑关系图&#xff0c;总共有11个状态。 正文&#xff1a; 包括检测&#xff08;Detect&#xff09;&#xff0c;轮询&…...

cmake 编译QT之JKQtPlotter-4.0.3

cmake 编译 JKQtPlotter-4.0.3 1.下载源码 源码地址&#xff1a;https://github.com/jkriege2/JKQtPlotter 2.编译 mkdir build cd buildDCMAKE_PREFIX_PATH指编译器目录 D:\ProgramFiles\cmake-3.25.0-rc1-windows-i386\bin\cmake.exe -G "Visual Studio 16 2019&qu…...

【C】memory 详解

<memory.h> 是一个 C 标准库头文件&#xff0c;提供了一组内存管理函数&#xff0c;用于分配、释放和操作动态内存。这些函数主要操作的是未初始化的内存块&#xff0c;是早期 C 编程中常用的内存操作工具。 尽管在现代 C 编程中更推荐使用<cstring>或<memory&…...

Python 爬虫 - Selenium 框架

Python 爬虫 - Selenium 框架 安装安装 Selenium安装 WebDriver 操作浏览器打开浏览器普通方式加载配置方式Headless 方式 设置浏览器窗口最大化显示最小化显示自定义大小 前进后退前进后退 元素定位根据 id 定位根据 name 定位根据 class 定位根据标签名定位使用 CSS 定位使用…...

mysql的having语句

MySQL的HAVING语句用于在GROUP BY子句对数据进行分组后&#xff0c;过滤满足特定条件的组。与WHERE子句不同&#xff0c;HAVING子句可以在过滤条件中使用聚合函数&#xff0c;而WHERE子句则不能。通常&#xff0c;HAVING子句与GROUP BY子句一起使用&#xff0c;以实现对分组数据…...

华为数据之道-读书笔记

内容简介 关键字 数字化生产 已经成为普遍的商业模式&#xff0c;其本质是以数据为处理对象&#xff0c;以ICT平台为生产工具&#xff0c;以软件为载体&#xff0c;以服务为目的的生产过程。 信息与通信技术平台&#xff08;Information and Communication Technology Platf…...

CDN、源站与边缘网络

什么是“源站” 源服务器 源服务器的目的是处理和响应来自互联网客户端的传入请求。源服务器的概念通常与边缘服务器或缓存服务器的概念结合使用。源服务器的核心是一台运行一个或多个程序的计算机&#xff0c;这些程序旨在侦听和处理传入的客户端请求。源服务器可以承担为网…...

工业相机 SDK 二次开发-Sherlock插件

本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一&#xff0e;环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹&#xff0c;根据 Sherlock 版本找到…...

FlinkSql使用中rank/dense_rank函数报错空指针

问题描述 在flink1.16(甚至以前的版本)中&#xff0c;使用rank()或者dense_rank()进行排序时&#xff0c;某些场景会导致报错空指针NPE(NullPointerError) 报错内容如下 该报错没有行号/错误位置&#xff0c;无法排查 现状 目前已经确认为bug&#xff0c;根据github上的PR日…...

VS C++ 配置OPENCV环境

VS C 配置OPENCV环境 1.下载opencv2.安装环境3.opencv环境4.VS配置opencv环境5.EXE执行文件路径的环境lib和dll需要根据是debug还是release环境来区分使用哪个 6.Windows环境 1.下载opencv 链接: link 2.安装环境 双击运行即可 3.opencv环境 include文件路径:opencv\build\…...

【SpringSecurity】基本开发流程

文章目录 概要整体架构流程实现流程1、编写各种Handler2 、AccessToken处理器3、定义AuthenticationFilter 继承 OncePerRequestFilter &#xff08;OncePerRequestFilter是Spring提供的一个过滤器基类&#xff0c;它确保了在一次完整的HTTP请求中&#xff0c;无论请求经过多少…...

Redis实战(黑马点评)——关于缓存(缓存更新策略、缓存穿透、缓存雪崩、缓存击穿、Redis工具)

redis实现查询缓存的业务逻辑 service层实现 Overridepublic Result queryById(Long id) {String key CACHE_SHOP_KEY id;// 现查询redis内有没有数据String shopJson (String) redisTemplate.opsForValue().get(key);if(StrUtil.isNotBlank(shopJson)){ // 如果redis的数…...

ChatGPT从数据分析到内容写作建议相关的46个提示词分享!

在当今快节奏的学术环境中&#xff0c;研究人员面临着海量的信息和复杂的研究任务。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;像ChatGPT这样的先进工具为科研人员提供了强大的支持。今天就让我们一起探索如何利用ChatGPT提升研究效率进一步优化研究流程。 ChatG…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...