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>不識別

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM