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

电子商务网站建设规划开题报告网站开发php和ui

电子商务网站建设规划开题报告,网站开发php和ui,网上购物软件排行榜,中国建设银行官网网址是多少目录 内联函数 什么是内联函数 宏函数与内联函数 内联函数注意事项 异常处理 内联函数 在C中,通常定义以下函数来求取两个整数的最大值 int max(int x, int y) {return x > y ? x : y; } 为这么一个小的操作定义一个函数的好处有: (1)阅读和…

目录

内联函数

什么是内联函数

宏函数与内联函数

内联函数注意事项

异常处理


内联函数

在C++中,通常定义以下函数来求取两个整数的最大值

int max(int x, int y)
{return x > y ? x : y;
}

为这么一个小的操作定义一个函数的好处有:

(1)阅读和理解函数 max 的调用,要比读一条等价的条件表达式并解释它的含义要容易得多;

(2)如果需要做任何修改,修改函数要比找出并修改每一处等价表达式容易得多;

(3)使用函数可以确保统一的行为,每个测试都保证以相同的方式实现;

(4)函数可以重用,不必为其他应用程序重写代码。

虽然有这么多好处,但是写成函数有一个潜在的缺点:调用函数比求解等价表达式要慢得多。在大多数的机器上,调用函数都要做很多工作:调用前要先保存寄存器,并在返回时恢复,复制实参,程序还必须转向一个新位置执行。即对于这种简短的语句使用函数开销太大。

在C语言中,我们使用带参数的宏定义这种借助编译器的优化技术来减少程序的执行时间,请定义一个宏完成以上的max函数的功能

那么在C++中有没有相同的技术或者更好的实现方法呢?答案是有的,那就是内联(inline)函数。内联函数作为编译器优化手段的一种技术,在降低运行时间上非常有用。

什么是内联函数

内联函数是C++的增强特性之一,用来降低程序的运行时间。当内联函数收到编译器的指示时,即可发生内联:编译器将使用函数的定义体来替代函数调用语句,这种替代行为发生在编译阶段而非程序运行阶段。

定义函数时,在函数的最前面以关键字“inline”声明函数,该函数即可称为内联函数(内联声明函数)。

inline int max(int x, y)
{return x > y ? x : y;
}

宏函数与内联函数

在C程序中,可以用宏代码提高执行效率。宏代码本身不是函数,但是看起来像函数。编译预处理器用拷贝宏代码的方式取代函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return等过程,从而提高了速度。

使用宏代码最大的缺点是容易出错,预处理器在拷贝宏代码时常常产生意向不到的边际效应。例如:

#define MAX(a, b) (a) > (b) ? (a) : (b) int result = MAX(20,10) + 20//result的值是多少?int result2 = MAX(10,20) + 20//result2的值是多少?//result = MAX(i, j) + 20; 将被预处理器扩展为: result = (i) > (j) ?(i):(j)+20

可以修改宏代码为

#define MAX(a, b) ((a) > (b) ? (a) : (b))

可以解决上面的错误了,但也不是万无一失的,例如:

int i = 4,j = 3;
result = MAX(i++,j);
cout << result << endl; //result = 5;
cout << i << endl; //i = 6;//使用MAX的代码段经过预处理器扩展后,result = ((i++) > (j) ? (i++):(j));

的另一个缺点就是不可调试,但内联函数是可以调试的。内联函数不是也像宏一样进行代码展开吗?怎么能够调试呢?其实内联函数的”可调试“不是说展开后还能调试,而是在程序的调试(Debug)版本里它根本就没有真正内联,编译器像普通函数那样为它生成含有调试信息的可执行代码。在程序的发行(Release)版本里,编译器才会实施真正的内联。

那C++的内联函数是如何工作的呢?

对于任何内联函数,编译器在符号表(符号表是编译器用来收集和保存字面常量和某些符号常量的地方)里放入函数的声明,包括名字、参数类型、返回值类型。如果编译器没有发现内联函数存在错误,那么该函数的代码也会被放入符号表里。在调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换)。如果正确,内联函数的代码就会直接替换函数调用语句,于是省去了函数调用的开销。这个过程与预处理有显著的不同,因为预处理器不能执行类型安全检查和自动类型转换。

—— 内联函数就是在普通函数定义之前加上inline关键字

(1)inline是一个建议,并不是强制性的,后面会学到inline失效的情况

(2)inline的建议如果有效,就会在编译时展开,可以理解为是一种更高级的代码替换机制(类似于宏——预处理)

(3)函数体内容如果太长或者有循环之类的结构,不建议inline,以免造成代码膨胀;比较短小的代码适合用inline。

C++的函数内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作类的数据成员,所以在C++中应尽可能的用内联函数取代宏函数。

对比总结:

宏函数 优点:只是进行字符串的替换,并没有函数的开销,对于比较短小的代码适合使用;

缺点:没有类型检查,存在安全隐患,而且比较容易写错。

如果使用普通函数的方式又会增加开销,所以一些时候可以采用内联函数(结合了宏函数和普通函数的优点)。

inline函数本质也是字符串替换(编译时),所以不会增加开销,但是有类型检查,比较安全。

