主頁 > 後端開發 > 初識 C 語言

初識 C 語言

2021-06-17 06:13:30 後端開發

目錄
  • 一、C 語言的起源
  • 二、選擇 C 語言的理由
    • 2.1 設計特性
    • 2.2 高效性
    • 2.3 可移植性
    • 2.4 強大而靈活
    • 2.5 面向程式員
    • 2.6 缺點
  • 三、C 語言的應用范圍
  • 四、計算機能做什么
  • 五、高級計算機語言和編譯器
  • 六、語言標準
    • 6.1 第 1 個 ANSI/ISO C 標準
    • 6.2 C99 標準
    • 6.3 C11 標準
  • 七、使用 C 語言的 7 個步驟
    • 7.1 第 1 步:定義程式的目標
    • 7.2 第 2 步:設計程式
    • 7.3 第 3 步:撰寫代碼
    • 7.4 第 4 步:編譯
    • 7.5 第 5 步:運行程式
    • 7.6 第 6 步:測驗和除錯程式
    • 7.7 第 7 步:維護和修改代碼
    • 7.8 說明
  • 八、編程機制
    • 8.1 目標代碼檔案、可執行檔案和庫
    • 8.2 UNIX 系統
    • 8.3 GNU 編譯器集合和 LLVM 專案
    • 8.4 Linux 系統
    • 8.5 PC 的命令列編譯器
    • 8.6 集成開發環境(Windows)
    • 8.7 Windows/Linux
    • 8.8 Macintosh 中的 C

歡迎來到 C 語言的世界,C 是一門功能強大的專業化編程語言,深受業余編程愛好者和專業程式員的喜愛,本文為讀者學習這一強大而流行的語言打好基礎,并介紹幾種開發 C 程式最可能使用的環境,

我們先來了解 C 語言的起源和一些特性,包括它的優缺點,然后,介紹編程的起源并探討一些編程的基本原則,最后,討論如何在一些常見系統中運行 C 程式,

一、C 語言的起源

1972 年,貝爾實驗室的丹尼斯·里奇(Dennis Ritch)和肯·湯普遜(Ken Thompson)在開發 UNIX 作業系統時設計了 C 語言,然而,C 語言不完全是里奇突發奇想而來,他是在 B 語言(湯普遜發明)的基礎上進行設計,至于 B 語言的起源,那是另一個故事,C 語言設計的初衷是將其作為程式員使用的一種編程工具,因此,其主要目標是成為有用的語言,

雖然絕大多數語言都以實用為目標,但是通常也會考慮其他方面,例如,Pascal 的主要目標是為更好地學習編程原理提供扎實的基礎;而 BASIC 的主要目標是開發出類似英文的語言,讓不熟悉計算機的學生輕松學習編程,這些目標固然很重要,但是隨著計算機的迅猛發展,它們已經不是主流語言,然而,最初為程式員設計開發的C語言,現在已成為首選的編程語言之一,

二、選擇 C 語言的理由

在過去 40 多年里,C 語言已成為最重要、最流行的編程語言之一,它的成長歸功于使用過的人都對它很滿意,過去 20 多年里,雖然許多人都從 C 語言轉而使用其他編程語言(如,C++、Objective C、Java 等),但是 C 語言仍憑借自身實力在眾多語言中脫穎而出,在學習 C 語言的程序中,會發現它的許多優點(見圖 1),下面,我們來看看其中較為突出的幾點,

C 語言的優點

圖 1 C 語言的優點

2.1 設計特性

C 是一門流行的語言,融合了計算機科學理論和實踐的控制特性,C 語言的設計理念讓用戶能輕松地完成自頂向下的規劃、結構化編程和模塊化設計,因此,用 C 語言撰寫的程式更易懂、更可靠,

2.2 高效性

C 是高效的語言,在設計上,它充分利用了當前計算機的優勢,因此 C 程式相對更緊湊,而且運行速度很快,實際上,C 語言具有通常是匯編語言才具有的微調控制能力(匯編語言是為特殊的中央處理單元設計的一系列內部指令,使用助記符來表示;不同的 CPU 系列使用不同的匯編語言),可以根據具體情況微調程式以獲得最大運行速度或最有效地使用記憶體,

2.3 可移植性

C 是可移植的語言,這意味著,在一種系統中撰寫的 C 程式稍作修改或不修改就能在其他系統運行,如需修改,也只需簡單更改主程式頭檔案中的少許項即可,大部分語言都希望成為可移植語言,但是,如果經歷過把 IBM PC BASIC 程式轉換成蘋果 BASIC(兩者是近親),或者在 UNIX 系統中運行 IBM 大型機的 FORTRAN 程式的人都知道,移植是最麻煩的事,C 語言是可移植方面的佼佼者,從 8 位微處理器到克雷超級計算機,許多計算機體系結構都可以使用 C 編譯器(C 編譯器是把 C 代碼轉換成計算機內部指令的程式),但是要注意,程式中針對特殊硬體設備(如,顯示監視器)或作業系統特殊功能(如,Windows 8 或 OS X)撰寫的部分,通常是不可移植的,

由于 C 語言與 UNIX 關系密切,UNIX 系統通常會將 C 編譯器作為軟體包的一部分,安裝 Linux 時,通常也會安裝 C 編譯器,供個人計算機使用的 C 編譯器很多,運行各種版本的 Windows 和 Macintosh(即,Mac)的 PC 都能找到合適的 C 編譯器,因此,無論是使用家庭計算機、專業作業站,還是大型機,都能找到針對特定系統的 C 編譯器,

2.4 強大而靈活

