導航:首頁 > 源碼編譯 > 並行c編譯器

並行c編譯器

發布時間:2023-06-12 19:13:06

A. Linux下C實現多進程同步並行

你去查一下OpenMP相關書籍,用OpenMP庫函數實現吧,Linux的gcc編譯器4.2版以後開始內置OpenMP並行支持,源程序里多寫兩句話就搞定的事情,不過OpenMP建立的是輕量級進程(在Windows下叫線程的東西)。

如果要用嚴格意義上的「進程」實現,還有一個多線程並行的工具是MPICH2,設計目的是多計算機分布式並行計算的,當然也能用在單一計算機上。

B. 如何評價CUDA,OpenCL,OpenMP,OpenACC等主流並行運算框架

PGI和Cray才是最早推動這項技術商業化的公司。PGI已經推出了一組非常類似的加速器指令,目前也成為了OpenACC標準的基礎部分之一。Cray公司正在開發自己的OpenACC編譯器,並且他的XK6客戶如橡樹嶺國家實驗室和瑞士國家超級計算機中心,預計將成為該技術的第一批超級計算機用戶。
簡而言之,OpenACC指令與OpenMP指令工作方式很類似,但前者特別適用於高度數據並行代碼。它們可插入標準的C,C + +和Fortran程序直接指導編譯器進行某些代碼段的並行。編譯器會特別注意數據在CPU和GPU(或其他)之間來回轉移的邏輯關系,並將計算映射到適當的處理器上。
這樣,開發人員就可以在現存的或者新的代碼上做相對小的改動以標示出加速並行區域。由於指令設計適用於一個通用並行處理器,這樣相同的代碼可以運行在多核CPU、GPU或任何編譯器支持的其他類型的並行硬體上。這種硬體的獨立性對於HPC的用戶來說特別重要,因為他們不願意接受那種受供應商限制的,非攜帶型編程環境。

C. 學C語言現在最好用的編程軟體

GNU編譯器套裝
開發 The GNU Project
最新版本 4.4.2 / 2009-10-15(2個月前)
操作系統 跨平台
類型 編譯器
許可協議 GPL
網站 gcc.gnu.org

GCC(GNU Compiler Collection,GNU編譯器套裝),是一套由GNU開發的編程語言編譯器。它是一套以GPL及LGPL許可證所發行的自由軟體,也是GNU計劃的關鍵部分,亦是自由的類Unix及蘋果計算機Mac OS X 操作系統的標准編譯器。GCC(特別是其中的C語言編譯器)也常被認為是跨平台編譯器的事實標准。

GCC原名為GNU C語言編譯器(GNU C Compiler),因為它原本只能處理C語言。GCC很快地擴展,變得可處理C++。之後也變得可處理Fortran、Pascal、Objective-C、Java,以及Ada與其他語言。
目錄
[隱藏]

* 1 概觀
* 2 目前支持的語言
o 2.1 內嵌OpenMP支持
* 3 支持的處理器架構
* 4 結構
o 4.1 前端介面
o 4.2 中介介面
o 4.3 後端介面
* 5 替GCC程序除錯
* 6 參考書目及注釋
* 7 參閱
* 8 更多閱讀
* 9 外部鏈接

[編輯] 概觀

GCC是由理查德·馬修·斯托曼在1985年開始的。他首先擴增一個舊有的編譯器,使它能編譯C,這個編譯器一開始是以Pastel語言所寫的。Pastel是一個不可移植的Pascal語言特殊版,這個編譯器也只能編譯Pastel語言。為了讓自由軟體有一個編譯器,後來此編譯器由斯托曼和Len Tower在1987年[1]以C語言重寫[2]並成為GNU項目的編譯器。GCC的建立者由自由軟體基金會直接管理[3]。

在1997年,一群不滿GCC緩慢且封閉的創作環境者,組織了一個名為EGCS《Experimental/Enhanced GNU Compiler System》的項目,此項目匯整了數項實驗性的分支進入某個GCC項目的分支中。EGCS比起GCC的建構環境更有活力,且EGCS最終也在1999年四月成為GCC的官方版本。

GCC目前由世界各地不同的數個程序設計師小組維護。它是移植到中央處理器架構以及操作系統最多的編譯器。

由於GCC已成為GNU系統的官方編譯器(包括GNU/Linux家族),它也成為編譯與建立其他操作系統的主要編譯器,包括BSD家族、Mac OS X、NeXTSTEP與BeOS。

GCC通常是跨平台軟體的編譯器首選。有別於一般局限於特定系統與運行環境的編譯器,GCC在所有平台上都使用同一個前端處理程序,產生一樣的中介碼,因此此中介碼在各個其他平台上使用GCC編譯,有很大的機會可得到正確無誤的輸出程序。
[編輯] 目前支持的語言

以2006年5月24日釋出的4.1.1版為准,本編譯器版本可處理下列語言:

