C++函数概念解析(1)

函数

一个典型的函数包含以下几个部分

  1. 返回类型
  2. 函数名称
  3. 一个或者多个形参
  4. 函数体
举例如下
int fact(int ival)
{int ret=1;while(val>1)ret*=val--;//这里先乘再减return ret;
}
函数名fact
形参ival
实参ret
返回类型int

每当我们定义出一个函数,我们不能直接使用它,还得提供一个数值去调用它

int main()
{int j=fact(5);cout<<"5! is "<<j<<endl;return 0;
}

执行函数首先隐式初始化,首先创建为一个叫ival的int类型变量,然后将它初始化为调用时所用到的形式参数

对于基元类型,复制初始化与直接初始化完全相同。对于具有构造函数的更复杂类型,除非复制构造函数被标记为显式,否则复制初始化与调用值在=”之后的复制构造函数相同。我们一般可以认为拷贝初始化就是直接初始化。

形参与实参

实参是形参的初始值。正如上文所言,形参最开始是没有值的,只是一个符号,在初始化开始之后,形参依次被其对应的实参初始化,但是编译器却并没有这种对应关系,无需按照顺序,可以直接求值。

函数的形参列表

形参列表可以为空,但不可以省略:

void f1()//隐式定义
void f2(void)//显式定义

为空时用void表示函数形参列表为空,是为了与C语言兼容,可以表示多个形参,中间使用逗号隔开,就算两个形参的类型一样,也得把两个类型都写出来:

int f3(int v1,int v2)
函数的返回类型

大多数函数的返回类型都是各种类型值,也有少部分是返回void,或者返回函数或者数组的指针

关于局部对象

在C++中,名字有作用域,对象有生命周期

作用域作用域(scope,或译作有效范围)是名字(name)与实体(entity)的绑定(binding)保持有效的那部分计算机程序。不同的编程语言可能有不同的作用域和名字解析。而同一语言内也可能存在多种作用域,随实体的类型变化而不同。作用域类别影响变量的绑定方式,根据语言使用静态作用域还是动态作用域变量的取值可能会有不同的结果。

生命周期:对象在程序执行过程中存在的时间

局部对象主要包含:

  1. 自动对象
  2. 局部静态对象
自动对象

一个函数在执行过程中,它的控制路径经过变量自定义语句时创建该对象,当到达定义所在的末尾时销毁该对象,整个过程期间存在的对象便称为自动对象。这就导致如果我们在用传递给函数的实参初始化的形参对应的自动对象,如果变量本来就有初始值,就是用这个初始值初始化,若无初始值,便开始默认初始化

局部静态对象

有些时候这个这个变量的生命周期贯穿函数以及之后的调用时间,通俗来说就是这个变量作用很大,单单在自己的生命周期里面调用还不够,需要多次调用,这样我们就可以把它定义为static对象,它的销毁是在程序终止的时候发生的

#include<iostream>
using namespace std;
size_t count_calls()
{static size_t ctr=0;return ++ctr;
}
int main()
{for(size_t i=0;i!=10;++i){cout<<count_calls()<<endl;}return 0;
}
关于函数声明

函数在使用前必须要声明,它只能定义一次,却可以声明多次

void print(vector<int>::const_iterator beg,vector<int>::const_iterator end)

我们在编写程序的时候,一般会把声明放在主函数前面,函数的定义放在主函数后面,调用则在主函数里面进行,这样做的目的是为了让程序更加的规范化,否则你就得在一大堆函数定义里面去找函数声明了

更加复杂的情况

C++支持分离式编译,定义和声明可以不在同一个文件中,这种情况下如果我们要编译我们必须告诉编译器我们的文件在哪里

指针形参

指针执行拷贝操作的时候,拷贝的是指针的值,拷贝之后两个指针是不同的两个指针,指针可以使得我们间接的访问所指的对象,通过对指针值得修改可以间接的改变指针指向的对象的值

#include<iostream>
using namespace std;
int main()
{int n=0,i=42;int *p=&n,*q=&i;*p=42;p=q;cout<<"p is "<<p<<endl;cout<<"i is "<<i<<endl;cout<<"n is "<<n<<endl;
}

输出如下:

p is 0x61fe08
i is 42
n is 42
避免引用拷贝

当容器对象比较大或者拷贝大类型对象的时候,拷贝被认为是一种低效的操作,甚至IO类型等个别类型压根不支持拷贝操作。我们可以使用引用形参来来完成这个操作。

