一段代碼,為什麼在linux下可以編譯運行,而在vs2013就不行?

如題,最近看高一凡的《數據結構與演算法解析》,書里給出的代碼在linux下可以編譯運行,但是換到vs2013上就有各種奇怪的問題。

重要的是,按照書上的說法,代碼稍作一點修改,就應該是在vs6,cv6,linux上都可以正常編譯運行,(比如linux上main函數返回int),但是vs2013上出現的問題讓我大寫的懵逼(百度上有人可以編譯運行,有人給了解決方案,但是並不能解決)。

所以,我很好奇,同一代碼(稍作修改後的),為什麼在不同平台,編譯結果如此不同,還是我是新手,忽略什麼。求解

另外,平時多用linux,vs系列很少用。


我看到你的ElemType是定義在cpp文件里的,而在.h文件里引用


更新一下,之前沒有展開看你的圖,因為你說在linux下面可以跑起來,所以我覺得代碼層面應該沒有問題。

但是仔細看代碼

你這個確實是聲明的地方有問題

這個typedef的位置你應該放在頭文件裡面,不然預處理的時候沒有辦法找到定義

在linux可以編譯通過我持懷疑態度,可能和編譯器的順序有關

-----------------以下是原答案------------------------

謝邀

你在linux下面編譯運行應該寫了Makefile或者是gcc -o之類的吧。

windows上面你應該沒有寫吧

但是不寫,你要通過工程屬性告訴編譯器這一切,我猜測應該是文件包含路徑之類的沒有弄好吧


你這代碼用 gcc 一樣編譯不過

#include 相當於查找替換,把頭文件整個複製到 include 那一行的位置

然後再看你的 main2-1.cpp,ElemType 的定義在第七行,而struct SqList 的定義在第二行 #include "c1.h" 的位置,也就是 ElemType 的定義之前,不滿足 c++ 語言先定義後使用的要求

用 Visual Studio (VC6 不叫 Studio)編譯正確的、不使用第三方庫(含 Win32 / POSIX API)的 c++ 代碼,在選對了語言版本的情況下,一般只會遇到不允許使用 scanf 這一個問題,除此之外基本上都可以確定是你的程序寫錯了


謝邀。

個人認為,是連接器的優先順序處理有點問題。

推薦把預處理、typedef 等放在一個文件中,並保證對該文件的引用在全文最開始。

比如將 typedef 那個語句剪到 c2-1. h 裡面,第五行的位置。


不如上傳github,連帶makefile和VS工程文件,這沒法看。

話說代碼縮進和空格寫這樣不難受嗎。一般這種代碼亂七八糟問題和隱患都很多。


簡單粗暴的解決方法:

把所有代碼都寫到一個cpp里,不要拆分成h和cpp文件,這樣肯定不會有問題的。


我覺得這不是VS的鍋

而是VS功能太強大(手動滑稽

//我只在寫C#的時候用VS

VS確實檢查語法錯誤的時候可能有bug

(或者你代碼本身有問題

在其他IDE試下

比如DEVCPP這種沒有檢查語法的IDE

編譯還不能過的話就代碼有問題了

而且

一個地方語法錯了可能出現奇奇怪怪的報錯

比如你這種就可能是別的原因導致VS不正常


程序有bug的時候,懷疑編譯器是非常愚蠢的做法。PVS-Studio的作者就專門寫了一篇博客,討論「編譯器的錯誤」:在我職業生涯8年中,只看到過一次cl.exe產生了錯誤的彙編代碼。而我的想法是,編譯器幾乎是計算機學科最重要的軟體了,融匯了學術界那麼多大牛的研究成果,又在工業界經過了那麼多年的驗證,幾乎是不可能出錯的。c++標準規定了什麼,編譯器就肯定能實現什麼,vs是這樣,clang是這樣,gcc也是這樣。說句不太好聽的話,那麼多大型實用的程序都能編譯好好的,難不成你我隨手一敲幾行代碼,就能找出編譯器的bug?

然而c++確實太艱難了,初學者在充分理解之前,很容易寫出奇奇怪怪的代碼,運行出自己無法解釋的結果。他們在反反覆複查閱思考,苦苦冥想之後依然搞不清楚,於是只好把錯誤歸結到編譯器上。他們還會爭辯,「明明在另一個系統上編譯得好好的」,「明明昨天還能運行」。有這種想法也是人之常情,但對解決問題毫無益處。越是困惑不解,就越要相信問題一定是出在自己的代碼身上。就像小說里大偵探破案那樣,真相只有一個,而真相水落石出之時大家都會發出哇的一聲:原來事實一直那麼明顯地擺在眼前,只是我們視而不見而已。

可是這個時候我們怎麼做才好呢?我覺得比較好的辦法是,第一,翻翻書增長自己的知識水平,要是程序乾脆編譯不通過,就去搞搞清楚預處理,編譯,彙編,鏈接,運行時發生了什麼,看懂報錯信息;第二,你要是懷疑代碼哪裡有問題,就另外寫一個小的代碼塊驗證一下唄,所謂大膽假設,小心論證嘛。

各位看客一定在覺得我滿嘴跑火車,到底也沒有解決題主的問題嘛。其實恰恰相反,我覺得最重要的都已經說了。

寫程序是臟活,腦袋多疼幾次,走點彎路,是好事。


這個問題錯的不應該。說明你的工程思維很差。

解決辦法一:c2-1.h文件包含main2-1文件,但不建議。

解決辦法二:將typedef去掉,直接用原類型。也不建議。

解決辦法三:在h文件中聲明,在cpp文件中包含h。

終極方法:學習編繹相關理論,學習軟體工程理論,工程文件組織方法,再自己定義一個文件組織規則,磨刀不誤砍柴工。


類型聲明,函數聲明都應寫在.h中。

另外,不應在.h中定義函數,應該只在.cpp或.c中定義函數。否則在重複引用.h時會出現鏈接錯誤。

題主自己造幾個輪子,並且使用自己的輪子,慢慢就知道怎麼寫了。


你這代碼能在linux跑起來?

你是用g++加參數直接編譯的,還是用的cmake ?或者說用的書提供的常式模板?

我感覺代碼的聲明位置有問題,


樓主問的可是"程序員的自我修養—鏈接與庫」? 嗯,我想是的!


這不是vs的鍋,就算這代碼可以跑在gcc下,也不能否認這骨骼驚奇的代碼組織防止。

typedef int ElemType;

類型別名聲明,這明顯應該放在 .h 頭文件里,如果是放在c、cpp源碼文件中,要將這句放在所用到的頭文件的前面。

/** main2-1.cpp */

typedef int ElemType; // 放在這裡

#include "c1.h"
#include "c2-1.h"

......

雖然可以編譯,但這對工程組織來說非常糟糕。


C語言沒有引用

找不到類型,親,你有聲明嗎?


推薦閱讀:

每個開發人員應該知道的 10 個 Linux 命令
PHP在IIS8 Apache Nginx 哪個性能更好?
為什麼說Arch Linux的pacman包管理系統更先進?相比與apt或rpm等好在哪裡呢?
RHCE(Red Hat Certified Engineer)紅帽認證工程師在面試的時候作用有多大?
MIUI V6 引入的Linux系統內核內存優化技術分別是什麼?

TAG:編程 | Linux | MicrosoftVisualStudio |