ACM提交,C++,G++,C,GCC的区别

今天做了一道水题,POJ-1004,水题一个,12个double类型的数求平均数

但是,

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 int main() {
 5     double n;
 6     while (cin>>n) {
 7         int i=0;
 8         double total = n;
 9         while (i++<11) {
10             cin>>n; 
11             total += n;
12         }
13         printf("$%.2lf\n", total/12);
14     }
15     return 0;
16 }

这个看起来没毛病的代码,竟然WA了,

又WA两次之后,这不是代码的事,分别用GCC,G++,C++提交,到C++的时候,A了!!!

 

总结总结,避免再犯

------------------------------------------------------------------------------------------------------------------------

放在最先:G++和GCC分别是C++和C的编译器,C++和C是语言。

但POJ上的则表示你提交代码运行所需的编译器,C和C++对应的编译器是VC++ 2008里面的C和C++编译器,而GCC和G++则对应相应的编译器。

那我上面既用了printf又用了cin怎么提交?

看到一篇博客叙述:G++和C++选项下的代码是没有差异的,但在库上面,两者有一定差距,比如G++默认可以cin一个string变量,而选择C++时则需要#include<string>,如果用C++编写代码,提交时最好选择G++作为编译器。

不好意思,我没用string类, 但是G++提交WA!!!

说明区别不止这一点。

------------------------------------------------------------------------------------------------------------------------

为什么G++提交WA了?

好吧回到现实中来。我昨天在做poj 3122这道题的时候,再一次的遇到了G++WA;C++AC的尴尬局面。

为什么呢?其实这个也算是编译器优化的一部分,那就是精度缺省。

众所周知,long long类型,作为一个在C/C++11才被确认为基本数据类型的一个数据类型,在不同的环

境下,他的类型标识符是不同的。也就是我们津津乐道的%lld 和 %I64d了。同样,double类型也是一

个有趣的类型。double类型其实准确地说是双精度型,他的内存长度一般是比float类型(单精度型)

的多了一倍,有的时候很早的标准里是把double称为long float的。所以说就有了为什么float类型

用%f,double用%lf。但是由于现在不是以前的那种一个内存条就几兆,多开一个double就会超内存的

年代了,所以double还有float在gcc中被自动优化。

在用scanf读数据时,为了与float区分,使用%lf。

在用printf写数据时,由于实质上,double和float是同一个类型,只不过内存占用有差异而已,他们

的标识符都是%f,注意,这个和标准C不同,这里的都是%f。

当然对于另外一个特殊的类型long double虽然不常用,但是编译器依旧在支持,这里有个插曲,理论

上long double应该是两倍的double(类似long long和int的关系,因为long和int其实是一个东西)

。但是实际上,long double很奇怪的是一个10字节的怪物,他有两个空余字节,是怎么改动都不会发

生变化的。输入输出的标识符都是%Lf,大写的L。

 

但是这里又有问题了,为什么我在本地用%f会WA,在OJ上用%f会AC?

因为我们本机如果使用的是Windows下的Code::Blocks这款IDE的话,编译器也就是MinGW这个东西。事

实上,为了尽量保持gcc的跨平台性,MinGW在某些地方是直接用了MSVC的东西的,而对我们影响最大的

就是这个标识符的问题。简单的说,如果你是要在本机测试,那么最好,请使用标准C的那个标识符系

统;如果你要提交代码,那么请改成gcc的那一套标识符系统。

再有就是编译器版本的问题,现在的MinGW版本已经到了4.8,但是POJ上仍然使4.4,所以低版本的编译

器同样会有一些不寻常的问题。

当然还有更简单的方法,就是直接用输入输出流在控制输入输出,这样更省事,而且跨平台性能更好,

不会出现这种因为标识符而出错的情况。

列个表格出来就是这个样子的:

列个表格出来就是这个样子的:

double f; POJ G++提交 POJ C++提交 本机测试(MinGW GCC 4.8) 最安全的方法
输入 scanf(“%lf”, &f); scanf(“%lf”, &f); scanf(“%lf”, &f); cin >> f;
输出 printf(“%f“, f); printf(“%lf”, f); printf(“%lf“, f); cout << f;

------------------------------------------------------------------------------------------------------------------------

原来还有精度的问题,那么总结:

1.用string的时候,c++需要包含头文件:#include <string>,G++不需要

2.精度问题

3.使用GCC/G++的提醒:

对于64位整数, long long int 和 __int64 都是支持并且等价的.但是在读和写的时候只支持scanf("%I64d", ...)和printf("%I64d", ...).

不支持"%lld"是因为MinGW下的GCC和G++使用的msvcrt.dll动态链接库并不支持C99标准.
根据ISO C++标准,在G++下,main函数的返回值必须是int,否则将会导致Compile Error(编译错误)的判答

4.G++/GCC使用scanf、printf时注意引用<stdio.h>/<cstdio>,只引用<iostream>不识别

 

posted @ 2018-05-04 10:48  朤尧  阅读(3307)  评论(0编辑  收藏  举报