C 語言功能強大且靈活(計算機領域經常使用這兩個詞),例如,功能強大且靈活的 UNIX 作業系統,大部分是用 C 語言寫的;其他語言(如,FORTRAN、Perl、Python、Pascal、LISP、Logo、BASIC)的許多編譯器和解釋器都是用C語言撰寫的,因此,在 UNIX 機上使用 FORTRAN 時,最終是由 C 程式生成最后的可執行程式,C 程式可以用于解決物理學和工程學的問題,甚至可用于制作電影的影片特效,

2.5 面向程式員

C 語言是為了滿足程式員的需求而設計的,程式員利用 C 可以訪問硬體、操控記憶體中的位,C 語言有豐富的運算子,能讓程式員簡潔地表達自己的意圖,C 語言不像 Pascal 甚至是 C++ 那么嚴格,這樣的靈活性既是優點也是缺點,優點是,許多任務用 C 來處理都非常簡潔(如,轉換資料的格式);缺點是,你可能會犯一些莫名其妙的錯誤,這些錯誤不可能在其他語言中出現,C 語言在提供更多自由的同時,也讓使用者承擔了更大的責任,

另外,大多數 C 實作都有一個大型的庫,包含眾多有用的 C 函式,這些函式用于處理程式員經常需要解決的問題,

2.6 缺點

人無完人,金無足赤,C 語言也有一些缺點,例如,前面提到的,要享受用 C 語言自由編程的樂趣,就必須承擔更多的責任,特別是,C 語言使用指標,而涉及指標的編程錯誤往往難以察覺,有句話說的好:想擁有自由就必須時刻保持警惕,

C 語言緊湊簡潔,結合了大量的運算子,正因如此,我們也可以撰寫出讓人極其費解的代碼,雖然沒必要強迫自己撰寫晦澀的代碼,但是有興趣寫寫也無妨,試問,除 C 語言外還為哪種語言舉辦過年度混亂代碼大賽[1]

瑕不掩瑜,C 語言的優點比缺點多很多,我們不想在這里多費筆墨,還是來聊聊 C 語言的其他話題,

三、C 語言的應用范圍

早在 20 世紀 80 年代,C 語言就已經成為小型計算機(UNIX 系統)使用的主流語言,從那以后,C 語言的應用范圍擴展到微型機(個人計算機)和大型機(龐然大物),如圖 2 所示,許多軟體公司都用 C 語言來開發文字處理程式、電子表格、編譯器和其他產品,因為用 C 語言撰寫的程式緊湊而高效,更重要的是,C 程式很方便修改,而且移植到新型號的計算機中也沒什么問題,

C 語言的應用范圍

圖 2 C 語言的應用范圍

無論是軟體公司、經驗豐富的 C 程式員,還是其他用戶,都能從 C 語言中受益,越來越多的計算機用戶已轉而求助 C 語言解決一些安全問題,不一定非得是計算機專家才能使用 C 語言,

20 世紀 90 年代,許多軟體公司開始改用 C++ 來開發大型的編程專案,C++ 在 C 語言的基礎上嫁接了面向物件編程工具(面向物件編程是一門哲學,它通過對語言建模來適應問題,而不是對問題建模以適應語言),C++ 幾乎是 C 的超集,這意味著任何 C 程式差不多就是一個 C++ 程式,學習 C 語言,也相當于學習了許多 C++ 的知識,

雖然這些年來 C++ 和 JAVA 非常流行,但是 C 語言仍是軟體業中的核心技能,在最想具備的技能中,C 語言通常位居前十,特別是,C 語言已成為嵌入式系統編程的流行語言,也就是說,越來越多的汽車、照相機、DVD 播放機和其他現代化設備的微處理器都用 C 語言進行編程,除此之外,C 語言還從長期被 FORTRAN 獨占的科學編程領域分得一杯羹,最終,作為開發作業系統的卓越語言,C 在 Linux 開發中扮演著極其重要的角色,因此,在進入 21 世紀的第 2 個 10 年中,C 語言仍然保持著強勁的勢頭,

簡而言之,C 語言是最重要的編程語言之一,將來也是如此,如果你想拿下一份編程的作業,被問到是否會 C 語言時,最好回答“是”,

四、計算機能做什么

在學習如何用 C 語言編程之前,最好先了解一下計算機的作業原理,這些知識有助于你理解用C語言撰寫程式和運行 C 程式時所發生的事情之間有什么聯系,

現代的計算機由多種部件構成,中央處理單元(CPU)承擔絕大部分的運算作業,隨機存取記憶體(RAM)是存盤程式和檔案的作業區;而永久記憶體存盤設備(過去一般指機械硬碟,現在還包括固態硬碟)即使在關閉計算機后,也不會丟失之前存盤的程式和檔案,另外,還有各種外圍設備(如,鍵盤、滑鼠、觸摸屏、監視器)提供人與計算機之間的互動,CPU 負責處理程式,接下來我們重點討論它的作業原理,

CPU 的作業非常簡單,至少從以下簡短的描述中看是這樣,它從記憶體中獲取并執行一條指令,然后再從記憶體中獲取并執行下一條指令,諸如此類(一個吉赫茲的 CPU 一秒鐘能重復這樣的操作大約十億次,因此,CPU 能以驚人的速度從事枯燥的作業),CPU 有自己的小作業區——由若干個暫存器組成,每個暫存器都可以存盤一個數字,一個暫存器存盤下一條指令的記憶體地址,CPU 使用該地址來獲取和更新下一條指令,在獲取指令后,CPU 在另一個暫存器中存盤該指令,并更新第 1 個暫存器存盤下一條指令的地址,CPU 能理解的指令有限(這些指令的集合叫作指令集),而且,這些指令相當具體,其中的許多指令都是用于請求計算機把一個數字從一個位置移動到另一個位置,例如,從記憶體移動到暫存器,