* Ada 《GNAT》
* C 《GCC》
* C++(G++)
* Fortran 《Fortran 77: G77,Fortran 90: GFORTRAN》

* Java 《編譯器:GCJ;解釋器:GIJ》
* Objective-C 《GOBJC》
* Objective-C++

先前版本納入的CHILL前端由於缺乏維護而被廢棄。

Fortran前端在4.0版之前是G77,此前端僅支持Fortran 77。在本版本中,G77被廢棄而採用更新的GFortran,因為此前端支持Fortran 95。

下列前端依然存在:

* Mola-2
* Mola-3
* Pascal
* PL/I

* D語言
* Mercury
* VHDL

[編輯] 內嵌OpenMP支持

OpenMP是一種跨語言的對稱多處理器(SMP)多線程並行程序的編程工具,也非常適合當今越來越流行的單CPU多核硬體環境,因此從gcc4.2開始,OpenMP成為其內嵌支持的並行編程規范,可以直接編譯內嵌 OpenMP語句的C/C++/Fortran95的源代碼。gcc4.2之前如果想在C/C++/Fortran中嵌入OpenMP語句的話,需要額外安裝庫和預處理器才能識別和正確處理這些語句。

* gcc 4.2.0開始支持OpenMP v2.5
* gcc 4.4.0開始支持OpenMP v2.5及v3.0

參見GNU的GOMP計劃
[編輯] 支持的處理器架構

GCC目前支持下列處理器架構(以4.1版為准):

* Alpha
* ARM
* Atmel AVR
* Blackfin
* H8/300
* IA-32(x86)與x86-64
* IA-64例如:Itanium

* MorphoSys家族
* Motorola 68000
* Motorola 88000
* MIPS
* PA-RISC
* PDP-11
* PowerPC

* System/370,System/390
* SuperH
* HC12
* SPARC
* VAX
* Renesas R8C/M16C/M32C家族

較不知名的處理器架構也在官方釋出版本中支持:

* A29K
* ARC
* C4x
* CRIS
* D30V
* DSP16xx
* FR-30
* FR-V

* Intel i960
* IP2000
* M32R
* 68HC11
* MCORE
* MMIX

* MN10200
* MN10300
* NS32K
* ROMP
* Stormy16
* V850
* Xtensa

由FSF個別維護的GCC處理器架構:

* D10V
* MicroBlaze

* PDP-10
* MSP430

* Z8000

當GCC需要移植到一個新平台上,通常使用此平台固有的語言來撰寫其初始階段。
[編輯] 結構

GCC的外部介面長得像一個標準的Unix編譯器。用戶在命令行下鍵入gcc之程序名,以及一些命令參數,以便決定每個輸入文件使用的個別語言編譯器,並為輸出代碼使用適合此硬體平台的匯編語言編譯器,並且選擇性地運行連接器以製造可運行的程序。

每個語言編譯器都是獨立程序,此程序可處理輸入的源代碼,並輸出匯編語言碼。全部的語言編譯器都擁有共通的中介架構:一個前端解析符合此語言的源代碼,並產生一抽象語法樹,以及一翻譯此語法樹成為GCC的寄存器轉換語言《RTL》的後端。編譯器優化與靜態代碼解析技術(例如FORTIFY_SOURCE[1],一個試圖發現緩存溢出《buffer overflow》的編譯器)在此階段應用於代碼上。最後,適用於此硬體架構的匯編語言代碼以Jack Davidson與Chris Fraser發明的演算法產出。

幾乎全部的GCC都由C寫成,除了Ada前端大部分以Ada寫成。
[編輯] 前端介面

前端的功能在於產生一個可讓後端處理之語法樹。此語法解析器是手寫之遞回語法解析器。

直到最近,程序的語法樹結構尚無法與欲產出的處理器架構脫鉤。而語法樹的規則有時在不同的語言前端也不一樣,有些前端會提供它們特別的語法樹規則。

在2005年,兩種與語言脫鉤的新型態語法樹納入GCC中。它們稱為GENERIC與GIMPLE。語法解析變成產生與語言相關的暫時語法樹,再將它們轉成GENERIC。之後再使用"gimplifier"技術降低GENERIC的復雜結構,成為一較簡單的靜態唯一形式(Static Single Assignment form,SSA)基礎的GIMPLE形式。此形式是一個與語言和處理器架構脫鉤的全局優化通用語言,適用於大多數的現代編程語言。
[編輯] 中介介面

一般編譯器作者會將語法樹的優化放在前端,但其實此步驟並不看語言的種類而有不同,且不需要用到語法解析器。因此GCC作者們將此步驟歸入通稱為中介階段的部分里。此類的優化包括消解死碼、消解重復計算與全局數值重編碼等。許多優化技巧也正在實現中。
[編輯] 後端介面

