C与C++的区别(上)

一、函数的默认值

int sum(int a,int b)
{
    return a+b;
}

int main()
{
    int a = 10;
    int b = 20;
    sum(a,b);
}

以上代码sum(a,b)的反汇编为

00C3144C  mov         eax,dword ptr [b]  
00C3144F  push        eax  
00C31450  mov         ecx,dword ptr [a]  
00C31453  push        ecx  
00C31454  call        sum (0C3105Fh)  
00C31459  add         esp,8  

如果将sum函数设置默认值,即

int sum(int a,int b = 20)
{
    return a+b;
}

int main()
{
    int a = 10;
    sum(a);
    //sum(a,30);30为立即数
}

以上代码sum函数的反汇编为

00231445  push        14h  
00231447  mov         eax,dword ptr [a]  
0023144A  push        eax  
0023144B  call        sum (023105Fh)  
00231450  add         esp,8  

与未初始化的函数相比就少了一步mov b的过程。

默认值的总结:
默认值是从右往左赋值的,绝不可以int sum(int a = 10,int b);
但是在函数声明的时候可以这样写:
int sum(int a,int b=20);
int sum(int a=10,int b);
这是因为在前一行的sum函数中已经给b赋值了
但是如果将以上两句函数声明倒过来写,将原来的第一句放在第二句的位置,就不行了,因为编译器是从上往下编译的,原来的第二句并没有给b先赋值。

二、inline内联函数
1、在调用点把代码直接展开(不会给sum函数开辟栈,而是直接的替换。)
例:

inline int sum(int a,int b)
{
    return a+b;
}

int main()
{
    int ret = sum(10,20);//将此句直接转换为:ret = 10+20
}

2、宏(#define)和内联函数(inline)的区别
宏:处于预编译阶段,不会做的词法解析以及类型检查,出错的可能性高,不安全。
下面举一个例子:

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

int main()
{
    int a = Max(10,20)+20;
    printf("%d\n",a);
    return 0;
}

上面这段代码输出的会是什么呢?
输出的是:40
为什么呢?
上面说过了,宏定义就是字符替换,所以原函数中的a = Max(10,20)+20就变为了a = 10>20?10:(20+20)。

内联函数:处于编译阶段,有进行词法解析以及类型检查,只要有错误就会编译失败,所以说inline函数是安全的。

3、内联函数和普通函数的区别
普通函数:需要开辟栈帧,清理栈帧(栈的回退)。
内联函数:没有栈帧的开辟及回退。

4、内联函数和static函数的区别
static函数:生成符号、符号属性;需要开辟栈帧,清理栈帧(栈的回退)。
内联函数:不产生符号;没有栈帧的开辟及回退。

static和inline函数的相同点:都只能在当前文件中使用。

另:普通函数与static函数的区别:普通函数中的变量是global全局变量,static函数中的是local局部变量。

Q:我们在什么时候用内联函数呢?
A:在栈帧开辟的开销(函数调用的开销)>函数执行的开销时。

最后需要注意的是:1、inline函数只在release版本中生效,在debug版本中的inline函数的调用也需要栈帧的开辟和回退。
2、inline函数只是对编译器的一个建议,最终能不能起作用是由编译器来决定的。比如:inline函数对递归函数不起作用,因为不知道需要展开函数几次。

三、函数的重载
c语言:函数产生符号由函数名称决定,所以函数的定义不能重名,否则出现重定义。

C++:函数产生符号由函数名称+形参的类型+形参的个数决定。函数定义可以重名,但前提是函数的参数不能完全相同。
例如:

bool compare(int a,int b)
{
    cout<<"compare(int,int)"<<endl;
    return a>b;
}

bool compare(double a,double b)
{
    cout<<"compare(double,double)"<<endl;
    return a>b;
}

bool compare(char* a,char* b)
{
    cout<<"compare(char*,char*)"<<endl;
    return strcmp(a,b)>0?true:false;
}

int main()
{
    compare(10,20);
    compare(10.5,20.6);
    compare("hello","world");
    return 0;
}

上方的函数在C语言中不能编译成功,因为函数重定义了。
而在C++中,三个函数名称分别为:compare_int_int;compare_double_double;compare_char*_char*

所以,1、我们把函数名相同,参数列表不同的函数称为一组重载函数。2、重载必须处于同一个作用域中。例:如果在主函数中加入一行函数声明

int main()
{
    compare(int a,int b);
    compare(10,20);
    compare(10.5,20.6);
    compare("hello","world");
    return 0;
}

再编译时就会出现类型无法转换的情况。

如果将以上代码改为

bool compare(int a,int b)
{
    cout<<"compare(int,int)"<<endl;
    return a>b;
}

bool compare(float a,float b)
{
    cout<<"compare(float,float)"<<endl;
    return a>b;
}

bool compare(char* a,char* b)
{
    cout<<"compare(char*,char*)"<<endl;
    return strcmp(a,b)>0?true:false;
}

int main()
{
    compare(10,20);
    compare(10.5,20.6);
    compare("hello","world");
    return 0;
}

编译时就会出错,不知将10.5和20.6转换为int还是double类型。
这里写图片描述
箭头所指的线路都是编译器默认会选择的优先转向。
比如short类型参与运算时,都会默认转换成int型计算,最后再将结果转化为short,这样做是为了提高精度。

为了更好的理解,下面举出一个例子:

unsigned int a = 1;
char b = -1;
char c = a>b?'a':'b';//b
cout<<c<<endl;

unsigned short a = 1;
char b = -1;
char c = a>b?'a':'b';//a
cout<<c<<endl;

四、C与C++的相互调用
1、C++转C(看得见源代码)
这里写图片描述
2.1、C转C++
这里写图片描述
2.2、C转C++(看不见源代码)
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值