下面介紹兩個有趣的知識,其一,存盤在計算機中的所有內容都是數字,計算機以數字形式存盤數字和字符(如,在文本檔案中使用的字母),每個字符都有一個數字碼,計算機載入暫存器的指令也以數字形式存盤,指令集中的每條指令都有一個數字碼,其二,計算機程式最終必須以數字指令碼(即,機器語言)來表示,

簡而言之,計算機的作業原理是:如果希望計算機做某些事,就必須為其提供特殊的指令串列(程式),確切地告訴計算機要做的事以及如何做,你必須用計算機能直接明白的語言(機器語言)創建程式,這是一項繁瑣、乏味、費力的任務,計算機要完成諸如兩數相加這樣簡單的事,就得分成類似以下幾個步驟,

  1. 從記憶體位置 2000 上把一個數字拷貝到暫存器1,

  2. 從記憶體位置 2004 上把另一個數字拷貝到暫存器2,

  3. 把暫存器 2 中的內容與暫存器 1 中的內容相加,把結果存盤在暫存器 1 中,

  4. 把暫存器 1 中的內容拷貝到記憶體位置 2008,

而你要做的是,必須用數字碼來表示以上的每個步驟!

如果以這種方式撰寫程式很合你的意,那不得不說抱歉,因為用機器語言編程的黃金時代已一去不復返,但是,如果你對有趣的事情比較感興趣,不妨試試高級編程語言,

五、高級計算機語言和編譯器

高級編程語言(如,C)以多種方式簡化了編程作業,首先,不必用數字碼表示指令;其次,使用的指令更貼近你如何想這個問題,而不是類似計算機那樣繁瑣的步驟,使用高級編程語言,可以在更抽象的層面表達你的想法,不用考慮 CPU 在完成任務時具體需要哪些步驟,例如,對于兩數相加,可以這樣寫:

total = mine + yours;

對我們而言,光看這行代碼就知道要計算機做什么;而看用機器語言寫成的等價指令(多條以數字碼形式表現的指令)則費勁得多,但是,對計算機而言卻恰恰相反,在計算機看來,高級指令就是一堆無法理解的無用資料,編譯器在這里派上了用場,編譯器是把高級語言程式翻譯成計算機能理解的機器語言指令集的程式,程式員進行高級思維活動,而編譯器則負責處理冗長乏味的細節作業,

編譯器還有一個優勢,一般而言,不同 CPU 制造商使用的指令系統和編碼格式不同,例如,用 Intel Core i7(英特爾酷睿 i7)CPU 撰寫的機器語言程式對于 ARM Cortex-A57 CPU 而言什么都不是,但是,可以找到與特定型別 CPU 匹配的編譯器,因此,使用合適的編譯器或編譯器集,便可把一種高級語言程式轉換成供各種不同型別 CPU 使用的機器語言程式,一旦解決了一個編程問題,便可讓編譯器集翻譯成不同 CPU 使用的機器語言,

簡而言之,高級語言(如 C、Java、Pascal)以更抽象的方式描述行為,不受限于特定 CPU 或指令集,而且,高級語言簡單易學,用高級語言編程比用機器語言編程容易得多,

六、語言標準

目前,有許多 C 實作可用,在理想情況下,撰寫 C 程式時,假設該程式中未使用機器特定的編程技術,那么它的運行情況在任何實作中都應該相同,要在實踐中做到這一點,不同的實作要遵循同一個標準,

C 語言發展之初,并沒有所謂的 C 標準,1978 年,布萊恩·柯林漢(Brian Kernighan)和丹尼斯·里奇(Dennis Ritchie)合著的 The C Programming Language(《C語言程式設計》)第 1 版是公認的 C 標準,通常稱之為 K&R C 或經典 C,特別是,該書中的附錄中的“C語言參考手冊”已成為實作 C 的指導標準,例如,編譯器都聲稱提供完整的 K&R 實作,雖然這本書中的附錄定義了 C 語言,但卻沒有定義 C 庫,與大多數語言不同的是,C 語言比其他語言更依賴庫,因此需要一個標準庫,實際上,由于缺乏官方標準,UNIX 實作提供的庫已成為了標準庫,

6.1 第 1 個 ANSI/ISO C 標準

隨著 C 的不斷發展,越來越廣泛地應用于更多系統中,C 社區意識到需要一個更全面、更新穎、更嚴格的標準,鑒于此,美國國家標準協會(ANSI)于 1983 年組建了一個委員會(X3J11),開發了一套新標準,并于 1989 年正式公布,該標準(ANSI C)定義了 C 語言和 C 標準庫,國際標準化組織于 1990 年采用了這套 C 標準(ISO C),ISO C 和 ANSI C 是完全相同的標準,ANSI/ISO 標準的最終版本通常叫作 C89(因為 ANSI 于 1989 年批準該標準)或 C90(因為 ISO 于 1990 年批準該標準),另外,由于 ANSI 先公布 C 標準,因此業界人士通常使用 ANSI C,

在該委員會制定的指導原則中,最有趣的可能是:保持 C 的精神,委員會在表述這一精神時列出了以下幾點:

  • 信任程式員;
  • 不要妨礙程式員做需要做的事;
  • 保持語言精練簡單;
  • 只提供一種方法執行一項操作;
  • 讓程式運行更快,即使不能保證其可移植性,

在最后一點上,標準委員會的用意是:作為實作,應該針對目標計算機來定義最合適的某特定操作,而不是強加一個抽象、統一的定義,在學習 C 語言程序中,許多方面都反映了這一哲學思想,

6.2 C99 標準