GCC後端的行為因不同的前處理器宏和特定架構的功能而不同,例如不同的字元尺寸、調用方式與大小尾序等。後端介面的前半部利用這些消息決定其RTL的生成形式,因此雖然GCC的RTL理論上不受處理器影響,但在此階段其抽象指令已被轉換成目標架構的格式。

GCC的優化技巧依其釋出版本而有很大不同,但都包含了標準的優化演算法,例如循環優化、線程跳躍、共通程序子句消減、指令調度等等。而RTL的優化由於可用的情形較少,且缺乏較高級的信息,因此比較起近來增加的GIMPLE語法樹形式[2],便顯得比較不重要。

後端經由一重讀取步驟後,利用描述目標處理器的指令集時所取得的信息,將抽象寄存器替換成處理器的真實寄存器。此階段非常復雜,因為它必須關照所有GCC可移植平台的處理器指令集的規格與技術細節。

後端的最後步驟相當公式化,僅僅將前一階段得到的匯編語言碼藉由簡單的副函數轉換其寄存器與存儲器位置成相對應的機器碼。
[編輯] 替GCC程序除錯

為GCC除錯的首選工具當然是GNU除錯器。其他特殊用途的除錯工具是Valgrind,用以發現存儲器泄漏 (Memory leak)。而GNU測量器(gprof)可以得知程序中某些函數花費多少時間,以及其調用頻率;此功能需要用戶在編譯時選定測量《profiling》選項。
[編輯] 參考書目及注釋

* Richard M. Stallman:Using and Porting the GNU Compiler Collection, Free Software Foundation,ISBN 0-595-10035-X
* Richard M. Stallman: Using Gcc: The Gnu Compiler Collection Reference, Free Software Foundation, ISBN 1-882114-39-6
* Brian J. Gough:An Introction to GCC, Network Theory Ltd., ISBN 0-9541617-9-3

1. ^ Tower, Leonard (1987) "GNU C編譯器beta測試版釋出" comp.lang.misc USENET新聞組;參閱http://gcc.gnu.org/releases.html#timeline
2. ^ Stallman, Richard M.(1986年2月1日).GNU狀態.GNU的公告版,1(1).自由軟體基金會.
3. ^ Stallman, Richard M. (2001) "GCC貢獻者名單"於使用及移植GCC 2.95版(Cambridge, Mass.: Free Software Foundation)

[編輯] 參閱
[[File:|36x32px|自由軟體主題]] 自由軟體主題首頁

GCC目前包含了Boehm GC,一個為C/C++ 所設計的垃圾回收器。

* distcc - 為分布式編譯所設計的軟體,以GCC為協同軟體。
* LLVM - 低層虛擬機編譯器架構。
* MinGW - 將GNU開發工具移植到Win32平台下的計劃
* Cygwin - 在Windows上運行GNU程序的模擬軟體。
* GCC Summit
* OpenWatcom - 另一個開放原碼的C++/Fortran編譯器。
* Code Sourcery - 一個GCC顧問公司。
* ggcc - 全球化GCC項目。

[編輯] 更多閱讀

* Arthur Griffith, GCC: The Complete Reference. McGrawHill/Osborne. ISBN 0-07-222405-3.
* Kerner, Sean Michael.Open Source GCC 4.0: Older, Faster,internetnews.com,2005年4月22日.
* Kerner, Sean Michael.New GCC Heavy on Optimization,internetnews.com,2006年3月2日.

[編輯] 外部鏈接

* GCC官方網站
* GCC Forum - 由Nabble維持,整理所有gcc通信討論串,並集成入一個可搜索介面中。

D. 求C語言的發展和現在應用

C語言
維 基
http://zh.w-i-k-i-p-e-d-i-a.org/zh/C%E8%AF%AD%E8%A8%80

編程范型
程序式
發行時間
1972年
設計者
丹尼斯·里奇(Dennis Ritchie)
實作者
丹尼斯·里奇(Dennis Ritchie)和肯·湯普遜(Ken Thompson)
最新發行時間 C99 (2000年3月)
啟發語言
B語言、組合語言
影響語言
awk, BitC, csh, C++, C#, Concurrent C, D, Java, JavaScript, Objective-C, Perl, PHP
作業系統
跨平台
C語言,是一種通用的、程序式的程式語言,廣泛用於系統與應用軟體的開發。具有高效、靈活、功能豐富、表達力強和較高的移植性等特點,在程序員中備受青睞。
C語言是由UNIX的研製者丹尼斯·里奇(Dennis Ritchie)和肯·湯普遜(Ken Thompson)於1970年研製出的B語言的基礎上發展和完善起來的。目前,C語言編譯器普遍存在於各種不同的操作系統中,例如UNIX、MS-DOS、Microsoft Windows及Linux等。C語言的設計影響了許多後來的程式語言,例如C++、Objective-C、Java、C#等。
後來於1980年代,為了避免各開發廠商用的C語言語法產生差異,由美國國家標准局(American National Standard Institution)為C語言訂定了一套完整的國際標准語法,稱為ANSI C,作為C語言的標准。1980年代至今的有關程式開發工具,一般都支持符合ANSI C的語法。
目錄 [隱藏]
1 設計哲學
2 特色
3 歷史
3.1 早期發展
3.2 K&R C
3.3 ANSI C 和 ISO C
3.4 C99
4 語法
4.1 Hello World 程序
4.2 進一步了解
4.3 復合語句
4.4 條件語句
4.5 循環語句
4.6 跳轉語句
4.7 在C99中的運算符號
4.8 數據類型
4.8.1 基礎數據類型
4.8.2 陣列
4.8.3 指針
4.8.4 字串
4.9 文件輸入/輸出
4.9.1 標准輸入/輸出
5 內存管理
6 安全問題
7 庫
8 保留關鍵字
8.1 C99新增關鍵字
9 C//
10 參考文獻
11 外部連結
12 參見
[編輯]設計哲學

C語言是一個程序語言,設計目標是提供一種能以簡易的方式編譯、處理低階記憶體、產生少量的機械碼以及不需要任何執行環境支援便能執行的程式語言。C語言也很適合搭配匯編語言來使用。盡管C語言提供了許多低階處理的功能,但仍然保持著良好跨平台的特性,以一個標准規格寫出的C語言程式可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(微控制器或稱MCU)以及超級電腦等作業平台。
[編輯]特色

C語言是一個有結構化程式設計、具有變數作用域(variable scope)以及遞回功能的程序式語言。
傳遞參數是以值傳遞(Pass-by-value),也可以透過指針來傳遞參數(Pass-by-address)。
不同的變數類型可以用結構體(struct)組合在一起。
只有32個保留字(reserved keywords),使變數、函數命名有更多彈性。
部份的變數類型可以轉換,例如整型和字元型變數。
透過指針(pointer),C語言可以容易的對記憶體進行低階控制。
編譯預處理(preprocessor)讓C語言的編譯更具有彈性。
[編輯]歷史

[編輯]早期發展
C語言的第一次發展在1969年到1973年之間。之所以被稱為「C」是因為C語言的很多特性是由一種更早的被稱為B語言的程式語言中發展而來。早期作業系統的核心大多由組合語言組成,隨著C語言的發展,C語言已經可以用來編寫作業系統的核心。1973年,Unix作業系統的核心正式用C語言改寫,這是C語言第一次應用在作業系統的核心編寫上。
[編輯]K&R C
1978年,丹尼斯·里奇(Dennis Ritchie)和Brian Kernighan合作出版了《C程序設計語言》的第一版。書中介紹的C語言標准也被C語言程式設計師稱作「K&R C」,第二版的書中也包含了一些ANSI C的標准。K&R C主要介紹了以下特色:
結構(struct)類型
長整數(long int)類型
無號整數(unsigned int)類型
把運算符=+和=-改為+=和-=。因為=+和=-會使得編譯器不知道使用者要處理i = +10還是i =- 10,使得處理上產生混淆。
即使在後來ANSI C標准被提出的許多年後,K&R C仍然是許多編譯器的最低標准要求,許多老舊的編譯仍然運行K&R C的標准。
[編輯]ANSI C 和 ISO C
主條目:ANSI C
1989年,C語言被 ANSI 標准化(ANSI X3.159-1989)。標准化的一個目的是擴展K&R C。這個標准包括了一些新特性。在K&R出版後,一些新特性被非官方地加到C語言中。
void 函數
函數返回 struct 或 union 類型
void * 數據類型
在ANSI標准化自己的過程中,一些新的特性被加了進去。ANSI也規定了一套標准函數庫。ANSI ISO(國際標准化組織)成立 ISO/IEC JTC1/SC22/WG14 工作組,來規定國際標準的C語言。通過對ANSI標準的少量修改,最終通過了 ISO 9899:1990。隨後,ISO標准被 ANSI 採納。
傳統C語言到ANSI/ISO標准C語言的改進包括:
增加了真正的標准庫
新的預處理命令與特性
函數原型允許在函數申明中指定參數類型
一些新的關鍵字,包括 const、volatile 與 signed
寬字元、寬字元串與位元組多字元
對約定規則、聲明和類型檢查的許多小改動與澄清
WG14工作小組之後又於1995年,對1985年頒布的標准做了兩處技術修訂(缺陷修復)和一個補充(擴展)。下面是 1995 年做出的所有修改:
3 個新的標准庫頭文件 iso646.h、wctype.h 和 wchar.h
幾個新的記號與預定義宏,用於對國際化提供更好的支持
printf/sprintf 函數一系列新的格式代碼
大量的函數和一些類型與常量,用於多位元組字元和寬位元組字元
[編輯]C99
在ANSI的標准確立後,C語言的規范在一段時間內沒有大的變動,然而C++在自己的標准化建立過程中繼續發展壯大。《標准修正案一》在1995年為C語言建立了一個新標准,但是只修正了一些C89標准中的細節和增加更多更廣得國際字元集支持。不過,這個標准引出了1999年ISO 9899:1999的發表。它通常被稱為C99。C99被ANSI於2000年3月採用。
在C99中包括的特性有:
對編譯器限制增加了,比如源程序每行要求至少支持到 4095 位元組,變數名函數名的要求支持到 63 位元組(extern 要求支持到 31)
預處理增強了。例如:
巨集支持取可變參數 #define Macro(...) __VA_ARGS__
使用巨集的時候,參數如果不寫,巨集里用 #,## 這樣的東西會擴展成空串。(以前會出錯的)
支持 // 行注釋(這個特性實際上在C89的很多編譯器上已經被支持了)
增加了新關鍵字 restrict, inline, _Complex, _Imaginary, _Bool
支持 long long, long double _Complex, float _Complex 這樣的類型
支持 <: :> <% %> %: %:%: ,等等奇怪的符號替代,D&E 里提過這個
支持了不定長的數組。數組的長度就可以用變數了。聲明類型的時候呢,就用 int a[*] 這樣的寫法。不過考慮到效率和實現,這玩意並不是一個新類型。所以就不能用在全局裡,或者 struct union 裡面,如果你用了這樣的東西,goto 語句就受限制了。
變數聲明不必放在語句塊的開頭,for 語句提倡這么寫 for(int i=0;i<100;++i) 就是說,int i 的聲明放在裡面,i 只在 for 裡面有效。
當一個類似結構的東西需要臨時構造的時候,可以用(type_name){xx,xx,xx} 這有點像 C++ 的構造函數
初始化結構的時候現在可以這樣寫:
struct {int a[3],b;} hehe[] = { [0].a = {1}, [1].a = 2 };
struct {int a, b, c, d;} hehe = { .a = 1, .c = 3, 4, .b = 5} // 3,4 是對 .c,.d 賦值的
字元串裡面,\u 支持 unicode 的字元
支持 16 進制的浮點數的描述
所以 printf scanf 的格式化串多支持了 ll / LL(VC6 里用的 I64)對應新的 long long 類型。
浮點數的內部數據描述支持了新標准,這個可以用 #pragma 編譯器指定
除了已經有的 __line__ __file__ 以外,又支持了一個 __func__ 可以得到當前的函數名
對於非常數的表達式,也允許編譯器做化簡
修改了對於/% 處理負數上的定義,比如老的標准里 -22 / 7 = -3, -22 % 7 = -1 而現在 -22 / 7 = -4, -22 % 7 = 6(根據本人的測試,使用c99標准時結果仍未-3和-1,本人使用的編譯器是gcc4.4.3)
取消了不寫函數返回類型默認就是 int 的規定
允許 struct 定義的最後一個數組寫做 [] 不指定其長度描述
const const int i;將被當作 const int i;處理
增加和修改了一些標准頭文件,比如定義 bool 的 <stdbool.h> 定義一些標准長度的 int 的 <inttypes.h> 定義復數的 <complex.h> 定義寬字元的 <wctype.h> 有點泛型味道的數學函數 <tgmath.h> 跟浮點數有關的 <fenv.h>。<stdarg.h> 里多了一個 va_ 可以復制 ... 的參數。<time.h> 里多了個 struct tmx 對 struct tm 做了擴展
輸入輸出對寬字元還有長整數等做了相應的支持
但是各個公司對C99的支持所表現出來的興趣不同。當GCC和其它一些商業編譯器支持C99的大部分特性的時候,微軟和Borland卻似乎對此不感興趣。
[編輯]語法

