-
1 # 鼴鼠科技
-
2 # 特修斯的宇宙
第一次聽到說c c++不能跨平臺!?
現在的小朋友只接觸過指令碼類語言就來談跨平臺了,殊不知你說的那些可以跨平臺的指令碼類語言基本就是c c++打的底。
-
3 # 散居獵人
你確認自己知道什麼是編譯器嗎?
如果廠家願意做,什麼語言開發軟體都可以跨平臺!!!
不能簡單說c語言,你要說的是windows7 32位的vc源程式,是不是可以不用改動或少許改動用在 安卓5.0上? 這樣問題才明確。
c和cpp都是可以跨平臺的,但改動是必要的。
比如 cpp builder 10.3可以跨平臺支援幾種主流作業系統。
-
4 # 超神時代0
c語言編譯是把c原始碼翻譯成計算機可以識別的二進位制機器碼的過程,編譯器相當於翻譯器,所有的程式如果要執行都是透過作業系統執行對應的機器碼的,不同的系統執行方式是不同的,所以要在不同系統中執行程式,原始碼一般不需要重寫,但是需要重新翻譯成新的系統可以識別的格式,所以需要使用對應系統的編譯器重新進行編譯。像JAVA這種號稱跨平臺的語言實際上是依靠在JAVA虛擬機器上執行編譯後的檔案做到的,把原始碼編譯成所有系統的虛擬機器都可以執行的檔案,但是執行虛擬機器會有一定的效能開銷。型別js或Python這類解釋型語言需要在直譯器上直接執行的,其實和JAVA虛擬機器類似,只是沒有了編譯這一步,原始碼可以直接執行在直譯器中,相對應的執行速度也會更慢一點
-
5 # 繁星落石
編譯器是單獨的一段程式,不在程式裡面,因為編譯器對開發環境有依賴,不同的軟硬體環境對編譯都有影響。另外不能跨平臺是因為程式編譯以後是二進位制可執行狀態,但是換到另一個平臺的時候這段二進位制程式碼可能並不會被識別出來,所以不能跨平臺,需要使用目標平臺的配置環境提供給編譯器來使程式正常在目標平臺執行。
-
6 # 光明右使8787
誰要跟你說C不能跨平臺,你把他拖出來打一頓。除了彙編,幾乎所有的高階語言都是跨平臺的,連作業系統都能跨平臺。C可以在任何一種作業系統和CPU平臺上編譯,包括大部分嵌入式CPU。只有一些極為小眾的微控制器晶片沒有提供C編譯器。編譯器不是作業系統提供的,是CPU廠家提供的。任何一家CPU廠商,可能不提供GO編譯器或其它編譯器,但必定會提供C編譯器。
-
7 # 智慧情感里奧
不同角度看,C跟C++寫的程式碼也能跨平臺複用。
說C跟C++不能跨平臺,是說編譯生成的執行程式是不能跨平臺c跟C++,下面統稱C,在各作業系統中生成可執行檔案。就需要經過編譯器編譯,連結,生成本地執行程式。
1)連結過程就可能用到作業系統的介面,比如Windows上DLL,動態庫,這些庫裡是系統提供的功能,比如音訊播放。
比如在Linux上會是個so庫。
2)比如作業系統可能是32位作業系統,也可能是64位作業系統。
這樣編譯過程中,為程式分配的堆疊跟儲存空間,都會不一樣。
程式碼本身,如果寫的基礎功能,在不同平臺上也是可以複用的好的工程程式碼,設計系統的時候,都儘量考慮跨平臺可複用性。
比如影象處理,C程式碼層呼叫OpenGL,那麼絕大部分程式碼是可以複用的。加一個開關就可以切換呼叫不同平臺的庫,可以用在Windows、Linux、還有各個手機作業系統上。
程式碼儘量考慮系統相容性跟模組化模組化的程式碼會是優質的程式碼。
為什麼C工程師能越老越吃香,因為積累了大量的優質功能程式碼。可以簡單編寫解釋型程式碼如JAVA,透過JNI來呼叫庫,又高效又快捷。
以上是對問題的理解,一起加油。 -
8 # 老夫渡劫
跟不同作業系統提供的系統呼叫不同有關係,也跟你寫的程式碼是否有涉及到這些不同的實現有關係,跟編譯器反倒關係不大。不同作業系統的核心實現方式是不一樣的。如果想要跨平臺,就需要為不同的目標系統準備不同的程式碼。
-
9 # 使用者70530252951
C語言誕生於貝爾實驗室,目的就是為了跨平臺。
編譯器已經把程式翻譯成機器程式碼了,編譯器的工作已經完成。鍋裡飯已經做好,你在哪吃什麼時候吃你隨便,難道非要帶著鍋嗎
-
10 # john1127
語言與平臺無關,但如果程式內含有對特定作業系統比如Linux的api呼叫,則無法跨平臺到windows,因為win實現同樣功能的介面可能完全不一樣。
而呼叫api一般是無法避免的,特別是圖形介面、底層硬體訪問相關部分
如果不含有作業系統api呼叫,那麼只需要在其它作業系統上重新編譯一下就可以了
-
11 # 愛思考的奧特曼
首先我們糾正一下題目中一個小小的誤區,不是C和C++不能跨平臺,應該是說是C/C++原始碼在編譯後生成的
.exe
檔案不能跨平臺,原始碼和可執行檔案要區分開來。想要搞明白這個問題,我們先得了解一下原始碼是怎麼變成程式的。
四個過程:預處理——編譯——彙編——可執行檔案當我們編寫完程式碼後,原始碼會經過上述的四個環節,最終變成常見的可執行檔案。
預處理階段(hello.i):在原始碼中會有標頭檔案,一些宏,註釋等。預處理的目的就是將標頭檔案展開,宏檔案代換,去掉註釋等,對程式碼進行一些初步的處理
編譯階段(hello.s):這一階段主要是檢查語法上的錯誤,比如記憶體有沒有溢位,指標有沒有指錯物件,然後生成可彙編檔案。
彙編階段(hello.o):計算機是不認識程式碼的,所以需要將彙編程式碼轉換成0和1組成的機器碼
連結(a.out):連結有兩種情況:靜態和動態。靜態庫和應用程式編譯在一起,在任何情況下都能執行;而動態庫是動態連結,檔案生效時才會呼叫。最終生成一個可執行檔案。
編譯器的作用我們不要把編譯器想的太厲害,覺得編譯器是萬能的。實際上編譯器就像是一個翻譯,負責把高階語言轉變成機器能看懂的低階語言,翻譯過程就是上述的四個過程。但是其中有一點需要格外注意。那就是不同的公司使用的指令集不同。輸出程式的格式和CPU使用的指令集有關,比如X86,arm,還有MIPS等等, 由於設計思路的差異,所以不同平臺上編譯生成後的可執行檔案格式是不一樣的,可能在ubantu裡能執行的C程式,放到windows下就會報錯。
類比一下java,為什麼說java可以跨平臺,是因為java內建了一個虛擬機器,程式都從虛擬機器中跑的,所以有人說“java不僅是一種語言,更是一個平臺”。
綜上所述,C/C++的一些基礎性程式碼是可以跨平臺的(可能會受API影響),是生成的可執行檔案不能跨平臺,C/C++不自帶編譯器,不同平臺下的編譯器存在差異。
-
12 # 大學生程式設計指南
從事軟體開發多年對於C/C++用的比較多,可以明確說這兩種程式語言也是支援跨平臺,肯定還是有很多人問什麼是真正意義上的跨平臺,所謂的跨平臺就是同一套程式碼在不同的作業系統都能直接去執行,這裡面涉及到一個很重要的問題,在java這門程式語言剛開始流行的時候就提到了跨平臺的功能,在windows上執行的jar包直接放在linux上也能直接去執行,單純從C/C++角度出發也是能夠實現這種功能的,因為其語法實現是相同的。
但在具體實施操作過程中還是多少有些差異,特別是涉及到作業系統介面等方面,畢竟linux和windows程式設計給出的api的介面還是存在一定的差異,所以單純的談跨平臺還是有點差異,針對這種情況一般在軟體架構裡面會區分出很多的平臺程式碼,在具體軟體的核心架構上程式碼是一致的,和平臺相關的程式碼還是需要單獨去實現,就拿簡單的執行緒的實現,不同的作業系統的介面就存在很大的差異,所以完全意義上的跨平臺方面距離高階程式語言還是存在差異。
談到編譯器就需要了解程式執行的原理,現在計算機的架構都是基於馮諾依曼的架構來完成的,具體執行的格式都是二進位制的格式,不同的作業系統生成不同格式的二進位制檔案,從程式碼到可執行的二進位制程式碼之間還需要有一種工具存在,這就是編譯器存在的價值,編譯器的執行中也是分為幾個階段,對於linux下C語言編譯過程有所瞭解的話,都會發現字尾為
.c
的程式檔案首先轉化成.o
的中間檔案,然後經過.o
轉化成可執行的二進位制檔案。編譯器其實就是一種轉化工具,將程式轉化成能夠執行的二進位制檔案,一般而言C/C++編譯器是可以通用的,不同的作業系統使用不用的編譯器底層。編譯器是一種工具包的集合,內部的實現也涉及到C/C++的程式設計,編譯器的通常說的程式設計程式碼還是存在一定的差異,編譯器是為程式碼轉化做服務的,真正實現跨平臺的基礎部件編譯器算是一種,因為不同的作業系統或者計算機架構需要具體的對應實現,雖然對於高階語言來講不需要關心底層如果來實現的,但是總得有人去操作這件事,相對來講java語言這方面做得比較徹底,直接透過一個虛擬機器來完成遮蔽,虛擬機器裡面相容了市面上常見的作業系統,這樣就能夠真正意義上做到了程式語言的跨平臺。
越是底層程式語言和平臺關聯越大,關心的細節也會越多的,底層語言的開發難度相對大一些,特別是涉及到平臺的指標等方面關心的硬體細節,所以對於底層程式語言積累的時間需要比較長,想對比其他高階程式語言還是難度大一些,特別是在入門的時候顯得困難一些,但是入門之後會更加有意思。
-
13 # 冬凜
是的,編譯器不但要依賴和匹配系統,還要依賴和匹配cpu等硬體,c和c++本身也是程式,編譯環境的執行需要系統和底層硬體的支援,在這個基礎上才能執行c和c++編譯環境去編譯和執行原始碼
-
14 # 苦苦tt
編譯可以認為翻譯。
c/c++編譯相當於翻譯文獻,翻譯後,儲存翻譯後文獻,也就是,不同國家(執行平臺),翻譯最終文獻不一樣的。
類似java,python,PHP,相當於同聲翻譯,直接現場翻譯,哪個國家人需要,使用哪種語音翻譯。
-
15 # BreezeMaker
編譯器只是把你的程式分析下,根據語意生成可執行的二進位制檔案。編譯器只是個軟體,編譯器可以用c寫然後用於編譯c,這叫自編譯。c/C++是可以跨平臺的,只是需要用編譯器重新編譯下,畢竟和硬體強相關,不像python解釋性語言那樣完全跨平臺,之所以它跨平臺,那是因為他的直譯器是用c|c++寫的在不同的編譯工具下重新編譯部署了而已。
-
16 # 肚子有個咕嚕雞
編譯器那可以想象為一個翻譯官,將你的文字流變成二進位制流,他可以在不同的平臺上工作,有些編譯器在win上生成mac上的程式碼。
c 跨平臺的意思 原始碼可以跑不同機器上編譯為不同的東西,而不是編譯出來的東西跑不同機器上都可用。實現後者的目標是Java
-
17 # 劉氓兔
瞎說,誰說的C/C++ 不能跨平臺?還有說語言和平臺無關。。。也是瞎扯。
1,首先,開發語言基於某些通用標準來設計的,標準庫函式都一樣,但是各個系統(Windows,linux,Unix,BSD,iOS)等系統呼叫,系統函式是不一樣的,你在開發的時候,就必須做不同系統函式的適配。這就是跨平臺。
2,開發語言,和系統有時候息息相關,如微軟開發套件就不能在非Windows系統上執行(據說微軟正在做跨平臺修改)。
3,跨平臺做得最好的是JAVA,用JAVA虛擬機器來實現跨平臺,而程式碼執行在虛擬機器上。
-
18 # 商君2
估計你是小白,c和c++都可以跨平臺,但是同樣的程式碼執行的時候不能跨平臺。因為c和c++是直接編譯執行的不同系統相同的操作的API都不同。相對於可以跨平臺的JAVA少了執行適配的過程,這一步JAVA是有虛擬機器代勞的。編譯器有好多的,c有編譯器,JAVA也有編譯器,兩者是不同的,JAVA是在c和c++的基礎上又封了一層實現的跨平臺。程式是程式編譯器是編譯器,編譯器是程式到彙編的一個橋樑,經過編譯了程式才可以背計算機讀懂,才能執行CPU或是記憶體的指令。c或c++編譯器在系統裡,JAVA以及別的是在虛擬機器裡,包括node或是Python,只要你配環境變數的都是
-
19 # 江南一散人
程式的可移植性,本質上與實現它的程式語言無關。需要區分兩個概念:程式語言和語言的實現。
程式語言我們通常說的C/C++、Java、Python、JavaScript等程式語言,其實是指語法和語義上的一種規範。這種規範,定義了編寫程式時必須要遵循的一種書寫規則,只有符合規則才能被編譯器正確識別和理解。
語言的實現語言的實現,通常指的就是編譯器了。對於同一種語言,不同的編譯器可以有完全不同的實現方式。
以Python語言為例,就有很多種大相徑庭的編譯器實現。
CPython - 解釋執行。PyPy - JIT執行。Jython - 把Python原始碼編譯成Java位元組碼,然後再Java虛擬機器裡執行。C/C++也是一樣,有很多種不同的實現,不過目前主流的實現,全都是編譯成二進位制的機器碼執行的。但是,其實網路上也有很多C/C++的直譯器,就是直接把C/C++的原始碼解釋執行的。
我目前正在開發中的一個編譯器專案,就支援C語言的絕大部分語法,目前的實現,也是解釋執行的。
瞭解了程式語言和語言的實現後,再來說說程式的可移植性。
程式的可移植性程式的可移植性,通俗來講,就是你在一個環境上編寫出來的程式碼,是不是能夠很方便的把它放到另外一個環境上執行。這裡的環境,包括軟體環境和硬體環境。
軟體環境:通常指作業系統,以及程式所依賴的執行時環境,如系統支援庫等。硬體環境:指程式執行的目標硬體,包括CPU、晶片組、外設等。但從程式語言本身來說,理論上,任何高階程式語言都是可移植的,只不過實現可移植性的方式有所不同。
編寫一次,到處編譯對於C/C++,目前幾乎所有通用的實現都是直接把原始碼編成二進位制目的碼。對於這種實現方式,要想進行移植,就必須要保證在不同的軟體環境和硬體環境下,都要實現相應的編譯器。比如要有Windows+x86的編譯器、Linux+x86的編譯器、Linux+ARM的編譯器等等。也就是編寫一次,到處編譯。
所以,所謂的C/C++程式不能跨平臺,是指被編譯成二進位制的可執行檔案不能跨平臺,而不是C/C++語言本身不能跨平臺。
編譯一次,到處執行而Java則選擇了不同的實現方式。Java典型的實現是,把Java原始碼編譯成位元組碼,然後把位元組碼放到虛擬機器中進行執行。
對這種方式,要實現可移植性,則必須要保證,在每種不同的軟體環境和硬體環境中,都必須要實現相應的Java虛擬機器。
比如要有Windows+x86的Java虛擬機器,Linux+x86的Java虛擬機器、Linux+ARM的Java虛擬機器等。
這些不同的虛擬機器,都遵循相同的Java位元組碼的規範。因此,只要把Java原始碼編譯成標準的Java位元組碼,就可以在所有的這些虛擬機器中執行。
-
20 # X蟈蟈X
《原理》
可執行程式生成的過程如下:
原始碼--->機器碼--->可執行程式
第一步,編寫好的原始碼我們的Cpu是根本不認識的需要透過一個程式(我們所說的編譯器)翻譯成機器能認識的機器碼。
第二步,機器碼只是Cpu能認識,但是也無法直接在作業系統上執行,需要另外一個程式(我們說的連結器),把翻譯好的零散的機器碼檔案組織起來並且新增一個能夠讓作業系統可以啟動執行的入口,這樣才能變成我們看到的可以執行的應用程式。
那麼這裡出現了兩個很明顯的問題,
1,不同的CPU所認識的機器碼不一樣,比如mips和arm,還有x86,那原始碼怎麼可能在完全不同的Cpu上執行?
2,不同的作業系統底部執行應用程式的形式也不一樣,比如windows和linux,那我們的原始碼又如何來適應這不同的作業系統?
《解決方案》
所以就有了現在的兩種解決方案。
1,原始碼一套,編譯器翻譯成對應cpu的機器碼,連結器來組織整理成對應作業系統的應用程式。這樣拿著原始碼就可以到任何cpu和作業系統的組合上去生成可執行檔案。
2,隨著網路的發達,人們發現第一套方案存在一個劣勢(這裡所說是劣勢,不是缺點,因為這就是事實,是硬體導致的),原始碼必須總要在不同的Cpu和作業系統上重新生成可執行檔案,否則無法執行。那當然是一定不能執行的,因為mips的機器碼當然不能執行在arm上,二進位制碼都不一樣;windows的也不能執行在linux上,作業系統的入口也不一樣。
所以人們為了讓不同的程式碼可以省去這個單獨編譯連結的過程,就預先先把可以適應不同Cpu作業系統組合的可執行機器碼檔案生成好安裝到各個系統上(我們所說的虛擬機器),而編寫程式碼者只需要把原始碼編譯成一個偽二進位制碼檔案(說是偽二進位制只是針對二進位制機器碼說的),這個偽二進位制作用是使用預先安裝單各個系統的虛擬機器的,從而實現了看似的跨平臺。
當然如果不生成偽二進位制理論上也可以直接使用在虛擬機器上的,但是因為人書寫的程式碼畢竟比二進位制碼完複雜麻煩,為了效率,先生成偽二進位制執行速度能更快點。
《跨平臺概念》
跨平臺這個概念要看怎麼理解,其實有以下兩種方式,
1,程式碼不變,只要在不同的cpu作業系統組合中生成可執行程式。
優勢:執行效率最高,因為直接生成機器碼。
劣勢:目標機器需要重新用原始碼生成可執行程式。
此即編譯執行,代表就是C/C++。
2,程式碼不變,編譯出偽二進位制檔案,預先在不同的Cpu作業系統組合中安裝好虛擬機器。
優勢:省去了重新編譯偽二進位制檔案的步驟,網路傳播更容易。
劣勢:目標機器需要安裝虛擬機器,否則不能執行,且程式執行效率低。
此即解釋執行,代表Java。
《結論》
所以,C/C++並非不能跨平臺,只是方式比較原始,但是優勢也非常明顯。
隨著網路時代Java的崛起,人們對於跨平臺有些偷換概念,而且很多程式設計師對於程式的執行原理也是一知半解,才會產生這種疑問。
《參考學習書籍》
對於想更深入學習的朋友,推薦兩本書
1,深入理解計算機系統
2,計算機組成與設計 硬體/軟體介面
回覆列表
預處理階段。預處理器(cpp)來把 程式碼中開頭的行進行展開, 比如標頭檔案,宏等內容,修改最初的C檔案。編譯階段。編譯器(ccl)將修改後的C檔案,翻譯成了 另一文字檔案,,這就是我們所說的彙編程式了。 彙編階段。彙編器(as)將翻譯成機器語言指令。 把這些命令打包成一種叫做可重定位目標程式(relocatable object program)的格式,此時的輸出格式就是了。這其實就是二進位制檔案了。連結階段。編譯過程最後還有一個連結階段(程式呼叫了 函式),最後的輸出結果還是和上一步類似,都是直接二進位制檔案。圖2以上就是大家都知道的程式。最終執行的結果 就是在console上輸出一行字串, ,如圖3,4所示,大家可以很清楚的看到X86和ARM不同的編譯結果。而在他們輸入的0和1中,有些代表的是指令,這些是有固定含義和編碼的。也是晶片能識別的。而另一些是資料。這些不同的程式的資料自然是不同的。我們前面就說,不管多麼複雜的計算機操作,到了cpu級別都是0和1,資料雖然多變,但是 指令的數量是有限的。因為 指令是要被晶片固定識別的。晶片中要用 電晶體(最初是電子管)組成的與或非門組合來識別這些指令和資料。因為直接輸入0和1,實在太繁瑣了,所以他們就發明了組合語言。來簡化 程式的編寫。
比如 計算 1+1,兩個 資料1都 使用 來表示,而 加操作,放在cpu中,可以是 (這個是胡亂寫的),這個二進位制代表的加操作能被計算機識別。而因為這個加操作對於cpu來說,編碼的格式是固定的。所以可以直接一個助記符來表示,這樣科學家們寫程式就方便多了,而這就是彙編程式的由來。因為彙編程式完成之後,可以再有一個專門的程式(就是要上文中所說的彙編器)來把編寫的彙編程式編譯成0和1.這樣計算機也可以識別了,而組合語言本身也方便了程式的編寫和閱讀。
編寫彙編比直接編寫二進位制方便高效了太多。但是 隨著計算任務的複雜,程式的規模越來越龐大,使用匯程式設計序也很累啊,那麼是否有更簡單的方式呢?所以科學家們發明了高階語言(比如 ,等),在編寫程式的時候,使用C語言等編寫,然後再使用 編譯器將C語言程式翻譯成彙編程式,彙編程式再使用彙編器編譯成0和1,這樣,cpu能識別的東西沒有變化,但是對於編寫程式的人,確實方便了很多。
透過以上的描述,我們就知道了高階語言的大概由來。也明白了我們所編寫的各種高階語言,到了最後,其實都是轉化為二進位制執行。
而直接二進位制格式的程式,我們稱之為本地機器碼(native code)。而類似那些 之類的 助記符,以及彙編的編寫格式或標準,我們稱之為 指令集。
但是問題的關鍵來了。不同公司所生產的 cpu晶片。他們所使用的指令集不同啊, 這種晶片設計的事情,沒有國際統一的標準,甚至像intel所代表的複雜指令集,和arm為代表的精簡指令集,還有PowerPC、MIPS等指令集,它們指令集的設計思路就是不一樣的。
所以為什麼說C&C++語言不能實現跨平臺執行,就是因為它編譯出來 輸出檔案的格式,只適用於某種特定的CPU,而其他CPU不認識啊。