【c/c++】cpp对c的函数扩展

(1)内联函数

1.含义

C++编译器可以将⼀个函数进⾏内联编译,只需要在函数定义时前⾯加上inline即可。被C++编译器内联编译的函数叫做内联函数。内联函数在最终⽣成的代码中是没有定义的。C++编译器直接将函数体插⼊在函数调⽤的地方。

#include <stdio.h>inline int myfunc(int a, int b)
{printf("a = %d\n", a);printf("b = %d\n", b);return (a < b) ? a : b;
}int main()
{int a = 1;int b = 3;int c = myfunc(a , b);return 0;
}/*
int main()
{int a = 1;int b = 3;printf("a = %d\n", a);printf("b = %d\n", b);int c = (a < b) ? a : b;return 0;
}
*/

内联函数说明:

  • 内联函数省去了普通函数调⽤时压栈,跳转和返回的开销,速度更快。当函数体的执⾏开销远⼤于压栈,跳转和返回所⽤的开销 时,那么内联将⽆意义。
  • C++编译器不⼀定准许函数的内联请求!内联函数是对编译器的⼀种请求,因此编译器可能 拒绝这种请求。
  • 现代C++编译器能够进⾏编译优化,因此⼀些函数即使没有inline声明,也可能被编译器内 联编译。

C++中内联编译的限制:

  • 不能存在任何形式的循环语句
  • 不能存在过多的条件判断语句
  •  函数体不能过于庞⼤
  • 不能对函数进⾏取址操作
  • 函数内联声明必须在调⽤语句之前
  • inline只是⼀种请求,编译器不⼀定允许这种请求

2.使用内联函数替代宏代码片段

C++中的const常量可以替代宏常数定义,如:

const int A = 3;   与  #define A 3

C++中是否有解决⽅案替代宏代码⽚段呢?(替代宏代码⽚段就可以避免宏函数的副作⽤)

C++中推荐使⽤内联函数替代宏代码⽚段

内联函数声明时inline关键字必须和函数定义(函数体)结合在⼀起,否则编译器会直接忽略内联请求。

#include <iostream>#define MYFUNC(a, b) (a < b) ? a : b //宏代码片段inline int myfunc(int a, int b)
{return a < b ? a : b;
}int main()
{int a = 1;int b = 3;int c = MYFUNC(a++, b);std::cout << a << "," << b << "," << c << std::endl;  // 3,3,2/*为什么当 int c = MYFUNC(a++, b); 时是a = 3, c = 2MYFUNC(a++, b) → (a++ < b) ? a++ : ba++先取值再自增 取值是1,自增后 a = 2,1小于b所以返回 a++ ,返回的这个a++先取值就是2,再自增就是3所以 a = 3, c = 2*/int x = 1;int y = 3;int z = myfunc(x++, y);std::cout << x << "," << y << "," << z << std::endl;  // 2,3,1/*    为什么当 int z = myfunc(x++, y); 时是 x = 2, z = 1x++传入实参 先返回值,也就是1,所以a为11和3比较返回1,所以z = 1*/return 0;
}

(2)默认参数

C++中可以在函数声明时为参数提供⼀个默认值, 当函数调⽤时没有指定这个参数的值,编译器会⾃动⽤默认值代替。

普通参数放在函数参数位置的左边,默认参数放在右边,默认参数右边必须全是默认参数。

#include <iostream>void test(char pos, int a = 0, int b = 0)
{std::cout << pos << "," << a << "," << b << std::endl;
}int main()
{test('S');           // S,0,0test('K', 10);       // K,10,0test('N', 3, 2);     // N,3,2return 0;
}

(3)占位参数

函数占位参数:占位参数只有参数类型声明,⽽没有参数名声明。⼀般情况下,在函数体内部⽆法使⽤占位参数。

#include <iostream>int func(int a, int b, int) 
{return a + b;
}int main()
{int ret = func(1, 2, 5);std::cout << ret << std::endl;  // 3return 0;
}

可以将占位参数与默认参数结合起来使⽤,作用:

  • 为以后程序的扩展留下线索
  • 兼容C语⾔程序中可能出现的不规范写法
#include <iostream>int func2(int a, int b, int=0) 
{std::cout << a << "," << b << std::endl;
}int main()
{func2(1, 2);   // okfunc2(1, 2, 100);  // okreturn 0;
}

(4)函数重载

1.含义

概念:⽤同⼀个函数名定义不同的函数。当函数名和不同的参数搭配时函数的含义不同。

函数重载⾄少满⾜下⾯的⼀个条件:

  • 参数个数不同
  • 参数类型不同
  • 参数顺序不同

返回值 不是 判断函数重载的标准 