[編輯]Hello World 程序
下面是一個在標准輸出設備 (stdout) 上,印出 "Hello World" 字串的簡單程序,這樣子的程序,通常作為初學編程語言時的第一個程序:
#include <stdio.h>

int main(void)
{
printf("Hello, world!\n");
return 0;
}
[編輯]進一步了解
C語言由函數和變數組成。C的函數就像是Fortran中的子程序和函數。
在C語言中,程序從main開始執行。main函數通過調用和控制其他函數進行工作。例如上面的printf。程序員可以自己寫函數,或從庫中調用函數。在上面的return 0;使得main返回一個值給調用程序的外殼,表明程序已經成功運行。
一個C語言的函數由返回值、函數名、參數列表(或void表示沒有返回值)和函數體組成。函數體的語法和其它的復合的語句部分是一樣的。
[編輯]復合語句
C語言中的復合語句(或稱語句塊)的格式為:
{語句;語句;……}
復合語句可以使得幾個語句從文法上變成一個語句。
[編輯]條件語句
C語言有三種條件語句形式。兩種是if,另一種是switch。
兩種if包括:
if(運算式)
語句;
以及
if(運算式)
語句;
else
語句;
運算式的值非零表示條件為真;如果條件為假,程式將跳過if處的語句,直接執行if後面的語句。但是如果if後面有else,則當條件為假時,程式跳到else處執行。if和else後面的語句可以是另個if語句,這種套疊式的結構,允許更復雜的邏輯控制流程得以實現。在一般情況下,else一定與最接近的if成對,必要時可用括弧{}越過此限制。比較下面兩種情況:
if(運算式)
if (運算式)
語句;
else
語句;
if(運算式){
if (運算式)
語句;
}
else
語句;
switch通常用於對幾種有明確值的條件進行控制。它要求的條件值通常是整數或字元。與switch搭配的條件轉移是case。使用case後面的標值,控製程式將跳到滿足條件的case處一直往下執行,直到語句結束或遇到break。通常可以使用default把其他例外的情況包含進去。如果switch語句中的條件不成立,控製程式將跳到default處執行;如果省略default子句,則直接執行下一語句。switch是可以嵌套的。
switch (<運算式>) {
case <值1>:
<語句>
break;
case <值2>:
<語句>
default :
<語句>
}
[編輯]循環語句
C語言有三種形式的循環語句:
do
<語句>
while (<表達式>);

