C++入门——内联函数、extern “C“

news2024/12/23 11:53:06

一.   内联函数

1.概念及分析

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调
用建立栈帧的开销,内联函数提升程序运行的效率。

int Add(int a, int b)
{
    int c = a + b;
    return c;
}

int main()
{
    int ret= Add(1, 2);
    return 0;
}

在我们之前使用的函数中,编译时会建立栈帧,进而去调用

 

而正如上面说的那样,内联函数编译时C++编译器会在调用内联函数的地方展开,没有函数调
用建立栈帧的开销。我们可以用inline修饰后来看一下

查看方式:
1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add
2. 在debug模式下,需要对编译器进行设置,否则不会展开,因为debug模式下,编译器默认不
会对代码进行优化

而由于我使用的是vs2022,release模式下的汇编代码太过简略,我在这里就只采用debug的模式来查看。

 

 

 如此设置,便能进行查看

 

 

可以看到,与普通的函数不同,内联函数的确是在调用的地方展开。


2.特性

1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会
用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运
行效率。

2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建
议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不
是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址
了,链接就会找不到。


3.宏

其实,在c语言中,我们使用宏也能产生类似的效果

#define ADD(x,y) ((x)+(y))

int main()
{
    int ret = ADD(1, 2);
    printf("%d", ret);
    return 0;
}

但宏在实质上已经不是函数了,而是将ADD(x,y)作为标识符来宏定义为字符串((x)+(y))

而宏也有其优缺点

优点:
1.增强代码的复用性。
2.提高性能。

缺点:
1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。

而C++中,除开短小函数使用内联函数来替代宏,常量定义时也可以使用const、enum



二.   extern “C”

由于C++是在C的基础上提供了更多的语法和特性,所以我们能不能在C++的程序中使用C静态库中的函数或者在C的程序中使用C++静态库中的函数呢?

实际上这种想法是可行的,但是我们需要进行一些处理,这也就要使用到extern "C"

1.C++程序

依旧是以vs2022为例,我们首先需要创建一个静态库 

 

 之后我们要在静态库里写一些c的函数

之后

 

这样,lib文件就会在Debug中生成

 C的静态库就处理完成了

我们再看到C++的程序

在使用C静态库中函数前,我们首先要包含头文件。与以往不同,我们需要通过文件的路径去寻找头文件(Add.h)

 

 

 通过对两个文件的路径进行分析,我们可以如此来引用头文件

#include"../DS/add.h"

其中,..代表的是前往上一层目录

然后,我们可以使用Add函数

#include<iostream>
using namespace std;
#include"../Slist/sList.h"

int main()
{
	cout << Add(1, 2) << endl;
	return 0;
}


 当我们运行时,会出现以上的问题,这是因为我们还没有去链接静态库 

 我们需要在上述位置将静态库中的Debug文件夹的路径添加上

并在上述位置加入所引用的头文件 

如此,若是在C++项目中引用C++静态库或是在C项目中引用C静态库,以上操作便能完成

而为了区别两种语言,C++的函数会被修饰,而C不会

因此我们就要使用extern "C"来表明头文件中的函数是用C编写的

extern "C"
{
	#include"../DS/add.h"
}

如此,便完成了全部的操作 


2.C程序 

 那么当我们反过来呢?

首先我们现将上述的文件中的.c改为.cpp,.cpp改为.c   并分别做一下调整

注意:由于C不认识C++的语法,我们C++静态库中的函数要遵循C的语法

我们应该对静态库中的头文件进行修饰。

但由于C语言中并没有extern "C",所以我们不能直接将函数放在其中,而是需要进行条件编译,使得C调用时不需要extern "C",C++调用时需要。

这里我们提供两种方法