// main.cpp
#include <stdio.h>void myPrint(int a)
{printf("a = %d \n", a);
}void myPrint(char *p)
{printf("%s \n", p);
}void myPrint(int a, int b)
{printf("a = %d ", a);printf("b = %d \n", b);
}int main()
{myPrint(1);char name[] = "111222233aaaa";myPrint(name);myPrint(1, 2);return 0;
}

2.函数重载和函数默认参数的二义性报错

#include <iostream>// 函数重载  和  函数默认参数 在一起
void myfunc(int a, int b, int c = 0)
{std::cout << a << "," << b << "," << c << std::endl;
}void myfunc(int a, int b)
{std::cout << a << "," << b << std::endl;
}int main()
{myfunc(1, 2); //函数调用时,会产生二义性// 报错:错误:调用重载的‘myfunc(int, int)’有歧义return 0;
}

3.函数重载和函数指针结合

当使⽤重载函数名对函数指针进⾏赋值时

根据重载规则挑选与函数指针参数列表⼀致的候选者

严格匹配候选者的函数类型与函数指针的函数类型

#include <iostream>
#include <cstring>
using namespace std;int func(int x)
{return x;
}int func(int a, int b)
{return a + b;
}int func(const char *s)
{return strlen(s);
}typedef int (*PFUNC)(int a); // 函数指针声明int main()
{int c = 0;PFUNC p;p = func;c = p(1);  // 根据类型进行匹配,选择int func(int x)std::cout << c << std::endl;  // 1// std::cout << p(1, 6) << std::endl;  // 会报错// 在第一次p=func以及c = p(1)后,根据重载规则// p的地址已经确定,是int func(int x)函数的地址,因此这里报错return 0;
}

end

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

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

相关文章

YOLOv8-PySide --- 基于 ultralytics 8.1.0 发行版优化 | 代码已开源

YOLOv8-PySide — 基于 ultralytics 8.1.0 发行版优化 Github 项目地址&#xff1a;https://github.com/WangQvQ/Ultralytics-PySide6 页面效果 如何使用 pip install ultralytics8.1.0 or git clone --branch v8.1.0 --single-branch https://github.com/ultralytics/ultral…

JMeter--配置元件--HTTP请求默认值

HTTP请求默认值 管理公用的HTTP请求配置数据&#xff1b;一个线程下可以同时存在多个http请求&#xff0c;可以把公共参数&#xff0c;提取到HTTP请求默认值组件中&#xff0c;比如&#xff1a;协议、IP、端口号、编码等&#xff1b;然后在每个http请求的配置元件中&#xff0c…

如何让AI生成自己喜欢的歌曲-AI音乐创作的正确方式 - 第507篇

历史文章 AI音乐&#xff0c;8大变现方式——Suno&#xff1a;音乐版的ChatGPT - 第505篇 日赚800&#xff0c;利用淘宝/闲鱼进行AI音乐售卖实操 - 第506篇 导读 在使用AI生成音乐&#xff08;AI写歌&#xff09;的时候&#xff0c;你是不是有这样的困惑&#xff1a; &…

新版a_bogus算法分析以及成品展示调用

新版a_bogus算法的过程&#xff0c;仅学习参考&#xff0c;如有涉及侵权联系本人删除 最近看到这个参数花了点时间研究了一下 流程和X-Bogus差不多&#xff0c;通过对这段字符串概是对数据、ua、时间戳、浏览器的几个指纹进行计算&#xff0c;长度168位 下面是实现效果以及测…

Spring原理分析--获取Resource资源对象

1.获取资源对象 ApplicationContext接口是BeanFactory的子接口&#xff0c;意味着它扩展了BeanFactory的功能&#xff0c;其中继承ResourcePatternResolver接口&#xff0c;提供获取Resource资源的功能&#xff0c;示例如下&#xff1a; SpringBootApplication public class …

TQZC706开发板教程:编译zynq linux内核2019_R1

您需要下载对应版本的Linux系统文件以及IMG1.3.1镜像文件。为了方便您的操作&#xff0c;本文所使用的所有文件以及最终生成的文件&#xff0c;我都已经整理并放置在本文末尾提供的网盘链接中。您可以直接通过该链接进行下载&#xff0c;无需在其他地方单独搜索和获取。希望这能…

C语言:数据结构(单链表)

目录 1. 链表的概念及结构2. 实现单链表3. 链表的分类 1. 链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表的指针链接次序实现的。 链表的结构跟火车车厢相似&#xff0c;淡季时车次的车厢会相应…

linux之进程通信

目录 一、进程通信介绍 1.目的 2.发展 3.进程通信是什么&#xff0c;怎么通信&#xff1f; 二、管道 1.介绍 2.匿名管道 1.单向通信管道原理 2.代码实现 3.管道特征 4.管道的四种情况 5.管道的应用场景 使用管道实现一个简易版本的进程池 3.命名管道 1.思考 2.…

