习惯了使用VS的编写C/C++的学习者,都知道VS在新建源文件时如果不指定扩展名,新创建的默认源文件扩展名是.cpp,这种情况在编写C++程序时也就无所谓了,但是如果在编写C语言程序仍然采用默认的.cpp后缀名大部分情况下也是没有问题的(C++兼容C)。我也是一直使用的这种方式在写C语言代码,因为写得比较少也没有过多深究这里边的区别。但是隐患是潜伏的,今天就爆发了!这种习惯要不得,是C代码就要用.c后缀,是C++代码就要用.cpp后缀,不要混用。
int entry(void)
{
int num = 0;
printf("Your number is : %d",++num);
char ch = 'a';
for( int i = 0; i < 10; ++i )
{
//do something
}
}
上面这段代码在VS的C++工程中运行是没有问题的,但是如果你用VS写的是C工程,编译时绝对会出现错误提示。
因为C语言标准要求在代码块中所有变量的定义一定要放在代码块的开头处,而C++标准则认为这种要求很不合理,所以C++代码中对变量的定义可以出现在代码块的任何地方,在任何你需要的地方都可以定义变量。习惯了编写C++代码的朋友如果突然写一些C代码肯定适应不了。因为上面的代码在使用VS的C编译器编译时可定会报错,经验不足的学习者可能会被这个错误提示弄得不知所措,并不知道为什么错了,代码明明没什么问题!!
VS的C编译器编译上面那段代码会有错误提示,但是如果你使用GNU的GCC编译器情况就不一样了。当你使用:gcc -c -o entry.o entry.c命令编译时是能顺利通过的,因为GUN GCC的gcc编译器对C标准的这个要求做了适当的优化(并没有遵循这条标准),其gcc和g++编译对代码块中变量的定义位置都是没有要求的。
如下代码在GCC编译器中编译没有问题:
#include <stdio.h>
int compares( void const *First, void const *Second );
int main( )
{
int ( * ptr_compar ) ( void const *, void const * );
ptr_compar = compares;
int state = 1;
while( state )
{
int first =0, second=0;
printf( "Input two interget num:" );
scanf("%d%d", &first,&second );
state = ptr_compar(&first,&second);
}
return 0;
}
int compares( void const *First, void const *Second )
{
if( *(int *)First > *(int *)Second )
return 1;
else
return 0;
}
编译,连接,运行:
G:\MinGW>gcc -c -o compare.o compare.c
G:\MinGW>gcc -o compare.exe compare.o
G:\MinGW>compare.exe
Input two interget num:3 2
Input two interget num:2 3
今天在此留下只言片语供遇到相似困惑的朋友提供帮助。
更新:
2015-04-21 第一次更新
造成上面这个现象的原因是VS2010及以前的C编译器没有完全支持C98标准。在C98标准中添加了新标准—— 变量的定义可以出现在函数体的任何地方,而不必全部写在函数体的开头位置。