1994 年,ANSI/ISO 聯合委員會(C9X 委員會)開始修訂 C 標準,最終發布了 C99 標準,該委員會遵循了最初 C90 標準的原則,包括保持語言的精練簡單,委員會的用意不是在 C 語言中添加新特性,而是為了達到新的目標,第 1 個目標是,支持國際化編程,例如,提供多種方法處理國際字符集,第 2 個目標是,“調整現有實踐致力于解決明顯的缺陷”,因此,在遇到需要將 C 移至 64 位處理器時,委員會根據現實生活中處理問題的經驗來添加標準,第 3 個目標是,為適應科學和工程專案中的關鍵數值計算,提高 C 的適應性,讓 C 比 FORTRAN 更有競爭力,

這 3 點(國際化、彌補缺陷和提高計算的實用性)是主要的修訂目標,在其他方面的改變則更為保守,例如,盡量與 C90、C++ 兼容,讓語言在概念上保持簡單,用委員會的話說:“……委員會很滿意讓 C++ 成為大型、功能強大的語言”,

C99 的修訂保留了 C 語言的精髓,C 仍是一門簡潔高效的語言,雖然該標準已發布了很長時間,但并非所有的編譯器都完全實作 C99 的所有改動,因此,你可能發現 C99 的一些改動在自己的系統中不可用,或者只有改變編譯器的設定才可用,

6.3 C11 標準

維護標準任重道遠,標準委員會在 2007 年承諾 C 標準的下一個版本是 C1X,2011 年終于發布了 C11 標準,此次,委員會提出了一些新的指導原則,出于對當前編程安全的擔憂,不那么強調“信任程式員”目標了,而且,供應商并未像對 C90 那樣很好地接受和支持 C99,這使得 C99 的一些特性成為 C11 的可選項,因為委員會認為,不應要求服務小型機市場的供應商支持其目標環境中用不到的特性,另外需要強調的是,修訂標準的原因不是因為原標準不能用,而是需要跟進新的技術,例如,新標準添加了可選項支持當前使用多處理器的計算機,對于 C11 標準,我們淺嘗輒止,深入分析這部分內容已超出本文討論的范圍,

七、使用 C 語言的 7 個步驟

C 是編譯型語言,如果之前使用過編譯型語言(如,Pascal 或 FORTRAN),就會很熟悉組建 C 程式的幾個基本步驟,但是,如果以前使用的是解釋型語言(如,BASIC)或面向圖形界面語言(如,Visual Basic),或者甚至沒接觸過任何編程語言,就有必要學習如何編譯,別擔心,這并不復雜,首先,為了讓讀者對編程有大概的了解,我們把撰寫 C 程式的程序分解成 7 個步驟(見圖 3),注意,這是理想狀態,在實際的使用程序中,尤其是在較大型的專案中,可能要做一些重復的作業,根據下一個步驟的情況來調整或改進上一個步驟,

編程的 7 個步驟

圖 3 編程的 7 個步驟

7.1 第 1 步:定義程式的目標

在動手寫程式之前,要在腦中有清晰的思路,想要程式去做什么首先自己要明確自己想做什么,思考你的程式需要哪些資訊,要進行哪些計算和控制,以及程式應該要報告什么資訊,在這一步驟中,不涉及具體的計算機語言,應該用一般術語來描述問題,

7.2 第 2 步:設計程式

對程式應該完成什么任務有概念性的認識后,就應該考慮如何用程式來完成它,例如,用戶界面應該是怎樣的?如何組織程式?目標用戶是誰?準備花多長時間來完成這個程式?

除此之外,還要決定在程式(還可能是輔助檔案)中如何表示資料,以及用什么方法處理資料,學習 C 語言之初,遇到的問題都很簡單,沒什么可選的,但是,隨著要處理的情況越來越復雜,需要決策和考慮的方面也越來越多,通常,選擇一個合適的方式表示資訊可以更容易地設計程式和處理資料,

再次強調,應該用一般術語來描述問題,而不是用具體的代碼,但是,你的某些決策可能取決于語言的特性,例如,在資料表示方面,C 的程式員就比 Pascal 的程式員有更多選擇,

7.3 第 3 步:撰寫代碼

設計好程式后,就可以撰寫代碼來實作它,也就是說,把你設計的程式翻譯成 C 語言,這里是真正需要使用 C 語言的地方,可以把思路寫在紙上,但是最侄訓是要把代碼輸入計算機,這個程序的機制取決于編程環境,我們稍后會詳細介紹一些常見的環境,一般而言,使用文本編輯器創建源代碼檔案,該檔案中內容就是你翻譯的 C 語言代碼,程式清單 1 是一個 C 源代碼的示例,

程式清單 1 C 源代碼示例

#include <stdio.h>
int main(void)
{
     int dogs;

     printf("How many dogs do you have?\n");
     scanf("%d", &dogs);
     printf("So you have %d dog(s)!\n", dogs);

     return 0;
}

在這一步驟中,應該給自己撰寫的程式添加文字注釋,最簡單的方式是使用 C 的注釋工具在源代碼中加入對代碼的解釋,

7.4 第 4 步:編譯

接下來的這一步是編譯源代碼,再次提醒讀者注意,編譯的細節取決于編程的環境,我們稍后馬上介紹一些常見的編程環境,現在,先從概念的角度講解編譯發生了什么事情,

前面介紹過,編譯器是把源代碼轉換成可執行代碼的程式,可執行代碼是用計算機的機器語言表示的代碼,這種語言由數字碼表示的指令組成,如前所述,不同的計算機使用不同的機器語言方案,C 編譯器負責把 C 代碼翻譯成特定的機器語言,此外,C 編譯器還將源代碼與C庫(庫中包含大量的標準函式供用戶使用,如 printf() 和 scanf())的代碼合并成最終的程式(更精確地說,應該是由一個被稱為聯結器的程式來鏈接庫函式,但是在大多數系統中,編譯器運行聯結器),其結果是,生成一個用戶可以運行的可執行檔案,其中包含著計算機能理解的代碼,

