当前位置:编程学习 > C/C++ >>

C++ VS C#(6):入口函数,改变形参数值

 //=====================================================================
//TITLE:
//    C++ VS C#(6):入口函数,改变形参数值
//AUTHOR:
//    norains
//DATE:
//    Wednesday  16-January-2011
//Environment:
//    Visual Studio 2010
//    Visual Studio 2005
//=====================================================================


1. 入口函数

     入口函数是一个应用程序的执行时的入口点,当该函数执行完毕时,那么该程序也就结束了。

     对于C#来说,这个是一个很简单的事情,入口函数就是Main,它有四种形式,如:
static void Main()
static void Main(string[] args)
static int Main()
static int Main(string[] args)

     为什么前面都带有static修饰呢?因为C#是纯粹的面向对象的语言,一切都包含在类之中,增加static标识是为了说明这是类的函数,而非成员函数。

     而如果是C++,那么情况就比较复杂了。如果是普通的C++程序,或DOS程序,那么入口函数就是main。也就是说,形式如下:
int main()
int main(int argc,char *argv[])

     看到这里,熟悉C++的朋友可能会觉得奇怪了,C++没有返回值为void的么?如果严格根据C++98标准的话,标准里确实只是写了这两个形式而已。可能有朋友又发问了,那为什么我返回值为void的时候,还是能正常编译通过呢?这个其实是和编译器有关。比如,当返回值为void时,用VC6.0就能编译通过,而g++3.2根本就无法通过。

     编译器的区别还不是麻烦的终点。如果你是在Windows环境下,那么入口函数就不再是main,而是WinMain!是不是有点匪夷所思?同样是C++程序,换了系统,居然连入口函数都改变了。但实际情况就是如此。

     WinMain函数的形参比main函数多了两个,并且形参还不能为空,其形式如下:
int WINAPI WinMain( HINSTANCE hInstance,
      HINSTANCE hPrevInstance,
      LPTSTR    lpCmdLine,
      int       nCmdShow)

     完了么?如果你以为这已经是结束,那么你太小看Windows下的C++了。因为随着Windows从16bit到32bit的迁移,C++的入口函数也开始发生变化。在VC6.0里,你可以使用WinMain,但如果是VS2005,并且编译环境是UNICODE的话,那么你需要使用的是:wWinMain!

     理由很简单,在ANSI环境,入口函数是WinMain;但在UNICODE环境,却变成了wWinMain!能不能在代码里直接兼容这两种环境呢?可以,但你需要将入口函数改为_tWinMain!

     _tWinMain是什么东西,有那么大的威力?其实它只是一个宏,在TCHAR.h文件中定义:

//TCHAR.H
#ifdef _UNICODE
#define _tWinMain wWinMain
#else
#define _tWinMain WinMain
#endif

     看到这,就明白为什么能适应不同的编译环境了吧?

2. 改变形参数值

     在C++里,如果想传入形参的数值,那么有什么方法呢?方法有两种,一个是指针,另一个是引用。

     以例子来说明比较直接。我们需要一个函数,用来交换传入形参的两个数值。这是一个很简单的例子,不是么?

     假设代码中声明了如下两个变量:
int a = 10;
int b = 20;

     采用引用方式的如下:

void Swap(int &a,int &b)
{
 int tmp = a;
 a = b;
 b = tmp;
}
//直接传入形参即可
Swap(a,b);

     如果是指针的话,那么也是很简单的:

void Swap(int *pA,int *pB)
{
 int tmp = *pA;
 *pA = *pB;
 *pB = tmp;
}

//调用时用&符号来表示这是指针
Swap(&a,&b);
 

     引用和指针这两种方式有什么区别呢?如果是从功能的角度,没有任何区别,它们都能够完成交换的任务;而如果从哲学的角度,那么采用指针的方式可以表明形参可以为NULL,而引用则表示形参绝对不能为NULL。这是不是有点玄乎?没办法,C++的复杂性就表现于此。与其说C++是一门语言,不如说其是一种信仰,一门哲学,可能更为恰当。如果简单点来说,为何C++存在这两种方式,追本溯源的话,其实是要和C兼容。引用是C++引进的新特性,在C里面是没有的。如果C要更改形参的数值,那么就只能使用指针。为了兼容C,那么C++肯定无可避免也存在着指针改变形参的方式。

     但如果到了C#的话,因为取消了指针,所以它就只剩下引用这种模式。当然咯,C#的引用和C++的写法是不同的,C++用&符号表示,而C#用的是ref关键字。而最大的区别还在于函数的调用,C++是直接输入变量名,而C#则必须增加ref关键字。相应的代码如下:

static void Swap(ref int a, ref int b)
{
int tmp = a;
a = b;
b = tmp;
}

//调用时必须带有ref关键字
Swap(ref a,ref b);
 

     初看起来,C#调用引用的时候需要增加ref关键字显得略微繁琐,其实在实际的使用过程中,这略微的繁琐却带来更明晰的含义。比如,在C++中如果你仅仅是查看函数的调用:Swap(a,b),你能判断得出a和b这两个形参是否会被改变么?因为无论是否引用,其调用方式都是一样的,所以你必须要返回查看Swap的定义你才能确定。而这歧义在C#中根本就不存在,Swap(a,b)这语句绝对不会改变a和b的值;如果存在改变的可能,那么必定使用ref标注,也就是Swap(ref a,ref b)的调用方式。

 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,