C和C++的区别(一)

1、带有默认值的函数

C++可以给函数定义或者声明时给参数赋初值

现在我们学习的C语言是C89标准,没有此功能,但C99标准有。

  我们知道形参入栈的时候是按从右向左的顺序依次压入栈的,看下面这段代码:

.cpp文件

#include<stdio.h>
int sum(int a,int b);
int main()
{
    int a=10;
    int b=20;
    sum(a,b);
    return 0;
}
int sum(int a,int b)
{
    int temp;
    temp=a+b;
    return temp;
}

形参入栈时反汇编是这样的:

   mov        eax,dword  ptr[ebp-8];

   push   eax;

  mov         ecx,dword   ptr[ebp-4];

  push   ecx;

扫描二维码关注公众号,回复: 908410 查看本文章

嗯,形参是从右向左依次入栈。

那么C++为什么使用带默认值的函数?有什么好处呢?

我们修改上面的代码:声明处:   int  sum(int a,int b=20);

                                   主函数调用处    sum(a);

    

形参的反汇编是什么:    push   14h;

                                     mov   eax,dword  ptr[ebp-4];

入栈的时候直接把立即数入栈,不用通过寄存器,是不是提高了效率呢!

在主函数中调用sum函数的方式还可以有哪些?

// sum(a,b);  正常的调用

 sum(a);       带有默认值的函数,在函数声明处给b赋值,int sum(int a,int b=20);

 sum(a,30)   把30赋给b,

 sum(a)和sum(a,30)的效率无差别 

反汇编形参入栈都是 push  14h

                                  push   1eh


 sum(,10),不可以哦,调用的时候要从最后一个开始赋值。因为你调用的函数定义就会变成   int  sum(int a=20,int b),这是不允许的,



如果你写成这样:

    int sum(int a,int b=20);

    int sum(int a=10,int b);

合起来是可以的。


   int  sum(int a=10,int b);

   int sum(int a,int b=20);

不可以


上面的代码我们把声明写在了前面,所以如果你这样写:

int  sum(int a,int  b)

int main()

{

.....

sum(a);

}

int sum(int a,int b=10)

{

.......

}

也是不可以的,因为函数的编译顺序是从上往下读的,这样给默认值就不可以了。


2、内联函数  inline
内联函数是在编译过程中在函数的调用点把函数的代码全部展开,不会生成函数的符号,是一种更安全的宏。
inline int sum(int a,int b)
{
    return a+b;
}

int main()
{
	int a=10;
	int b=20;
	sum(a,b);
        return 0;
}
编译时:
int  main()
{
    int a=10;
    int b=20;
    a+b;
   return  0;
}

把内联函数的内容替换到主函数调用它的地方。和宏很相似,但宏只是单纯的字符替换,无法调试,那么就发现不了错误,是很头疼的,而内联函数在编译阶段会进行类型检查,是一种更安全的宏。

内联函数和普通函数的区别是是什么?
   内联函数没有标准的函数栈帧的开辟和回退。
   内联函数是一种安全宏,对代码的替换,不会生成符号,而普通函数会生成符号。

那么我们平时也没见把每个函数写成是内联函数啊!!
  1、内联函数只对本文件有效,所以如果你要使用它,可以把它写进头文件,供多个文件使用。
  2、执行效率
       如果调用函数的开销>函数执行的开销,也就是说像我们上面的例子,如果调用的代码只有类似a+b的简单算法,当然用内联函数的效率就比较高,但调用函数如果复杂的话,用普通函数的效率会高一些。

内联函数和static  函数的区别:
相同:都在本文件中使用。
区别:
           1、栈帧开辟回退(内联没有,static 函数需要开辟回退)
           2、符号的产生(内联函数不产生,static 函数产生local符号)
inline 只在release 版本起作用,debug版本不起作用。
inline函数只是给编译器的一个建议(代码优化)
inline函数对递归函数不起作用,因为编译阶段不运行,并不知道递归几次,inline的代码就无法展开,进行替换。

猜你喜欢

转载自blog.csdn.net/lyt15829797751/article/details/78467692