while (<表達式>)
<語句>;

for (<表達式1> ; <表達式2> ; <表達式3>)
<語句>;
在while和do中,語句將執行到表達式的值為零時結束。在do...while語句中,循環體將至少被執行一次。這三種循環結構可以互相轉化:
for (<表達式1>; <表達式2>; <表達式3>)
<語句>;
如果<語句>中不使用continue語句的話,相當於
<表達式1>;
while (<表達式2>) {
<語句>;
<表達式3>;
}
當循環條件一直為真時,將產生死循環。
[編輯]跳轉語句
跳轉語句包括四種:goto,continue,break和return。
goto語句是無條件轉移語句:
goto 標記;
標記必須在當前函數中定義,使用「標記:」的格式定義。程式將跳到標記處繼續執行。由於goto容易產生閱讀上的困難,所以應該盡量少用。
continue語句用在迴圈語句中,作用是結束當前一輪的迴圈,馬上開始下一輪迴圈。
break語句用在迴圈語句或switch中,作用是結束當前迴圈,跳到循環體外繼續執行。但是使用break只能跳出一層迴圈。在要跳出多重迴圈時,可以使用goto使得程式更為簡潔。
當一個函數執行結束後要返回一個值時,使用return。return可以跟一個運算式或變數。如果return後面沒有值,將執行不返回值。
[編輯]在C99中的運算符號
()、 []、 -> 、 .、 !、 ++、 -- 、(cast) 括弧、指標、成員、邏輯非、自加、自減、強制轉換
++ 、 -- 、 * 、 & 、 ~ 、 ! 、 + 、 - 、 sizeof 單目運算符
* 、 / 、 % 算術運算符
+ 、 - 算術運算符
<< 、 >> 位運算符
< 、 <= 、 > 、 >= 關系運算符
== 、 != 關系運算符號
& 位與
^ 位異或
| 位或
&& 邏輯與
|| 邏輯或
? 、 : 條件運算符
= 、 += 、 -= 、 *= 、 /= 、 %= 、 < 、 <= 、 > 、 >= 、 &= 、 |= 、 ^= 賦值運算符
, 順序運算符
比較特別的是,位元右移(>>)運運算元可以是算術(左端補最高有效位)或是邏輯(左端補 0)位移。例如,將 11100011 右移 3 位元,算術右移後成為 11111100,邏輯右移則為 00011100。因算術位元右移較適於處理帶負號整數,所以幾乎所有的編譯器都是算術位元右移。(經測試,gcc4.4.3使用c99依然是00011100,即邏輯移位)
[編輯]數據類型
[編輯]基礎數據類型
注意:以下是典型的數據位長和范圍。但是編譯器可能使用不同的數據位長和范圍。這取決於使用的編譯器。請參考具體的參考手冊。
在頭文件<limits.h>和<float.h>中說明了基礎數據的長度。float,double和long double的范圍就是在IEEE 754標准中提及的典型數據。
關鍵字 位長 范圍 printf chars
char 1 -128..127(或0..255,與體系結構相關) %c
unsigned char 1 0..255
signed char 1 -128..127
int 2 or
4 -32768..32767 or
-2147483648..2147483647 %i, %d
unsigned int 2 or
4 0..65535 or
0..4294967295 %u
signed int 2 or
4 -32768..32767 or
-2147483648..2147483647 %i, %d
short int 2 -32768..32767 %hi
unsigned short 2 0..65535 %hu
signed short 2 -32768..32767
long int 4 -2147483648..2147483647 %li, %ld
unsigned long 4 0..4294967295 %lu
signed long 4 -2147483648..2147483647
long long 8 -9223372036854775808..9223372036854775807 %lli
unsigned long long 8 0..18446744073709551615 %llu
float 4 3.4x10-38..3.4x10+38 (7 sf) %f, %e, %g
double 8 1.7x10-308..1.7x10+308 (15 sf) %f, %e, %g
long double 8 或以上 編譯器相關 %Lf, %Le, %Lg
[編輯]陣列
如果一個變數名後面跟著一個有數字的中括弧,這個聲明就是陣列聲明。字串也是一種陣列。它們以ASCII的NUL作為陣列的結束。要特別注意的是,方括內的索引值是從0算起的。
例如:
int myvector [100];/* 從myvector[0]至myvector[99]止共100個元素 */
char mystring [80];
float mymatrix [3] [2] = {2.0 , 10.0, 20.0, 123.0, 1.0, 1.0};
int notfull [3][3] = {{1},{1,2,3},{4,5}}; (*)
char lexicon [10000] [300];/* 共一萬個最大長度為300的字元陣列。*/
int a[3][4];
上面最後一個例子創建了一個陣列,但也可以把它看成是一個多維陣列。注意陣列的下標從0開始。這個陣列的結構如下:
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]
例子(*)創建了一個3*3的二維陣列,初始化時有些元素並未賦值。如下:
1 0 0
1 2 3
4 5 0
為0的位置的數值是隨機的。
[編輯]指針
如果一個變數聲明時在前面使用 * 號,表明這是個指針型變數。換句話說,該變數存儲一個地址,而 * 則是取內容操作符,意思是取這個內存地址里存儲的內容。指針是 C 語言區別於其他同時代高級語言的主要特徵之一。
指針是一把雙刃劍,許多操作可以通過指針自然的表達,但是不正確的或者過分的使用指針又會給程序帶來大量潛在的錯誤。
例如:
int *pi; /* 指向整型數據的指針變數 */
int *api[3];/* 由指向整型數據的指針構成的數組,長度為 3 */
char **argv; /* 指向一個字元指針的指針 */
儲存在指針中的地址所指向的數值在程序中可以由 * 讀取。例如,在第一個例子中, *pi 是一個整型數據。這叫做引用一個指針。
另一個運算符 &,叫做取地址運算符,它將返回一個變數、數組或函數的存儲地址。因此,下面的例子:
int i, *pi; /* int and pointer to int */
pi = &i;
i 和 *pi 在程序中可以相互交替使用,直到 pi 被改變成指向另一個變數的地址。
[編輯]字串
C語言的字元串其實就是char型數組,所以使用字串並不需要引用庫。但是C標准庫確實包含了一些用於對字串進行操作的函數,使得它們看起來就像字串而不是陣列。使用這些函數需要引用標頭檔<string.h>。

