C与C++函数的不同特性

        C与C++函数最大的不同点在于——C++函数可以重载,即几个函数的函数名可以相同,但是参数类型或参数个数必须不同;而C函数在一个环境中不能同名。这其中可以引申出关于为什么C++的类型安全机制比C更好的原因。先请看下面的代码:

 

//  a.c

#include 
< stdio.h >


void  Hi( void )
{
    puts(
"Hi");
}



void  test( void )
{
    
void *= &Hi;
    
    (
*(void(*)(void))p)();
}

         上面是一段C代码。我们可以看到test()函数中有一个void指针指向Hi函数,这不会有任何问题(没有error和warning)。

        下面再看一段C++代码:

 

#include  < iostream >
using   namespace  std;


void  Hello( void )
{
    cout 
<< "Hello, world!" << endl;
}



void  Hello( int  i)
{
    cout 
<< "The data is: " << i << endl;
}



extern   " C "   void  test( void );

int  main( void )
{
    
void(*p)(void= &Hello;
    
    (
*p)();
    
    
void *= (void*)(unsigned long)(void(*)(int))&Hello;
    
    (
*(void(*)(int))q)(10);
    
    test();
    
    
return 0;
}


 

        我们看到这段代码中有两个Hello()函数,一个带有一个类型为void的参数,而另一个带有一个类型为int的参数。我们看main()函数的第一句:void(*p)(void= &Hello;这句语句没有问题。因为C++编译器与C编译器不同,在这种情况下,编译器将根据左操作数的类型去跟有操作数的类型进行比较,因为Hello()函数集合中确实存在(void(*)(void))类型的函数,因此匹配成功。

        如果是void *p = &Hello;那么编译器肯定出错。我们可以简单地理解为编译器无法识别所取的Hello函数的地址到底是哪一个。其实利用上述思路我们应该正确地理解为:由于编译器无法在Hello集合中找到void*类型与左操作数的类型进行匹配,所以编译器会报错。

        解决这个问题的方法就是通过多次的类型强制转换。这里还有一个GCC系列编译器的问题。该系列的编译器规范指出,void*类型的指针不能指向函数,因此如果单纯地强制转为(void(*)(int))编译器会有warning,所以这里先转为(void(*)(int)),然后再转为(unsigned long),最后再转为(void*),这样就不会产生warning。

        而C语言编译器不会有类型查找,它直接比较左操作数和有操作数的类型一致性问题,并且放得很宽。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值