内联函数注意事项

  1. 如果要把inline函数声明在头文件中,则必须把函数定义也写在头文件中。若头文件中只有声明没有实现,被认为是没有定义替换规则。

    如下,foo函数不能成为内联函数:

inline void foo(int x, int y);//该语句在头文件中void foo(int x, int y)//实现在.cpp文件中
{ //... }

因为编译器在调用点内联展开函数的代码时,必须能够找到 inline函数的定义才能将调用函数替换为函数代码,而对于在头文件中仅有函数声明是不够的。

当然内联函数定义也可以放在源文件中,但此时只有定义的那个源文件可以用它,而且需要为每个源文件拷贝一份内联函数的定义(每个源文件里的定义必须是完全相同的)。相比之下,放在头文件中既能够确保调用函数是定义是相同的,又能够保证在调用点能够找到函数定义从而完成内联(替换)。

image-20240306154205860

从测试文件出发,找到头文件,发现此函数是inline函数,那么要展开替换,必须要有明确的替换规则,但是在头文件中并没有发现替换规则,所以报错未定义问题。

inline函数在头文件必须有定义。

  1. 谨慎使用内联

内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?事实上,内联不是万灵丹,它以代码膨胀(拷贝)为代价,仅仅省去了函数调用的开销,从而提高程序的执行效率。(注意:这里的“函数调用开销”是指参数压栈、跳转、退栈和返回等操作)

如果执行函数体内代码的时间比函数调用的开销大得多,那么 inline 的效率收益会很小。另外,每一处内联函数的调用都要拷贝代码,将使程序的总代码量增大,消耗更多的内存空间。以下情况不宜使用内联:

  • 如果函数体内的代码比较长,使用内联将导致可执行代码膨胀过大。

  • 如果函数体内出现循环或其他复杂的控制结构,那么执行函数体内代码的时间将比函数调用开销大得多,因此内联的意义并不大。

实际上,inline 在实现的时候就是对编译器的一种请求,因此编译器完全有权利取消一个函数的内联请求。一个好的编译器能够根据函数的定义体,自动取消不值得的内联,或自动地内联一些没有inline 请求的函数。因此编译器往往选择那些短小而简单的函数来内联。

异常处理

异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw.

抛出异常即检测是否产生异常,在 C++ 中,其采用 throw 语句来实现,如果检测到产生异常,则抛出异常。该语句的格式为:

throw 表达式;
  • 先定义抛出异常的规则(throw),异常是一个表达式,它的值可以是基本类型,也可以是类;

double division(double x, double y)
{if(y == 0)throw "Division by zero condition!";return x / y;
}

try-catch语句块的语法如下:

try {
//语句块
} catch(异常类型) {
//具体的异常处理...
} ...
catch(异常类型) {
//具体的异常处理...
}

try-catch语句块的catch可以有多个,至少要有一个,否则会报错。

  • 执行 try 块中的语句,如果执行的过程中没有异常拋出,那么执行完后就执行最后一个 catch块后面的语句,所有 catch 块中的语句都不会被执行;

  • 如果 try 块执行的过程中拋出了异常,那么拋出异常后立即跳转到第一个“异常类型”和拋出的异常类型匹配的 catch 块中执行(称作异常被该 catch 块“捕获”),执行完后再跳转到最后一个catch 块后面继续执行。

注意:catch的是类型,不是具体信息

image-20240306155908426

http://www.dtcms.com/wzjs/597106.html

相关文章:

  • 盐城市滨海县建设局网站企业建站系统免费
  • 网站建设公司网页自己制作头像的软件
  • WordPress挂在虚拟站点巩义专业网站建设公司首选
  • 上海网站搜索引擎优化六安论坛网站
  • 网站之间如何交换友情链接wordpress 密码查看
  • 建设个网站多少钱哪个网站做海南二手房
  • 移动网站 制作旅游主题网站策划书
  • 做门户网站长沙社区赚钱吗做国外房产的网站
  • 沧州网站建设的技术方案做网站怎么引用字体
  • 徐州建设银行网站绵阳做网站
  • 微信公众平台怎么做微网站wordpress 学术 模板
  • 服装店网站建设思路网站建设服务 行业代码
  • 阿里云的虚拟主机用什么做网站重庆软件开发公司有哪些
  • 苏州网站定制公司哪家好网站建设算固定资产吗
  • 网站建设太金手指六六二七已有网站开发app客户端
  • wordpress 淘客推广seo网站
  • 国外 图片网站wordpress 随机文章
  • 做二手平台公益的网站wordpress显示栏目名称
  • 长丰县住房和城乡建设局网站衡阳网站建设公司地址
  • 科凡网站建设怎么样网站根验证文件在哪
  • 小说素材网站东阳网络推广
  • 网站开发实验室标准网站建设费用
  • crm系统 网站建设wordpress企业中文模板下载地址
  • 0基础网站建设模板陕西头条新闻
  • 一个网站通常包含多个网页怎么编辑网站后台
  • 网站抓取超时错误wordpress2018版本
  • 设计师网站 知乎太原百度推广制作个性商城网站
  • 衡阳网站建设mdawl渭南做网站都有哪些
  • 网站开发项目经验描述企业网站备案号密码忘记
  • 百度云网站建设教程如何建设网站站点