[編輯]文件輸入/輸出
在C語言中,輸入和輸出是經由標准函式庫中的一組函數來實現的。在ANSI/ISO C中,這些函數被定義在標頭檔<stdio.h>中。
[編輯]標准輸入/輸出
有三個標准輸入/輸出是標准I/O庫預先定義的:
stdin 標准輸入
stdout 標准輸出
stderr 輸入輸出錯誤

下面的這個例子顯示了一個過濾程式(filter program)是怎樣構成的。
#include <stdio.h>

int main(void)
{
int c;
while (1)
{
c = getchar();
if (c==EOF)
{
perror("getchar()");
return -1;
}
putchar(c);
}

return 0;
}
[編輯]內存管理

C語言的特色之一是:程序員必須親自處理內存的分配細節。
C語言使用棧(Stack)來保存函數返回地址/棧禎基址、完成函數的參數傳遞和函數局部變數的存儲。 如果程序需要在運行的過程中動態分配內存,可以利用堆(Heap)來實現。
基本上C程序的元素存儲在內存的時候有3種分配策略:
靜態分配
如果一個變數聲明為全局變數或者是函數的靜態變數,這個變數的存儲將使用靜態分配方式。靜態分配的內存一般會被編譯器放在數據段或代碼段來存儲,具體取決於實現。這樣做的前提是,在編譯時就必須確定變數的大小。 以 IA32 的 x86 平台及 gcc 編譯器為例,全局及靜態變數放在數據段的低端;全局及靜態常量放在代碼段的高端。
自動分配
函數的自動局部變數應該隨著函數的返回會自動釋放(失效),這個要求在一般的體系中都是利用棧(Stack)來滿足的。相比於靜態分配,這時候,就不必絕對要求這個變數在編譯時就必須確定變數的大小,運行時才決定也不遲,但是C89仍然要求在編譯時就要確定,而C99放鬆了這個限制。但無論是C89還是C99,都不允許一個已經分配的自動變數運行時改變大小。
所以說C函數永遠不應該返回一個局部變數的地址。
要指出的是,自動分配也屬於動態分配,甚至可以用alloca(3)函數來像分配堆(Heap)一樣進行分配,而且釋放是自動的。
動態分配
還有一種更加特殊的情況,變數的大小在運行時有可能改變,或者雖然單個變數大小不變,變數的數目卻有很大彈性,不能靜態分配或者自動分配,這時候可以使用堆(Heap)來滿足要求。ANSI C 定義的堆操作函數是malloc(3)、calloc(3)、realloc(3)和free(3)。
使用堆(Heap)內存將帶來額外的開銷和風險。
[編輯]安全問題