#ifdef __cplusplus
extern "C"
{
#endif
	int Add(int a,int b);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#define EXTRERN_C extern "C"
#else
#define EXTRERN_C
#endif

EXTRERN_C int Add(int a,int b);

之后,别忘了重新生成一下解决方案,这样就能实现C程序调用C++静态库了

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

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

相关文章

聚焦技术创新实力,时序数据库 TDengine 荣登中国技术先锋年度评选两大榜单

2023 年 1 月 5 日&#xff0c;中国技术先锋年度评选 | 2022 中国最受开发者欢迎的技术活动榜单正式发布。作为中国领先的新一代开发者社区&#xff0c;SegmentFault 思否依托社区活动板块及全站数百万开发者用户行为数据&#xff0c;及活动规模、内容好评度、行业综合影响力指…

Go语言设计与实现 --调度器(详细介绍)

GMP和GM模型 先来一张图&#xff1a; G(Goroutine)&#xff1a;代表Go 协程Goroutine&#xff0c;存储了 Goroutine 的执行栈信息、Goroutine 状态以及 Goroutine 的任务函数等。G的数量无限制&#xff0c;理论上只受内存的影响&#xff0c;创建一个 G 的初始栈大小为2-4K&…

vue项目安装使用element_UI

安装element_UI之前需要安装VUE脚手架框架! 第一步: 在Vscode 随意打开一个文件夹,在集成终端打开 npm i -g vue/cli (检测: vue -V) 第二步:新建一个文件夹,并且在集成终端打开安装VUE脚手架 需要输入命令: vue create yan6 //yan6 为自定义文件名 1: 选第三个自定义 2: 将…

SpringBoot缓存数据(官方案例)

在线文档项目结构 1.源码克隆&#xff1a;git clone https://github.com/spring-guides/gs-caching.git 2.包含两个项目initial和complete&#xff0c;initial可以根据文档练习完善&#xff0c;complete是完整项目 3.功能描述&#xff1a;构建应用程序&#xff0c;在图书存储库…

JAVA并发编程工具篇--1理解线程池任务的执行和线程的销毁

前言&#xff1a;在编程中我们为什么要使用线程池&#xff0c;线程池中的线程是怎么执行任务的&#xff0c;线程池中的线程是如何复用和销毁的&#xff1b; 1 什么是线程池&#xff1a; 提前创建一些线程放到一个地方&#xff0c;使用的时候直接获取&#xff0c;避免频繁的创建…

CalDAV网页客户端AgenDAV

什么是 AgenDAV &#xff1f; AgenDAV 是一个类似于 Google 日历的 CalDAV 网络客户端&#xff0c;具有 AJAX 界面&#xff0c;允许用户管理自己的日历和共享的日历。 注意事项 AgenDAV依赖于 CalDAV 服务器&#xff08;Bakal、DAViCal 等&#xff09;&#xff0c;所以需要先安…

软件测试员在面试中常遇问题

目前&#xff0c;疫情已经逐渐得到了控制&#xff0c;各行各业都掀起了复工大潮。与此同时&#xff0c;软件测试的招聘需求也随着复工的开始而变得紧急起来&#xff0c;而求职者应该怎样抓住机会进行应聘呢&#xff1f;首先最重要的就是多刷面试题&#xff0c;这样才能才面试过…

CSS权威指南(五)字体

文章目录1.字体族2.font-face3.字重&#xff08;font-weight&#xff09;4.字号&#xff08;font-size&#xff09;5.字形&#xff08;font-style&#xff09;6.字体拉伸&#xff08;font-stretch&#xff09;7.字距&#xff08;font-kerning&#xff09;8.字体变形&#xff08…

Python 办公自动化,全网最全整理来了!拒绝无效率加班!

大家好&#xff0c;今天给大家分享一篇 Python 自动化办公干货&#xff0c;整整42个实战项目案例。每一个项目案例都有详细的视频讲解&#xff0c;是一套非常全面的Python自动化办公项目&#xff0c;建议大家收藏后学习&#xff0c;梳理不易&#xff0c;记得点赞支持。详细目录…

【菜菜的CV进阶之路 - 深度学习环境搭建】常用软件安装

四、安装网易云 双系统装完了&#xff0c;下一步当然是&#xff0c;休息一下&#xff0c;听一首歌啦~ 1、连网&#xff1a;只能使用wifi连&#xff0c;网线直连的话&#xff0c;还需要配置 2、安装网易云&#xff1a; 下载最新的Linux安装包&#xff0c;然后 sudo apt inst…

数据的存储(C语言)

数据类型&#xff1a; 要了解数据是如何存储的&#xff0c;我们就得先知道C语言中的数据类型 基本数据类型 基本数据类型&#xff0c;也就是C语言内置类型&#xff1a; char -> 字符型 short -> 短整型 int -> 整…

html textarea 插入字符在光标处

textarea 插入字符在光标处前言深度解析1 效果图上代码前言 深度解析 1 效果图 上代码 <!DOCUMENT><html><head> <link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css&qu…

Semantic Segmentation | 评价指标代码解析

如有错误&#xff0c;恳请指出。 文章目录1. 定义解析2. 代码解析之前有记录过关于图像语义分割的相关评价指标与经典网络&#xff0c;在看PointNet的语义分割训练脚本的时候&#xff0c;图像的语义分割和点云的语义分割其实本质上是一致的。所以这里想记录一下语义分割的评价指…

MySQL下载及使用navicat连接mysql数据库(含下载地址、超具体细节、推荐数据库教程)

目录下载地址安装流程第一步&#xff1a;开始安装第二步&#xff1a;类型选择第三步&#xff1a;developer default第四步&#xff1a;execute第五步&#xff1a;服务器配置窗口第六步&#xff1a;网络类型配置窗口第七步&#xff1a;第八步&#xff1a;服务器密码设置窗口第九…

Vue全家桶 Pinia状态管理

Pinia状态管理1. Pinia和Vuex的对比2. 创建Pinia的Store3. Store 简介与使用4. Pinia核心概念State5. Pinia核心概念Getters6. Pinia核心概念ActionsPinia开始于大概2019年&#xff0c;最初是作为一个实验为Vue重新设计状态管理&#xff0c;让它用起来像组合式API&#xff0c;从…

[C语言]初步的来了解一下指针(多图详解)

目录 1.指针是什么 2.指针类型 2.1指针类型的意义(-整数) 2.2指针的解引用 3.野指针 3.1野指针出现的情况 3.2 如何规避野指针 4.指针运算 4.1指针-整数 4.2指针-(减)指针 5.二级指针 1.指针是什么 指针是内存中最小的单元编号&#xff0c;也就是地址。指针还可以是一种…

录屏软件电脑版免费哪个好?4款免费屏幕录制软件下载

在电脑上经常能使用的录屏功能&#xff1a;录制软件的操作过程、精彩的游戏瞬间、经典的影视故事、网络教学等。许多人都在问&#xff0c;录屏软件电脑版哪个好&#xff1f;Windows平台上有很多录屏软件&#xff0c;如果对录屏需求不高的朋友&#xff0c;可以通过内置的视频软件…

08线性回归+基础优化算法

P2基础优化算法 1.最常见的优化算法——梯度下降&#xff0c;用在模型没有显示解的情况下&#xff08;线性回归有显示解&#xff0c;但是现实中很少有这样理想的情况&#xff09; 2.梯度下降的实现方法&#xff1a;沿着反梯度更新方向参数求解 解释&#xff1a; 超参数&#x…

HTTP_day03

当键入网址后&#xff0c;到网页显示&#xff0c;其间发生了什么&#xff08;下&#xff09; 掘金地址 键入 localhost ,通过 Wireshark 抓包分析&#xff0c;抓包结果如下图所示 抓包结果 我们知道 HTTP 协议是运行在 TCP/IP 基础 之上的。 浏览器 通过 HTTP 接收和发送数据…

怎么才能写出好的代码

前言这是一篇如何写好代码的水文&#xff0c;因为最近输出了不少干货&#xff0c;但是大家点赞太少&#xff0c;我越来越没有激情了&#xff0c;那就放放水啦。所以如果大家觉得我的分享对你有用&#xff0c;动动发财小手&#xff0c;赞起来吧&#xff01;虽然是一篇水文&#…