編譯器還會檢查 C 語言程式是否有效,如果 C 編譯器發現錯誤,就不生成可執行檔案并報錯,理解特定編譯器報告的錯誤或警告資訊是程式員要掌握的另一項技能,

7.5 第 5 步:運行程式

傳統上,可執行檔案是可運行的程式,在常見環境(包括 Windows 命令提示符模式、UNIX 終端模式和 Linux 終端模式)中運行程式要輸入可執行檔案的檔案名,而其他環境可能要運行命令(如,在 VAX 中的 VMS[2])或一些其他機制,例如,在 Windows 和 Macintosh 提供的集成開發環境(IDE)中,用戶可以在 IDE 中通過選擇選單中的選項或按下特殊鍵來編輯和執行 C 程式,最終生成的程式可通過單擊或雙擊檔案名或圖示直接在作業系統中運行,

7.6 第 6 步:測驗和除錯程式

程式能運行是個好跡象,但有時也可能會出現運行錯誤,接下來,應該檢查程式是否按照你所設計的思路運行,你會發現你的程式中有一些錯誤,計算機行話叫作 bug,查找并修復程式錯誤的程序叫除錯,學習的程序中不可避免會犯錯,學習編程也是如此,因此,當你把所學的知識應用于編程時,最好為自己會犯錯做好心理準備,隨著你越來越老練,你所寫的程式中的錯誤也會越來越不易察覺,

將來犯錯的機會很多,你可能會犯基本的設計錯誤,可能錯誤地實作了一個好想法,可能忽視了輸入檢查導致程式癱瘓,可能會把圓括號放錯地方,可能誤用 C 語言或打錯字,等等,把你將來犯錯的地方列出來,這份錯誤串列應該會很長,

看到這里你可能會有些絕望,但是情況沒那么糟,現在的編譯器會捕獲許多錯誤,而且自己也可以找到編譯器未發現的錯誤,在學習 C 語言的程序中,我們會給讀者提供一些除錯的建議,

7.7 第 7 步:維護和修改代碼

創建完程式后,你發現程式有錯,或者想擴展程式的用途,這時就要修改程式,例如,用戶輸入以 Zz 開頭的姓名時程式出現錯誤、你想到了一個更好的解決方案、想添加一個更好的新特性,或者要修改程式使其能在不同的計算機系統中運行,等等,如果在撰寫程式時清楚地做了注釋并采用了合理的設計方案,這些事情都很簡單,

7.8 說明

編程并非像描述那樣是一個線性的程序,有時,要在不同的步驟之間往復,例如,在寫代碼時發現之前的設計不切實際,或者想到了一個更好的解決方案,或者等程式運行后,想改變原來的設計思路,對程式做文字注釋為今后的修改提供了方便,

許多初學者經常忽略第 1 步和第 2 步(定義程式目標和設計程式),直接跳到第 3 步(撰寫代碼),剛開始學習時,撰寫的程式非常簡單,完全可以在腦中構思好整個程序,即使寫錯了,也很容易發現,但是,隨著撰寫的程式越來越龐大、越來越復雜,動腦不動手可不行,而且程式中隱藏的錯誤也越來越難找,最終,那些跳過前兩個步驟的人往往浪費了更多的時間,因為他們寫出的程式難看、缺乏條理、讓人難以理解,要撰寫的程式越大越復雜,事先定義和設計程式環節的作業量就越大,

磨刀不誤砍柴工,應該養成先規劃再動手撰寫代碼的好習慣,用紙和筆記錄下程式的目標和設計框架,這樣在撰寫代碼的程序中會更加得心應手、條理清晰,

八、編程機制

生成程式的具體程序因計算機環境而異,C 是可移植性語言,因此可以在許多環境中使用,包括 UNIX、Linux、MS-DOS(一些人仍在使用)、Windows 和 Macintosh OS,有些產品會隨著時間的推移發生演變或被取代,

首先,來看看許多 C 環境(包括上面提到的 5 種環境)共有的一些方面,雖然不必詳細了解計算機內部如何運行 C 程式,但是,了解一下編程機制不僅能豐富編程相關的背景知識,還有助于理解為何要經過一些特殊的步驟才能得到 C 程式,

用 C 語言撰寫程式時,撰寫的內容被存盤在文本檔案中,該檔案被稱為源代碼檔案(source code file),大部分 C 系統,包括之前提到的,都要求檔案名以 .c 結尾(如,wordcount.c 和 budget.c),在檔案名中,點號(.)前面的部分稱為基本名(basename),點號后面的部分稱為擴展名(extension),因此,budget 是基本名,c 是擴展名,基本名與擴展名的組合(budget.c)就是檔案名,檔案名應該滿足特定計算機作業系統的特殊要求,例如,MS-DOS 是 IBM PC 及其兼容機的作業系統,比較老舊,它要求基本名不能超過 8 個字符,因此,剛才提到的檔案名 wordcount.c 就是無效的 DOS 檔案名,有些 UNIX 系統限制整個檔案名(包括擴展名)不超過 14 個字符,而有些 UNIX 系統則允許使用更長的檔案名,最多 255 個字符,Linux、Windows 和 Macintosh OS 都允許使用長檔案名,

接下來,我們來看一下具體的應用,假設有一個名為 concrete.c 的源檔案,其中的 C 源代碼如程式清單 2 所示,

程式清單 2 c 程式

#include <stdio.h>
int main(void)
{
     printf("Concrete contains gravel and cement.\n");

     return 0;
}

如果看不懂程式清單 2 中的代碼,不用擔心,我們將在以后的文章中學習相關知識,

8.1 目標代碼檔案、可執行檔案和庫