bool shorter (const string &s1,const string &s2)
{return s1.size()<s2.size()
}
const形参和实参
int main()
{const int ci=42;int i=ci;//拷贝的时候忽略了它是顶层ciint *const p=&i;*p=0;cout<<i<<endl;
}

使用实参初始化会忽略掉顶层const,这时把值传给它的常量对象或者非常量对象都可以

void fcn(const int i)//可以读取i,但是不能修改i
void fcn(int i)//错误,重复定义了fcn(int)

在参数传递的时候要注意:

  1. 不能使用指向const int的对象初始化int
  2. 不能把普通引用绑定到const对象上
把函数不会改变的形参定义成普通引用是一种常见错误

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

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

相关文章

棋牌类游戏算法–牌分类_快速分类–三向和双枢轴

棋牌类游戏算法–牌分类毫无疑问&#xff0c;Quicksort被认为是本世纪最重要的算法之一&#xff0c;并且它是许多语言的事实上的系统排序&#xff0c;包括Java中的Arrays.sort 。 那么&#xff0c;quicksort有何新功能&#xff1f; 好吧&#xff0c;除了我刚刚&#xff08;在J…

真实收货地址大全2016_中国古典诗词大全汇集了诗经、唐诗、宋词、元曲以及纳兰词,12册精美套装。...

↑点击上方“诗画天地”关注我们诗词也如人生&#xff0c;你驻足便是驿站&#xff0c;你前行便是风景。任由时光无尽幻变&#xff0c;回眸处星孤月洁&#xff0c;阅读诗词能让人生变得清明透彻&#xff0c;仿佛与古人走在同一条道上&#xff0c;俯仰之间&#xff0c;人生皆是诗…

C++函数概念解析(2)

数组形参 我们为函数传递一个数组时&#xff0c;实际传递的是这个数组的指针 void print(const int*); void print(const int[]);//函数的意图是作用于一个数组 void print(const int[10]);以数组作为形参的函数也必须保证这个数组不越界 使用标记指定数组长度 以C风格字符串…

C++中函数概念解析(3)

概念&#xff1a; 如果同一作用域里几个函数的名字相同但形参列表不相同&#xff0c;我们称之为重载&#xff08;overload&#xff09; 它们这些函数接受的参数不一样&#xff0c;但执行的操作非常类似&#xff0c;当调用这些函数时&#xff0c;编译器会根据传递的实参类型推断…

python可以帮机器人编程吗_Python如何实现机器人聊天

今天午休的时候&#xff0c;无意之中看了一篇博客&#xff0c;名字叫Python实现机器人&#xff0c;感觉挺有的意思的。于是用其写了一个简单的Python聊天&#xff0c;源码如下所示:# -*- coding: utf-8 -*-import aimlimport sysimport osdef get_module_dir(name):print("…

测试案例6种编写方法_一种编写测试的好方法

测试案例6种编写方法测试。 我最近一直在考虑测试。 作为我对各种项目所做的代码审查的一部分&#xff0c;我已经看到了数千行未经测试的代码。 这不仅是测试覆盖率统计数据指出这一点的情况&#xff0c;更是该项目中根本没有任何测试的情况 。 我一直听到这种悲惨状况的两个原…

python字符串查找匹配_说说在 Python 中,如何找出所有字符串匹配

Regex 对象有一个 findall() 方法&#xff0c;它会返回包含所查找字符串的所有匹配。这与 search() 方法明显不同&#xff0c;search() 将返回一个 Match 对象&#xff0c;其中包含被查找字符串中的 “ 第一次 ” 匹配文本。请看以下示例&#xff0c;注意区分&#xff1a;phone…

类 in C++

我们为什么需要类、 用户在实际编程中传统数据类型往往不能够满足实际需要&#xff0c;我们对经常使用的对象需要自定义一种数据结构来满足调用的需求以便于提高程序运行的效率。 类的组成 数据抽象封装接口实现 这个程序的作用是读取入库书籍的ISBN编号 saledata total;/…

使用Spring MVC应用程序配置嵌入式H2控制台

在上一篇文章中&#xff0c;我们使用嵌入式H2数据库将Spring MVC应用程序部署到Tomcat。 在嵌入式数据库中浏览数据非常困难&#xff0c;因为我们无法连接外部客户端来查看数据。 H2提供了一个Web控制台&#xff0c;我们可以启用它并使用它来浏览数据&#xff0c;如下所示&…

python实践心得体会_“Python自然语言实践”——总结(一),实战

