【C++基础】8. 函数

news2024/10/12 0:33:02

文章目录

  • 【 1. 函数的定义 】
  • 【 2. 函数声明 】
  • 【 3. 调用函数 】
  • 【 4. 函数参数 】
    • 4.1 传值调用
    • 4.2 指针调用
    • 4.3 引用调用
  • 【 5. 形参默认值 】
  • 【 6. lambda函数 】

  • 函数是一组一起执行一个任务的语句。每个 C++ 程序都至少有一个函数,即主函数 main() 。可以把代码划分到不同的函数中便于识别。
  • 函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。
  • C++ 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。
  • 函数还有很多叫法,比如 方法子例程程序,等等。

【 1. 函数的定义 】

  • C++ 中的函数定义的一般形式如下:
return_type function_name( parameter list )
{
   body of the function
}

在 C++ 中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:

  • 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
  • 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
  • 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
  • 函数主体:函数主体包含一组定义函数执行任务的语句。
  • 实例
// 函数返回两个数中较大的那个数
int max(int num1, int num2) 
{
   // 局部变量声明
   int result;

   if (num1 > num2)
      result = num1;
   else
      result = num2;

   return result; 
}

【 2. 函数声明 】

  • 函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
  • 函数声明包括以下几个部分:
return_type function_name( parameter list );
  • 实例:针对上面定义的函数 max(),以下是函数声明:
int max(int num1, int num2);
  • 在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:
int max(int, int);
  • 当在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,应该在调用函数的文件顶部声明函数。

【 3. 调用函数 】

  • 创建 C++ 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。
  • 当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。
  • 调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。
  • 实例
#include <iostream>
using namespace std;

// 函数声明
int max(int num1, int num2);

int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;
   int ret;

   // 调用函数来获取最大值
   ret = max(a, b);

   cout << "Max value is : " << ret << endl;

   return 0;
}

// 函数返回两个数中较大的那个数
int max(int num1, int num2) 
{
   // 局部变量声明
   int result;

   if (num1 > num2)
      result = num1;
   else
      result = num2;

   return result; 
}

在这里插入图片描述

【 4. 函数参数 】

  • 如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的 形式参数 ,简称 形参。形参 就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。
  • 默认情况下,C++ 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的参数。之前提到的实例,调用 max() 函数时,使用了相同的方法。
调用类型描述
传值调用该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
指针调用该方法把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
引用调用该方法把参数的引用复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。

4.1 传值调用

  • 向函数传递参数的传值调用方法,把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
  • 默认情况下,C++ 使用传值调用方法来传递参数。一般来说,这意味着函数内的代码不会改变用于调用函数的实际参数。函数 swap() 定义如下:
#include <iostream>
using namespace std;

// 函数声明
void swap(int x, int y);

int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;

   cout << "交换前,a 的值:" << a << endl;
   cout << "交换前,b 的值:" << b << endl;

   // 调用函数来交换值
   swap(a, b);

   cout << "交换后,a 的值:" << a << endl;
   cout << "交换后,b 的值:" << b << endl;

   return 0;
}
// 函数定义
void swap(int x, int y)
{
   int temp;

   temp = x; /* 保存 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 x 赋值给 y */

   return;
}

在这里插入图片描述

4.2 指针调用

  • 向函数传递参数的指针调用方法,把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
  • 按指针传递值,参数指针被传递给函数,就像传递其他值给函数一样。因此相应地,在下面的函数 swap() 中,您需要声明函数参数为指针类型,该函数用于交换参数所指向的两个整数变量的值。
#include <iostream>
using namespace std;

// 函数声明
void swap(int *x, int *y);

int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;

   cout << "交换前,a 的值:" << a << endl;
   cout << "交换前,b 的值:" << b << endl;

   /* 调用函数来交换值
    * &a 表示指向 a 的指针,即变量 a 的地址 
    * &b 表示指向 b 的指针,即变量 b 的地址 
    */
   swap(&a, &b);

   cout << "交换后,a 的值:" << a << endl;
   cout << "交换后,b 的值:" << b << endl;

   return 0;
}
// 函数定义
void swap(int *x, int *y)
{
   int temp;
   temp = *x;    /* 保存地址 x 的值 */
   *x = *y;        /* 把 y 赋值给 x */
   *y = temp;    /* 把 x 赋值给 y */

   return;
}

在这里插入图片描述

4.3 引用调用

  • 向函数传递参数的引用调用方法,把引用的地址复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
  • 按引用传递值,参数引用被传递给函数,就像传递其他值给函数一样。因此相应地,在下面的函数 swap() 中,您需要声明函数参数为引用类型,该函数用于交换参数所指向的两个整数变量的值。
#include <iostream>
using namespace std;

// 函数声明
void swap(int &x, int &y);