C 編程的基本策略是,用程式把源代碼檔案轉換為可執行檔案(其中包含可直接運行的機器語言代碼),典型的 C 實作通過編譯和鏈接兩個步驟來完成這一程序,編譯器把源代碼轉換成中間代碼,聯結器把中間代碼和其他代碼合并,生成可執行檔案,C 使用這種分而治之的方法方便對程式進行模塊化,可以獨立編譯單獨的模塊,稍后再用聯結器合并已編譯的模塊,通過這種方式,如果只更改某個模塊,不必因此重新編譯其他模塊,另外,聯結器還將你撰寫的程式和預編譯的庫代碼合并,

中間檔案有多種形式,我們在這里描述的是最普遍的一種形式,即把源代碼轉換為機器語言代碼,并把結果放在目標代碼檔案(或簡稱目標檔案)中(這里假設源代碼只有一個檔案),雖然目標檔案中包含機器語言代碼,但是并不能直接運行該檔案,因為目標檔案中存盤的是編譯器翻譯的源代碼,這還不是一個完整的程式,

目標代碼檔案缺失啟動代碼(startup code),啟動代碼充當著程式和作業系統之間的介面,例如,可以在 MS Windows 或 Linux 系統下運行 IBM PC 兼容機,這兩種情況所使用的硬體相同,所以目標代碼相同,但是 Windows 和 Linux 所需的啟動代碼不同,因為這些系統處理程式的方式不同,

目標代碼還缺少庫函式,幾乎所有的 C 程式都要使用C標準庫中的函式,例如,concrete.c 中就使用了 printf() 函式,目標代碼檔案并不包含該函式的代碼,它只包含了使用 printf() 函式的指令,printf() 函式真正的代碼存盤在另一個被稱為庫的檔案中,庫檔案中有許多函式的目標代碼,

聯結器的作用是,把你撰寫的目標代碼、系統的標準啟動代碼和庫代碼這 3 部分合并成一個檔案,即可執行檔案,對于庫代碼,聯結器只會把程式中要用到的庫函式代碼提取出來(見圖 4),

編譯器和聯結器

圖 4 編譯器和聯結器

簡而言之,目標檔案和可執行檔案都由機器語言指令組成的,然而,目標檔案中只包含編譯器為你撰寫的代碼翻譯的機器語言代碼,可執行檔案中還包含你撰寫的程式中使用的庫函式和啟動代碼的機器代碼,

在有些系統中,必須分別運行編譯程式和鏈接程式,而在另一些系統中,編譯器會自動啟動聯結器,用戶只需給出編譯命令即可,

接下來,了解一些具體的系統,

8.2 UNIX 系統

由于 C 語言因 UNIX 系統而生,也因此而流行,所以我們從 UNIX 系統開始(注意:我們提到的 UNIX 還包含其他系統,如 FreeBSD,它是 UNIX 的一個分支,但是由于法律原因不使用該名稱),

1.在 UNIX 系統上編輯

UNIX C 沒有自己的編輯器,但是可以使用通用的 UNIX 編輯器,如 emacs、jove、vi 或 X Window System 文本編輯器,

作為程式員,要負責輸入正確的程式和為存盤該程式的檔案起一個合適的檔案名,如前所述,檔案名應該以 .c 結尾,注意,UNIX 區分大小寫,因此,budget.c、BUDGET.c 和 Budget.c 是 3 個不同但都有效的 C 源檔案名,但是 BUDGET.C 是無效檔案名,因為該名稱的擴展名使用了大寫 C 而不是小寫 c,

假設我們在 vi 編輯器中撰寫了下面的程式,并將其存盤在 inform.c 檔案中:

#include <stdio.h>
int main(void)
{
     printf("A .c is used to end a C program filename.\n");

     return 0;
}

以上文本就是源代碼,inform.c 是源檔案,注意,源檔案是整個編譯程序的開始,不是結束,

2.在 UNIX 系統上編譯

雖然在我們看來,程式完美無缺,但是對計算機而言,這是一堆亂碼,計算機不明白 #include 和 printf 是什么(也許你現在也不明白,但是學到后面就會明白,而計算機卻不會),如前所述,我們需要編譯器將我們撰寫的代碼(源代碼)翻譯成計算機能看懂的代碼(機器代碼),最后生成的可執行檔案中包含計算機要完成任務所需的所有機器代碼,

以前,UNIX C 編譯器要呼叫語言定義的 cc 命令,但是,它沒有跟上標準發展的腳步,已經退出了歷史舞臺,但是,UNIX 系統提供的 C 編譯器通常來自一些其他源,然后以 cc 命令作為編譯器的別名,因此,雖然在不同的系統中會呼叫不同的編譯器,但用戶仍可以繼續使用相同的命令,

編譯 inform.c,要輸入以下命令:

cc inform.c

幾秒鐘后,會回傳 UNIX 的提示,告訴用戶任務已完成,如果程式撰寫錯誤,你可能會看到警告或錯誤訊息,但我們先假設撰寫的程式完全正確(如果編譯器報告 void 的錯誤,說明你的系統未更新成 ANSI C 編譯器,只需洗掉 void 即可),如果使用 ls 命令列出檔案,會發現有一個 a.out 檔案(見圖 5),該檔案是包含已翻譯(或已編譯)程式的可執行檔案,要運行該檔案,只需輸入:

a.out
用 UNIX 準備 C 程式

圖 5 用 UNIX 準備 C 程式

輸出內容如下:

A .c is used to end a C program filename.

如果要存盤可執行檔案(a.out),應該把它重命名,否則,該檔案會被下一次編譯程式時生成的新 a.out 檔案替換,

如何處理目標代碼?C 編譯器會創建一個與源代碼基本名相同的目標代碼檔案,但是其擴展名是 .o,在該例中,目標代碼檔案是 inform.o,然而,卻找不到這個檔案,因為一旦聯結器生成了完整的可執行程式,就會將其洗掉,如果原始程式有多個源代碼檔案,則保留目標代碼檔案,學到后面多檔案程式時,你會明白到這樣做的好處,

8.3 GNU 編譯器集合和 LLVM 專案

GNU 專案始于 1987 年,是一個開發大量自由 UNIX 軟體的集合(GNU 的意思是“GNU’s Not UNIX”,即 GNU 不是 UNIX),GNU 編譯器集合(也被稱為 GCC,其中包含 GCC C 編譯器)是該專案的產品之一,GCC 在一個指導委員會的帶領下,持續不斷地開發,它的 C 編譯器緊跟 C 標準的改動,GCC 有各種版本以適應不同的硬體平臺和作業系統,包括 UNIX、Linux 和 Windows,用 gcc 命令便可呼叫 GCC C 編譯器,許多使用 gcc 的系統都用 cc 作為 gcc 的別名,

LLVM 專案成為 cc 的另一個替代品,該專案是與編譯器相關的開源軟體集合,始于伊利諾伊大學 2000 年的研究專案,它的 Clang 編譯器處理 C 代碼,可以通過 clang 呼叫,有多種版本供不同的平臺使用,包括 Linux,2012 年,Clang 成為 FreeBSD 的默認 C 編譯器,Clang 也對最新的 C 標準支持得很好,

GNU 和 LLVM 都可以使用 -v 選項來顯示版本資訊,因此各系統都使用 cc 別名來代替 gcc 或 clang 命令,以下組合:

cc -v

顯示你所使用的編譯器及其版本,

gcc 和 clang 命令都可以根據不同的版本選擇運行時選項來呼叫不同 C 標準,

gcc -std=c99 inform.c
gcc -std=c1x inform.c
gcc -std=c11 inform.c

GCC 最基本的用法是:gcc [options] [filenames],其中 options 是所需的引數,filenames 是檔案名,

第 1 行呼叫 C99 標準,第 2 行呼叫 GCC 接受 C11 之前的草案標準,第 3 行呼叫 GCC 接受的 C11 標準版本,Clang 編譯器在這一點上用法與 GCC 相同,

8.4 Linux 系統

Linux 是一個開源、流行、類似于 UNIX 的作業系統,可在不同平臺(包括 PC 和 Mac)上運行,在 Linux 中準備 C 程式與在 UNIX 系統中幾乎一樣,不同的是要使用 GNU 提供的 GCC 公共域 C 編譯器,編譯命令類似于:

gcc inform.c

注意,在安裝 Linux 時,可選擇是否安裝 GCC,如果之前沒有安裝 GCC,則必須安裝,通常,安裝程序會將 cc 作為 gcc 的別名,因此可以在命令列中使用 cc 來代替 gcc,

欲詳細了解 GCC 和最新發布的版本,請訪問 https://www.gnu.org/software/gcc/index.html,

8.5 PC 的命令列編譯器

C 編譯器不是標準 Windows 軟體包的一部分,因此需要從別處獲取并安裝 C 編譯器,可以從互聯網免費下載 Cygwin 和 MinGW,這樣便可在 PC 上通過命令列使用 GCC 編譯器,Cygwin 在自己的視窗運行,模仿 Linux 命令列環境,有一行命令提示,MinGW 在 Windows 的命令提示模式中運行,這和 GCC 的最新版本一樣,支持 C99 和 C11 最新的一些功能,Borland 的 C++ 編譯器 5.5 也可以免費下載,支持 C90,

源代碼檔案應該是文本檔案,不是字處理器檔案(字處理器檔案包含許多額外的資訊,如字體和格式等),因此,要使用文本編輯器(如,Windows Notepad)來編輯源代碼,如果使用字處理器,要以文本模式另存檔案,源代碼檔案的擴展名應該是 .c,一些字處理器會為文本檔案自動添加 .txt 擴展名,如果出現這種情況,要更改檔案名,把 txt 替換成 c,

通常,C 編譯器生成的中間目標代碼檔案的擴展名是 .obj(也可能是其他擴展名),與 UNIX 編譯器不同,這些編譯器在完成編譯后通常不會洗掉這些中間檔案,有些編譯器生成帶 .asm 擴展名的匯編語言檔案,而有些編譯器則使用自己特有的格式,

一些編譯器在編譯后會自動運行聯結器,另一些要求用戶手動運行聯結器,在可執行檔案中鏈接的結果是,在原始的源代碼基本名后面加上 .exe 擴展名,例如,編譯和鏈接 concrete.c 源代碼檔案,生成的是 concrete.exe 檔案,可以在命令列輸入基本名來運行該程式:

C>concrete

8.6 集成開發環境(Windows)

許多供應商(包括微軟、Embarcadero、Digital Mars)都提供 Windows 下的集成開發環境,或稱為 IDE(目前,大多數 IDE 都是 C 和 C++ 結合的編譯器),可以免費下載的 IDE 有 Microsoft Visual Studio Express 和 Pelles C,利用集成開發環境可以快速開發 C 程式,關鍵是,這些 IDE 都內置了用于撰寫 C 程式的編輯器,這類集成開發環境都提供了各種選單(如,命名、保存源代碼檔案、編譯程式、運行程式等),用戶不用離開 IDE 就能順利撰寫、編譯和運行程式,如果編譯器發現錯誤,會回傳編輯器中,標出有錯誤的行號,并簡單描述情況,