使用JXLS+Excel模板制作灵活的excel导出

前期一直卡在模板的批注上&#xff0c;改了很多遍的模板批注最终才成功导入&#xff0c;记录下方便以后寻找。 话不多说直接上代码&#xff1a; Report package com.example.jxls.common;import java.io.IOException; import java.io.InputStream; import java.io.OutputStr…

使用 Meta Llama 3 构建人工智能的未来

使用 Meta Llama 3 构建人工智能的未来 现在提供 8B 和 70B 预训练和指令调整版本,以支持广泛的应用 使用 Meta AI 体验 Llama 3 我们已将 Llama 3 集成到我们的智能助手 Meta AI 中,它扩展了人们完成工作、创造和与 Meta AI 联系的方式。通过使用 Meta AI 进行编码任务和解…

python安装时遇到A newer version of the Python launcher is already installed.

由于业务需要&#xff0c;我得用python3.9版本&#xff08;好像是因为python3.9对深度学习等的支持比较好&#xff09;&#xff0c;需要涉及到python3.9和python3.12的共存问题&#xff0c;方法有很多&#xff0c;什么创建虚拟环境使得不同版本的共存之类的。最后我选择最笨的&…

RHCA证书含金量高吗?Linux认证难考吗?

在IT行业&#xff0c;Linux系统认证作为衡量专业人士Linux技能水平的重要标准&#xff0c;越来越受到重视。 特别是红帽认证架构师&#xff08;RHCA&#xff09;证书&#xff0c;它代表着Linux领域的高级专业技能。 那么&#xff0c;RHCA证书的含金量如何&#xff1f;Linux认…

通过Dos批量对程序进行打包

本文介绍如何编写dos可执行程序来进行软件的发包,通过dos自动获取系统当前时间复制软件模版到指定的产品目录,然后将指定的产品内容复制到程序内部。最终通过360压缩工具进行一个打包操作。提供程序发布效率。 当前时间日期: set predate=%date:~0,4%%date:~5,2%%date:~8,2%…

C语言.字符函数与字符串函数

字符函数与字符串函数 1.字符分类函数2.字符转换函数3.[strlen](https://cplusplus.com/reference/cstring/strlen/?kwstrlen) 的使用和模拟实现4.[strcpy](https://legacy.cplusplus.com/reference/cstring/strcpy/?kwstrcpy) 的使用和模拟实现5.[strcat](https://legacy.cp…

Remote access minikube cluster远程访问minikube k8s集群

minikube是启动一个虚拟机来模拟单节点环境&#xff0c;容器运行在单独的网络环境 可以看到192.168.49.2:8443是api server地址&#xff0c;是虚拟的ip (base) [rootlocalhost access]# kubectl config view apiVersion: v1 clusters: - cluster:certificate-authority: /roo…

信息系统及其技术发展

目录 一、信息系统基本概念 1、信息系统项目开发 2、信息系统项目管理 3、信息系统 Ⅰ、生命周期 Ⅱ、新基建 ①信息基础设施 ②融合基础设施 ③创新基础设施 Ⅲ、工业互联网 Ⅳ、车联网 ①体系框架 ②连接方式 4、习题 二、信息技术发展 1、SDN 2、5G 3、存储…

AI小知识----什么是RAG

RAG的概念 RAG的全称是Retrieval-Augmented Generation&#xff0c;中文翻译为检索增强生成。它是一个为大模型提供外部知识源的概念&#xff0c;这使它们能够生成准确且符合上下文的答案&#xff0c;同时能够减少模型幻觉。 「检索(Retrive)」 根据用户请求从外部知识源检索相…

书生·浦语大模型第二期实战营(5)笔记

大模型部署简介 难点 大模型部署的方法 LMDeploy 实践 安装 studio-conda -t lmdeploy -o pytorch-2.1.2conda activate lmdeploypip install lmdeploy[all]0.3.0模型 ls /root/share/new_models/Shanghai_AI_Laboratory/ln -s /root/share/new_models/Shanghai_AI_Laborato…

【Vue3源码学习】— CH3.2 VNode解析(上)

VNode解析—上 1. VNode 的作用和优势1.1 抽象表示1.2 更新优化1.3 跨平台2. _createVNode 函数解析2.1 调用链路2.2 _createVNode函数实现关键操作说明:注1:注2:2.3 _createVNode小结3. createBaseVNode 详解3.1 源码解析3.2 关键部分解析3.3 类型说明3.3.1 ts | 符号3.3.2 解…

探索Java设计模式:命令模式

深入理解与实践Java设计模式之命令模式 一、简要介绍 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;它将请求封装为一个对象&#xff0c;使得使用命令对象的客户端与请求接收者&#xff08;即具体执行命令的对象&#xff09;解耦。这样做…