正则表达式在NLP中的基本应用正则表达式的作用&#xff1a;(1)将文档内容从非结构化转为结构化以便后续的文本挖掘(2)去除“噪声”&#xff0c;在处理大量文本片段的时候&#xff0c;有非常多的文字信息与最终输出的文本无关。这些无关的片段称之为“噪声”。1. 匹配字符串在Py…

Hashcat从入门到入土(二)

使用hashcat破解word密码 昨天的文章里给自己挖了一个坑&#xff0c;使用公司电脑显卡还是GT705古董级别的&#xff0c;显卡驱动也没设置好&#xff0c;导致使用hashcat的时候出现了exhausted的问题&#xff0c;导致密码没有算出来&#xff0c;今天我用自己电脑算一下&#xf…

rizomuv缩放排布_RizomUV

第一章:为什么要用RizomUV来解决UV进程课时1:教程简介课时2:为什么要用RizomUV2020课时3:课程框架结构第二章&#xff1a;有哪些准备工作课时4:MAYA桥接工具安装课时5:3DSMAX桥接工具安装课时6:C4D桥接工具安装课时7:Zbrush桥接工具安装课时8:Blender桥接工具安装课时9:桥接工具…

坚实原则:接口隔离原则

以前&#xff0c;我们研究了liskov替代原理。 下一个原则是接口隔离 。 接口隔离原则&#xff08;ISP&#xff09;指出&#xff0c;不应强迫任何客户端依赖其不使用的方法。 想象一下一个接口&#xff0c;在我们的代码库中有很多方法&#xff0c;尽管只有一部分方法被实现&…

将SQL server2019数据库部署在虚拟机上

下载Windows.iso 前段时间由于数据库文件丢失&#xff0c;导致项目再转入新的环境以后需要重新安装SQL server&#xff0c;但是由于win11对SQL server2019支持非常差&#xff0c;申请的SQL server2022的试用资格又迟迟没有批准导致我的数据库始终连不上&#xff0c;于是只能打…

sqoop mysql 安装_Sqoop安装及验证_MySQL

Sqoop安装及验证环境&#xff1a;系统Red Hatlinux 6.4Hadoop版本1.2.1Sqoop版本1.4.4Mysql数据库版本5.6.15通过Sqoop实现Mysql /Oracle与HDFS / Hbase互导数据http://www.linuxidc.com/Linux/2013-06/85817.htm[Hadoop] Sqoop安装过程详解http://www.linuxidc.com/Linux/2013…

restful web_泽西岛的RESTful Web服务

restful web我已经讨论了有关体系结构考虑事项<< link >>的早期文章&#xff0c;以成为可在我的系统/机器上使用的分布式环境上的RESTful系统。 本文我们将讨论如何基于REST体系结构考虑来构建Web服务。 本教程说明了如何使用Tomcat 6&#xff0c;Eclipse和Jersey …

常见操作系统调度算法研究(1)

FIFO FIFO全称是first in first out&#xff0c;是操作系统里面常见的一种算法&#xff0c;他就好比是一堆人在排一个队伍&#xff0c;按照先进先出的规则&#xff0c;谁首先排队谁就可以第一个出去。 它的缺点显而易见&#xff0c;如果第一个进去的家伙任务量过大&#xff0c…

struts2 mysql 乱码_struts2项目插入中文到mysql数据库乱码的解决方法

项目又出了一些小问题&#xff0c;在更新/插入中文数据到mysql数据库时会显示问号。我做了如下工作解决了问题&#xff1a;1. 检查页面编码将所有的jsp页面编码方式、字符集更改为2. 更改数据库字符集/编码方式将mysql配置文件my.ini相关内容改为[mysql]default-character-setu…

常见操作系统调度算法研究(2)

轮转策略 轮转策略&#xff08;Round-Robin&#xff09;简称为RR&#xff0c;在RR里面&#xff0c;每个准备就绪的任务只能在有限的时间内运行&#xff0c;也就是说不管这个任务完成与否&#xff0c;都会切换任务到下一个。 由于它要频繁的切换队列&#xff0c;我们可以把准备…

使用Apache Ignite优化Spark作业性能(第1部分)

快来看看他们是如何工作的&#xff01; 本文的某些部分摘自我的书《 Apache Ignite的高性能内存计算》 。 如果您对这篇文章感兴趣&#xff0c;请查看本书的其余部分&#xff0c;以获取更多有用的信息。 Apache Ignite提供了几种提高Spark作业性能的方法&#xff1a;Ignite RD…