初次接觸 Windows IDE 可能會望而生畏,因為它提供了多種目標(target),即運行程式的多種環境,例如,IDE 提供了 32 位 Windows 程式、64 位 Windows 程式、元件檔案(DLL)等,許多目標都涉及 Windows 圖形界面,要管理這些(及其他)選擇,通常要先創建一個專案(project),以便稍后在其中添加待使用的源代碼檔案名,不同的產品具體步驟不同,一般而言,首先使用【檔案】選單或【專案】選單創建一個專案,選擇正確的專案形式非常重要,本文中的例子都是一般示例,針對在簡單的命令列環境中運行而設計,Windows IDE 提供多種選擇以滿足用戶的不同需求,例如,Microsoft Visual Studio 提供【Win32 控制臺應用程式】選項,對于其他系統,查找一個諸如【DOS EXE】、【Console】或【Character Mode】的可執行選項,選擇這些模式后,將在一個類控制臺視窗中運行可執行程式,選擇好正確的專案型別后,使用 IDE 的選單打開一個新的源代碼檔案,對于大多數產品而言,使用【檔案】選單就能完成,你可能需要其他步驟將源檔案添加到專案中,

通常,Windows IDE 既可處理 C 也可處理 C++,因此要指定待處理的程式是 C 還是 C++,有些產品用專案型別來區分兩者,有些產品(如,Microsoft Visual C++)用 .c 檔案擴展名來指明使用 C 而不是 C++,當然,大多數 C 程式也可以作為 C++ 程式運行,

你可能會遇到一個問題:在程式執行完畢后,執行程式的視窗立即消失,如果不希望出現這種情況,可以讓程式暫停,直到按下 Enter 鍵,視窗才消失,要實作這種效果,可以在程式的最后(return 這行代碼之前)添加下面一行代碼:

getchar();

該行讀取一次鍵的按下,所以程式在用戶按下 Enter 鍵之前會暫停,有時根據程式的需要,可能還需要一個擊鍵等待,這種情況下,必須用兩次 getchar():

getchar();
getchar();

例如,程式在最后提示用戶輸入體重,用戶鍵入體重后,按下 Enter 鍵以輸入資料,程式將讀取體重,第 1 個 getchar() 讀取 Enter 鍵,第 2 個 getchar() 會導致程式暫停,直至用戶再次按下 Enter 鍵,如果你現在不知所云,沒關系,在學完 C 輸出后就會明白,到時,我們會提醒讀者使用這種方法,

雖然許多 IDE 在使用上大體一致,但是細節上有所不同,就一個產品的系列而言,不同版本也是如此,要經過一段時間的實踐,才會熟悉編譯器的作業方式,必要時,還需閱讀使用手冊或網上教程,

Microsoft Visual Studio 和 C 標準

在 Windows 軟體開發中,Microsoft Visual Studio 及其免費版本 Microsoft Visual Studio Express 都久負盛名,它們與 C 標準的關系也很重要,然而,微軟鼓勵程式員從 C 轉向 C++ 和 C#,雖然 Visual Studio 支持 C89/90,但是到目前為止,它只選擇性地支持那些在 C++ 新特性中能找到的 C 標準(如,long long 型別),而且,自 2012 版本起,Visual Studio 不再把 C 作為專案型別的選項,盡管如此,本文中的絕大多數程式仍可用 Visual Studio 來編譯,在新建專案時,選擇 C++ 選項,然后選擇【Win32 控制臺應用程式】,在應用設定中選擇【空專案】,幾乎所有的 C 程式都能與 C++ 程式兼容,所以,本文中的絕大多數 C 程式都可作為 C++ 程式運行,或者,在選擇 C++ 選項后,將默認的源檔案擴展名 .cpp 替換成 .c,編譯器便會使用 C 語言的規則代替 C++,

8.7 Windows/Linux

許多 Linux 發行版都可以安裝在 Windows 系統中,以創建雙系統,一些存盤器會為 Linux 系統預留空間,以便可以啟動 Windows 或 Linux,可以在 Windows 系統中運行 Linux 程式,或在 Linux 系統中運行 Windows 程式,不能通過 Windows 系統訪問 Linux 檔案,但是可以通過 Linux 系統訪問 Windows 檔案,

8.8 Macintosh 中的 C

目前,蘋果免費提供 Xcode 開發系統下載(過去,它有時免費,有時付費),它允許用戶選擇不同的編程語言,包括 C 語言,

Xcode 憑借可處理多種編程語言的能力,可用于多平臺,開發超大型的專案,但是,首先要學會如何撰寫簡單的 C 程式,在 Xcode 4.6 中,通過【File】選單選擇【New Project】,然后選擇【OS X Application Command Line Tool】,接著輸入產品名并選擇 C 型別,Xcode 使用 Clang 或 GCC C 編譯器來編譯 C 代碼,它以前默認使用 GCC,但是現在默認使用 Clang,可以設定選擇使用哪一個編譯器和哪一套 C 標準(因為許可方面的事宜,Xcode 中 Clang 的版本比 GCC 的版本要新),

Mac OS X 建立在 UNIX 系統之上,終端工具打開的視窗是讓用戶在 UNIX 命令列環境中運行程式,蘋果在標準軟體包中不提供命令列編譯器,但是,如果下載了 Xcode,還可以下載可選的命令列工具,這樣就可以使用 clang 和 gcc 命令在命令列模式中編譯,

原文:初識 C 語言

(完)


  1. 國際 C 語言混淆代碼大賽(IOCCC,The International Obfuscated C Code Contest),這是一項國際編程賽事,從 1984 年開始,每年舉辦一次(1997、1999、2002、2003 和 2006 年除外),目的是寫出最有創意且最讓人難以理解的 C 語言代碼, ??

  2. VAX(Virtual Address eXtension)是一種可支持機器語言和虛擬地址的 32 位小型計算機,VMS(Virtual Memory System)是舊名,現在叫 OpenVMS,是一種用于服務器的作業系統,可在 VAX、Alpha 或 Itanium 處理器系列平臺上運行, ??

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/287964.html

標籤:C

上一篇:【爬蟲實戰】帶你一步步破解亞馬遜 淘寶 京東的反爬蟲機制

下一篇:C 語言概述

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more