【C++】调用约定&&C与C++区别

 1、调用约定

_cdecl: C标准调用约定

  • 从右至左的顺序将参数压入栈中
  • 形参的开辟由调用方处理,清理由调用方处理
  • 编译后的函数名前加一个下滑线,如:_fun

_stdcall:windows下标准调用约定

  • 从右至左的顺序将参数压入栈中
  • 形参的开辟由调用方处理,清理由被调用方处理
  • 编译后的函数名前加一个下滑线,函数名后面加一个@,如:_fun@

_fastcall:快速调用约定,通过寄存器传递参数,相比较取内存栈中读取参数,该调用约定更快

  • 使用ecx和edx寄存器传递前两个参数,其他参数从右至左的顺序将参数压入栈中
  • 形参的开辟由调用方处理,清理由被调用方处理
  • 编译后的函数名前后个加一个@,并且在后面紧跟函数参数的字节数如:@fun@8

_thiscall:类成员方法缺省的调用约定

2、C与C++区别

1、函数重载

静多态包含函数重载和函数模板,多态是为了实现接口服用,它可以用8个字概括:同一接口,不同形态,是函数的形参为函数重载提供支持。重载的三要素是:同名同作用域不同参。(调用点看不见返回值类型)

C语言中产生函数符号的规则根据函数名产生,所以c语言中不存在函数重载。C++中产生函数符号的规则根据函数名、参数个数、参数类型。

2、new和malloc的区别

1、属性:new/delete是C++的关键字,需要编译器的支持;malloc/free是库函数,需要头文件的支持

2、参数:new在申请内存分配时无需制定内存块的大小,编译器会在根据类型信息自行计算;malloc需要显式的置处所需内存的大小

3、返回类型:new分配成功时,返回的时对象类型的指针,类型严格与对象匹配,无需进行类型转换,符合类型安全;malloc分配成功返回void*,需要通过强制类型转换将void*转换成我们需要的类型

4、分配失败:new会抛出bac_alloc异常;malloc返回NULL

5、自定义类型:new先调用operator new函数,申请足够的内存(通常底层使用malloc实现),再调用类的构造函数,初始化对象的成员变量,最后返回自定义类型指针;malloc是库函数,只能申请内存,不能进行初始化

6、重载:new可以重载,因为operator new可以重载,所以new可以调用malloc;malloc不可以重载,所以malloc不可以调用new

7、内存区域:new在自由存储区;malloc在堆上(在C中,内存分为:堆、栈、全局/静态、常量存储区。在C++中,内存分为:堆、栈、自由存储区、全局/静态、常量存储区)

8、new可以开辟常量,如:const int *p = new const int(20);;malloc不可以

eg:int *p = new int[10];delete p;程序不会出错,地址匹配上了。Test *t = new Test[10];delete t;当自定义类型用new申请数组,只释放一个,程序会中止、出错,因为使用new申请10个对象时,每一个对象不光申请了空间,而且都调用一次构造,而只释放一个对象只调用了一次析构

9、使用malloc分配的内存后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配实现内存的扩充。realloc先判断当前的指针所指内存是否有足够的连续空间,如果有,原地扩大可分配的内存地址,并且返回原来的地址指针;如果空间不够,先按照新指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来的内存区域。而new没有这样直观的配套设施来扩充内存。

10、C++提供了new[]和delete[]来专门处理数组类型,使用new[]分配的内存必须使用 delete[]进行释放。new[]一次分配所有的内存,多次调用构造函数,搭配使用delete[],delete[]多次调用析构函数,销毁数组中的每个对象。而malloc则只能手动自定数组的大小。

3、const

在C语言中,const修饰的变量称为常变量,是global属性。在编译阶段看常变量是否做左值,其他处理和普通变量一样

在C++中,const修饰的变量称为常量,是local属性,可以使用extern去掉local属性。在编译阶段处理把用到常量的地方直接替换常量初始化的值。

  • 一定要初始化
  • 常量不能做左值
  • 不能间接修改,杜绝间接访问来修改常量内存的风险(如果用普通指针指向const修改的变量,普通指针一定会解引用,所以存在风险)

const修饰指针变量(函数参数)时:

  1.只有一个const,如果const位于*左侧,表示指针所指数据是常量,不能通过解引用修改该数据;指针本身是变量,可以指向其他的内存单元。

       2.只有一个const,如果const位于*右侧,表示指针本身是常量,不能指向其他内存地址;指针所指的数据可以通过解引用修改。

  3.两个const,*左右各一个,表示指针和指针所指数据都不能修改。

const修饰成员函数:

       1.const修饰的成员函数不能修改任何的成员变量(mutable修饰的变量除外)

       2.const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量

this指针是Test *const this = &test

4、inline函数

在编译阶段,调用点展开,所以导致只能本文件可见

inline函数和static修饰的函数的区别:inline函数没有开栈清栈的开销,因为在编译阶段代码展开导致inline函数只能本文件可见;static修饰的函数除了因为符号属性为local属性,所以只能本文件可见之外其他和普通函数没什么区别

inline函数和宏函数的区别:inline函数在编译阶段处理,所以它有类型检查和安全检查,宏函数是在预编译阶段进行的文本替换,没有类型检查和安全检查。inline是一种更安全的宏

inline注意事项:

  • inline函数一般写在头文件中
  • inline只在Release版本下生效
  • inline是给编译器的一个建议,递归、循环、switch都不能写成inline
  • inline函数是基于实现的,而不是基于声明的
  • inline函数是以代码膨胀为代价,用空间换时间

5、函数默认值

  • 自右向左依次赋值
  • 不能重复赋值
  • 一般写在声明上

6、C和C++的相互调用

C++调用C时:C++中写extern "C"

C调用C++时:当可修改C++源文件时,在C++源文件添加extern "C";当不可修改C++源文件时,加.cpp文件当中间层

当编译.C文件时,不知道编译器的编译方式:加宏#ifdef_cplusplus

7、namespace,存在同名的namespace会合并

using namespace std;   using指示符

using std::cout;  using声明

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值