C語言的特色之一是:語言不負責內存邊界檢查。
[編輯]庫

C語言的標准文檔要求了一個平台移植C語言的時候至少要實現的一些功能和封裝的集合,稱為「標准庫」,標准庫的聲明頭部通過預處理器命令#include進行引用。
在C89標准中:
文件 簡介說明
<assert.h> 斷言相關
<ctype.h> 字元類型判斷
<errno.h> 標准報錯機制
<float.h> 浮點運算
<limits.h> 各種體系結構限制
<locale.h> 本地化介面
<math.h> 數學函數
<setjmp.h> 跨函數跳轉
<signal.h> 信號(類似UNIX的信號定義,但是差很遠)
<stdarg.h> 可變參處理
<stddef.h> 一些標准宏定義
<stdio.h> 標准I/O庫
<stdlib.h> 標准工具庫函數
<string.h> ASCIIZ字元串及任意內存處理函數
<time.h> 時間相關
在95年的修正版中
<iso646.h>
<wchar.h>
<wctype.h>
在C99中增加了六個函式庫
<complex.h>
<fenv.h>
<inttypes.h>
<stdbool.h>
<stdint.h>
<tgmath.h>
以上是C語言的標准,而各個平台各自又對C庫函數進行的各種擴充,就浩如煙海了。如POSIX C、GNU C等。
[編輯]保留關鍵字

char short int unsigned
long float double struct
union void enum signed
const volatile typedef auto
register static extern break
case continue default do
else for goto if
return switch while sizeof
[編輯]C99新增關鍵字
_Bool _Complex _Imaginary inline restrict
[編輯]C//

C//是一種結構化的並行語言,讀作C parallel。它基於標准C語言但擴展了為數不多的構造用來表示並行性和進程交互。C//的核心是稱為一致區域的構造,它方便了結構化的、確定的、終止的和復合的並行程序的開發。
[編輯]參考文獻

E. c語言編譯器是用匯編語言寫的嗎

這個是肯定的。演算法優化,首先是邏輯描述的精煉化。至於C,只是計算邏輯到計算機模式的一種映射,而匯編僅是利用特殊計算機指令的一個更深的藕荷。
不過有一點,C語言由於是計算邏輯到計算機模式的映射,所以不單單考慮演算法本身,還肩負數據組織的實現。數據流動方式,數據組織方式,對計算性能的影響也很大。這要看是否和計算機組成原理相貼近。其實這塊也是側重邏輯的設計,而不是具體機器指令的實現,因此匯編是無能為力的。
不過在DSP等特殊CPU架構,C語言和編譯器無法很好的將上述邏輯轉換為機器指令,或者C本身的邏輯無法很好的貼近CPU的特性,那麼還是得匯編。一個典型的例子就是如何使用DSP的並行指令(通常的矢量計算)和並發指令集,幾個不同的指令(隸屬不同處理單元)的同時執行。使用C語言無法描述清楚這些邏輯方式,而編譯器又太水,則還是不得不用匯編。此時C語言僅能淪落到大的計算機組織特性的貼近,和整體框架,模塊的設計上。細節方面無能為力了。

F. C代碼實現並行執行

我是這么想的,你監測鏈表節點是否增加,可以通過增加一個計數器來實現。
因為鏈表節點的增加工作是你自己的程序實現的,那麼你修改一下,讓程序變成每增加一個節點,計數器就增加1,每減少一個節點,計數器就減少1.

每次截取指令時,都保存一下計數器的值。下一次截取指令時,先取得當前計數器值,再與上次保存的計數器值比較,看是否增加了。

第二個思路,你可以加一個鎖(可以是一個全局標志位),當有節點加入時,鎖置位,截取命令時先檢查鎖的狀態。

閱讀全文

與並行c編譯器相關的資料

熱點內容
dvd光碟存儲漢子演算法 瀏覽:758
蘋果郵件無法連接伺服器地址 瀏覽:963
phpffmpeg轉碼 瀏覽:672
長沙好玩的解壓項目 瀏覽:145
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:737
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:302
PDF分析 瀏覽:486
h3c光纖全工半全工設置命令 瀏覽:143
公司法pdf下載 瀏覽:383
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:350
風翼app為什麼進不去了 瀏覽:779
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:151
伊克塞爾文檔怎麼進行加密 瀏覽:893
app轉賬是什麼 瀏覽:163