一段代碼,為什麼在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 |