int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;

   cout << "交换前,a 的值:" << a << endl;
   cout << "交换前,b 的值:" << b << endl;

   /* 调用函数来交换值 */
   swap(a, b);

   cout << "交换后,a 的值:" << a << endl;
   cout << "交换后,b 的值:" << b << endl;

   return 0;
}
// 函数定义
void swap(int &x, int &y)
{
   int temp;
   temp = x; /* 保存地址 x 的值 */
   x = y;    /* 把 y 赋值给 x */
   y = temp; /* 把 x 赋值给 y  */

   return;
}

在这里插入图片描述

【 5. 形参默认值 】

  • 当=定义一个函数,您可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实际参数的值留空,则使用这个默认值。
  • 这是通过在函数定义中使用赋值运算符来为参数赋值的。调用函数时,如果未传递参数的值,则会使用默认值,如果指定了值,则会忽略默认值,使用传递的值。请看下面的实例:
#include <iostream>
using namespace std;

int sum(int a, int b=20)
{
  int result;

  result = a + b;

  return (result);
}

int main ()
{
   // 局部变量声明
   int a = 100;
   int b = 200;
   int result;

   // 调用函数来添加值
   result = sum(a, b);
   cout << "Total value is :" << result << endl;

   // 再次调用函数
   result = sum(a);
   cout << "Total value is :" << result << endl;

   return 0;
}

在这里插入图片描述

【 6. lambda函数 】

  • C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。
  • Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。
  • Lambda 表达式本质上与函数声明非常类似。Lambda 表达式具体形式如下:
[capture](parameters)->return-type{body}
  • 实例
[](int x, int y){ return x < y ; }
[capture](parameters){body} //如果 lambda 函数没有传回值(例如 void),其返回类型可被完全忽略,例如:[]{ ++global_x; }
[](int x, int y) -> int { int z = x + y; return z + x; } // 明确指定返回类型

  • 在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++变量传递有传值和传引用的区别。可以通过前面的[]来指定:
[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。

对于[=]或[&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[]的形式,如果要使用 this 指针,必须显式传入:

[this]() { this->someFunc(); }();

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

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

相关文章

Fiddler工具使用汇总

Fiddler工作原理 fiddler作为一个代理服务器&#xff0c;跟浏览器建立连接之后&#xff0c;浏览器像目标服务器发送的请求都会经过fiddler代理&#xff0c;所以fiddler可以捕获到http&#xff08;s&#xff09;请求&#xff0c;从而可以解释、分析、甚至重写发出去的http&…

[De1CTF 2019]SSRF Me | BUUCTF

根据题目名我们知道这是一道SSRF的题目 它允许攻击者在受害服务器上发起未经授权的网络请求 分析 在buuctf上有一个提示 也就是说flag在 网站的flag.txt 访问主页 很明显是段flask代码 格式化后 from flask import Flask, request # 导入Flask和request模块 import sock…

设备管理系统的优势是什么?设备管理系统对企业运营管理有什么帮助?

传统的设备报修维护方式存在一些问题&#xff0c;例如指派传递速度慢和故障信息不准确等。然而&#xff0c;使用设备管理系统就可以轻松地解决这些问题&#xff0c;并且报修全流程只需短短的30秒。设备管理系统具有许多优势&#xff0c;首先它支持多种渠道的报修&#xff0c;包…

《TCP/IP网络编程》阅读笔记--进程间通信

目录 1--进程间通信 2--pipe()函数 3--代码实例 3-1--pipe1.c 3-2--pipe2.c 3-3--pipe3.c 3-4--保存信息的回声服务器端 1--进程间通信 为了实现进程间通信&#xff0c;使得两个不同的进程间可以交换数据&#xff0c;操作系统必须提供两个进程可以同时访问的内存空间&am…

初出茅庐的小李博客之数制与编码知识

模拟量与数字量&#xff1a; 数字量和模拟量是两种用于表示和处理不同类型数据的概念&#xff0c;常见于电子和计算机系统中。它们在信号处理、传感器技术、通信和控制系统中有不同的应用。 1. 数字量&#xff08;Digital&#xff09;&#xff1a; 数字量是离散的&#xff0…

06文本搜索工具——grep以及正则表达式

一、grep工具的使用 可以通过返回状态码判断文件有没有这个数据&#xff0c;有状态码为0&#xff0c;没有为1。文件不存在状态码为2 -o&#xff1a; 二、正则表达式 1、基本正则表达式 .为匹配任意字符&#xff0c;..两个两个匹配任意字符&#xff0c;...三个三个匹配任意字符 …

群拼团接龙小程序源码功能和开发

针对微信群开发的拼团接龙小程序&#xff0c;有点快团团的味道。是做私域非常不错的一款小程序。 小程序基于Uniapp开发&#xff0c;目前适配了微信小程序。 接龙&#xff1a; 在小程序中可以创建自定义接龙&#xff0c;不需要复杂的申请流程。 商品发布&#xff1a; 接龙…

模板测试和深度测试在cocoscreator中的应用

模板测试(Stencil Test)&#xff1a; 当片段着色器处理完一个片段之后&#xff0c;模板测试(Stencil Test)会开始执行&#xff0c;和深度测试一样&#xff0c;它也可能会丢弃片段。接下来&#xff0c;被保留的片段会进入深度测试&#xff0c;它可能会丢弃更多的片段。模板测试…

React 开发一个移动端项目(1)

技术栈&#xff1a; 项目搭建&#xff1a;React 官方脚手架 create-react-appreact hooks状态管理&#xff1a;redux 、 redux-thunkUI 组件库&#xff1a;antd-mobileajax请求库&#xff1a;axios路由&#xff1a;react-router-dom 以及 historyCSS 预编译器&#xff1a;sass…

Web开发后端总结

Web后端开发现在基本上都是基于标准的三层架构进行开发的&#xff0c;在三层架构当中&#xff0c;Controller控制器层 - 负责接收请求响应数据&#xff0c;Service - 业务层负责具体的业务逻辑处理&#xff0c;而Dao - 数据访问层也叫持久层&#xff0c;就是用来处理数据访问操…

第9节-PhotoShop基础课程-移动抓手缩放工具

文章目录 前言1. 移动工具1.移动工具1.自动选择&#xff08;图层和组&#xff09;2.显示变换控件 &#xff08;Shift 变换/ Ctrl 变换&#xff09;3.自由变换 Ctrl T &#xff08;Shift 变换/ Ctrl 变换&#xff09;4.对齐功能 2.画板工具 V1. 创建画板并作图2.导出画板 2.路…

【strcpy函数和strncpy函数的对比与模拟实现】

strcpy函数和strncpy函数的对比与模拟实现 1.strcpy函数介绍 资源来源于cplusplus网站 大致意思就是&#xff1a; 它的作用为&#xff1a; 将一个字符串复制到另一块空间地址中 的函数&#xff0c;‘\0’是停止拷贝的终止条件&#xff0c;同时也会将 ‘\0’ 也复制到目标空间…

redis集群最少使用三个主节点和使用16384个槽以及主节点数量不超过1000的原因

目录 集群最少三个主节点的原因 为什么是三个? 为什么是奇数? 16384个槽和1000个主节点 集群最少三个主节点的原因 https://redis.io/docs/management/scaling/ 官网建议&#xff0c;搭建 redis 集群最少三主三从。 但是这么做是出于什么考虑呢&#xff1f; https://workt…

02深度学习目标检测方法介绍-传统

一、目标学习的检测方法变迁及对比 “目标检测“是当前计算机视觉和机器学习领域的研究热点。从Viola-Jones Detector、DPM等冷兵器时代的智慧到当今RCNN、YOLO等深度学习土壤孕育下的GPU暴力美学&#xff0c;整个目标检测的发展可谓是计算机视觉领域的一部浓缩史。整个目标检测…

Python实操 PDF自动识别并提取Excel文件

最近几天&#xff0c;paddleOCR开发了新的功能&#xff0c;通过将图片中的表格提取出来&#xff0c;效果还不错&#xff0c;今天&#xff0c;作者按照步骤测试了一波。 首先&#xff0c;讲下这个工具是干什么用的&#xff1a;它的功能主要是针对一张完整的PDF图片&#xff0c;可…

EasyAVFilter代码示例之将摄像机RTSP流转成RTMP推流输出

以下是一套完整的RTSP流转RTMP推流功能的开发源码&#xff0c;就简简单单几行代码&#xff0c;就可以完成原来ffmpeg很复杂的调用流程&#xff0c;而且还可以集成在自己的应用程序中调用&#xff0c;不需要再单独一个ffmpeg的进程来调用&#xff0c;方法很简单&#xff1a; #i…

spring中的@Configuration配置类和@Component

在Spring的开发工作中&#xff0c;基本都会使用配置注解&#xff0c;尤其以Component及Configuration为主&#xff0c;当然在Spring中还可以使用其他的注解来标注一个类为配置类&#xff0c;这是广义上的配置类概念&#xff0c;但是这里我们只讨论Component和Configuration&…

盲盒小程序开发方案

盲盒游戏作为一种富有趣味性和收藏价的虚拟盲盒产品&#xff0c;近年来在游戏市场中备受关注。本文将深入探讨盲盒游戏的开发方案&#xff0c;从市场趋势分析、用户体验设计、商业模式选择等多个维度&#xff0c;为开发者提供业且有深度的思考&#xff0c;以帮助他们在盲盒游戏…

容器编排学习(八)卷的概述与存储卷管理

一 卷 1 容器化带来的问题 容器中的文件在磁盘上是临时存放的&#xff0c;这给容器中运行的重要的应用程序带来一些问题 问题1&#xff1a;当容器崩溃或重启的时候&#xff0c;kubelet 会以干净的状态(镜像的状态)重启容器&#xff0c;容器内的历史数据会丢失 问题2&…

upload-labs1-17思路

1 直接写一个php文件测试一下&#xff0c;发现弹窗不让上传 原理很简单&#xff0c;就是把后缀名拿出来过滤一遍&#xff0c;而白名单就是弹窗的这三个 解决方法&#xff1a; 因为这是在前端防御的一个手段&#xff0c;所以直接在浏览器设置上禁用js就行了&#xff1a; 也可…