『壹』 c/c++多線程編程中,為什麼基本類型不用加鎖
先 你描述的不對 嚴格來說是在對應的cpu體系下遵循了正確的內存對齊的方式的數據才有不需要加鎖的可能
加鎖主要是防止partial read/.1;write 請參考《intel開發者手冊》第三卷8;write以及cpu亂序帶來的cpu操作可見性問題
舉x86-64的例子來說 一個基本類型如果地址無cache splite(落在兩個cacheline中) 都可以保證無partial read/.1
『貳』 C語言編程技術的優勢和劣勢
隨著互聯網編程技術的不斷發展,現在大多數的軟體開發都是通過編程語言來實現的,今天我們就一起來了解一下C語言編程開發技術都有哪些優勢和劣勢。
C語言的一些好的體驗
一次通過閱讀POV-Ray源代碼學會如何在C語言中實現面向對象編程。
通過閱讀GTK+源代碼了解C語言代碼的清晰、干凈和可維護性。
通過閱讀SIOD和Guile的源代碼,知道如何使用C語言實現Scheme解析器。
使用C語言寫出GNOMEEye的初始版本,並對MicroTile渲染進行調優。
C語言的一些不好的體驗
在Evolution團隊時,很多東西老是崩潰。那個時候還沒有Valgrind,為了得到Purify這個軟體,需要購買一台Solaris機器。
調試gnome-vfs線程死鎖問題。
調試Mesa,卻無果。
接手Nautilus-share的初始版本,卻發現代碼裡面居然沒有使用free()。
想要重構代碼,卻不知道該如何管理好內存。
想要打包代碼,卻發現到處是全局變數,而且沒有靜態函數。
但不管怎樣,還是來說說那些Rust里有但C語言里沒有的東西吧。
自動資源管理
Rust從C++那裡借鑒了一些想法,如RAII(,資源獲取即初始化)和智能指針,並加入了值的單一所有權原則,還提供了自動化的決策性資源管理機制。
自動化:不需要手動調用free()。內存使用完後會自動釋放,文件使用完後會自動關閉,互斥鎖在作用域之外會自動釋放。如果要封裝外部資源,基本上只要實現Drop這個trait就可以了。封裝過的資源就像是編程語言的一部分,因為你不需要去管理它的生命周期。
決策性:資源被創建(內存分配、初始化、打開文件等),然後在作用域之外被銷毀。根本不存在垃圾收集這回事:代碼執行完就都結束了。程序數據的生命周期看起來就像是函數調用樹。
如果在寫代碼時老是忘記調用這些方法(free/close/destroy),或者發現以前寫的代碼已經忘記調用,甚至錯誤地調用,那麼以後我再也不想使用這些方法了。
泛型
Vec真的就是元素T的vector,而不只是對象指針的數組。在經過編譯之後,它只能用來存放類型T的對象。
在C語言里需要些很多代碼才能實現類似的功能,所以我不想再這么幹了。
trait不只是interface
Rust並不是一門類似那樣的面向對象編程語言,它有trait,看起來就像是里的interface——可以用來實現動態綁定。如果一個對象實現了Drawable,那麼就可以肯定該對象帶有draw()方法。
不過不管怎樣,trait的威力可不止這些。
依賴管理
以前實現依賴管理需要:
手動調用或通過自動化工具宏來調用g-config。
指定頭文件和庫文件路徑。
基本上需要人為確保安裝了正確版本的庫文件。
而在Rust里,只需要編寫一個Cargo.toml文件,然後在文件里指明依賴庫的版本。這些依賴庫會被自動下載下來,或者從某個指定的地方獲取。
測試
C語言的單元測試非常困難,原因如下:
內部函數通常都是靜態的。也就是說,它們無法被外部文件調用。測試程序需要使用#include指令把源文件包含進來,或者使用#ifdefs在測試過程中移除這些靜態函數。
需要編寫Makefile文件將測試程序鏈接到其中的部分依賴庫或部分代碼。
需要使用測試框架,並把測試用例注冊到框架上,還要學會如何使用這些框架。
衛生宏(HygienicMacro)
Rust的衛生宏避免了C語言宏可能存在的問題,比如宏中的一些東西會掩蓋掉代碼里的標識符。Rust並不要求宏中所有的符號都必須使用括弧,比如max(5+3,4)。
沒有自動轉型
在C語言里,昆明北大青鳥http://www.kmbdqn.cn/發現很多bug都是因為在無意中將int轉成short或char而導致,而在Rust里就不會出現這種情況,因為它要求顯示轉型。
不會出現整型溢出
這個就不用再多作解釋了。
『叄』 c/c++多線程編程中,為什麼基本類型不用加鎖
首先 你描述的不對 嚴格來說是在對應的cpu體系下遵循了正確的內存對齊的方式的數據才有不需要加鎖的可能
加鎖主要是防止partial read/write以及cpu亂序帶來的cpu操作可見性問題
舉x86-64的例子來說 一個基本類型如果地址無cache splite(落在兩個cacheline中) 都可以保證無partial read/write 請參考《intel 開發者手冊》第三卷8.1.1.1章
另外一個功能就是杜絕cpu亂序引起的可見性問題了 僅局限於x86-64來說 如果你操控的這個基本類型對於storeload亂序不敏感 做到良好對齊就足夠了 當然cpu亂序又是一個更深入的問題了 手機上說不清 一般來說 lock 都帶有 mb-aquire的語意 unlock都帶有mb-release的語意 因此加鎖可以解決亂序問題
另外 題主懷疑多個緩存數據會不一致 這一點是不會發生的 這一點不是由操作系統保證的 而是每種cpu硬體都會遵守類似於mesi的緩存一致性協議 緩存的數據更改會在fsb上傳遞給各個其他cpu 這種復雜的一致性方式帶來了性能問題 於是又引入了storebuffer和invalidate queue等機制來優化 從而導致cpu亂序的發生 又引入了各種memory barrior指令在必要時防止亂序的發生 在應用層這些被封裝在各種鎖里
上面所說局限於smp結構
『肆』 昆明北大青鳥分享C語言編程技術的優勢和劣勢
隨著互聯網編程技術的不斷發展,現在大多數的軟體開發都是通過編程語言來實現的,今天我們就一起來了解一下C語言編程開發技術都有哪些優勢和劣勢。
C語言的一些好的體驗
一次通過閱讀POV-Ray源代碼學會如何在C語言中實現面向對象編程。
通過閱讀GTK+源代碼了解C語言代碼的清晰、干凈和可維護性。
通過閱讀SIOD和Guile的源代碼,知道如何使用C語言實現Scheme解析器。
使用C語言寫出GNOME Eye的初始版本,並對MicroTile渲染進行調優。
C語言的一些不好的體驗
在Evolution團隊時,很多東西老是崩潰。那個時候還沒有Valgrind,為了得到Purify這個軟體,需要購買一台Solaris機器。
調試gnome-vfs線程死鎖問題。
調試Mesa,卻無果。
接手Nautilus-share的初始版本,卻發現代碼裡面居然沒有使用free()。
想要重構代碼,卻不知道該如何管理好內存。
想要打包代碼,卻發現到處是全局變數,而且沒有靜態函數。
但不管怎樣,還是來說說那些Rust里有但C語言里沒有的東西吧。
自動資源管理
Rust從C++那裡借鑒了一些想法,如RAII(Resource Acquisition Is Initialization,資源獲取即初始化)和智能指針,並加入了值的單一所有權原則,還提供了自動化的決策性資源管理機制。
自動化:不需要手動調用free()。內存使用完後會自動釋放,文件使用完後會自動關閉,互斥鎖在作用域之外會自動釋放。如果要封裝外部資源,基本上只要實現Drop這個trait就可以了。封裝過的資源就像是編程語言的一部分,因為你不需要去管理它的生命周期。
決策性:資源被創建(內存分配、初始化、打開文件等),然後在作用域之外被銷毀。根本不存在垃圾收集這回事:代碼執行完就都結束了。程序數據的生命周期看起來就像是函數調用樹。
如果在寫代碼時老是忘記調用這些方法(free/close/destroy),或者發現以前寫的代碼已經忘記調用,甚至錯誤地調用,那麼以後我再也不想使用這些方法了。
泛型
Vec真的就是元素T的vector,而不只是對象指針的數組。在經過編譯之後,它只能用來存放類型T的對象。
在C語言里需要些很多代碼才能實現類似的功能,所以我不想再這么幹了。
trait不只是interface
Rust並不是一門類似那樣的面向對象編程語言,它有trait,看起來就像是里的interface——可以用來實現動態綁定。如果一個對象實現了Drawable,那麼就可以肯定該對象帶有draw()方法。
不過不管怎樣,trait的威力可不止這些。
依賴管理
以前實現依賴管理需要:
手動調用或通過自動化工具宏來調用g-config。
指定頭文件和庫文件路徑。
基本上需要人為確保安裝了正確版本的庫文件。
而在Rust里,只需要編寫一個Cargo.toml文件,然後在文件里指明依賴庫的版本。這些依賴庫會被自動下載下來,或者從某個指定的地方獲取。
測試
C語言的單元測試非常困難,原因如下:
內部函數通常都是靜態的。也就是說,它們無法被外部文件調用。測試程序需要使用#include指令把源文件包含進來,或者使用#ifdefs在測試過程中移除這些靜態函數。
需要編寫Makefile文件將測試程序鏈接到其中的部分依賴庫或部分代碼。
需要使用測試框架,並把測試用例注冊到框架上,還要學會如何使用這些框架。
衛生宏(Hygienic Macro)
Rust的衛生宏避免了C語言宏可能存在的問題,比如宏中的一些東西會掩蓋掉代碼里的標識符。Rust並不要求宏中所有的符號都必須使用括弧,比如max(5 + 3, 4)。
沒有自動轉型
在C語言里,昆明北大青鳥http://www.kmbdqn.com/發現很多bug都是因為在無意中將int轉成short或char而導致,而在Rust里就不會出現這種情況,因為它要求顯示轉型。
不會出現整型溢出
這個就不用再多作解釋了。
『伍』 武漢北大青鳥分享C語言編程技術的優勢和劣勢
隨著互聯網編程技術的不斷發展,現在大多數的軟體開發都是通過編程語言來實現的,今天我們就一起來了解一下C語言編程開發技術都有哪些優勢和劣勢。
C語言的一些好的體驗一次通過閱讀POV-Ray源代碼學會如何在C語言中實現面向對象編程。
通過閱讀GTK+源代碼了解C語言代碼的清晰、干凈和可維護性。
通過閱讀SIOD和Guile的源代碼,知道如何使用C語言實現Scheme解析器。
使用C語言寫出GNOMEEye的初始版本,並對MicroTile渲染進行調優。
C語言的一些不好的體驗在Evolution團隊時,很多東西老是崩潰。
那個時候還沒有Valgrind,為了得到Purify這個軟體,需要購買一台Solaris機器。
調試gnome-vfs線程死鎖問題。
調試Mesa,卻無果。
接手Nautilus-share的初始版本,卻發現代碼裡面居然沒有使用free()。
想要重構代碼,卻不知道該如何管理好內存。
想要打包代碼,卻發現到處是全局變數,而且沒有靜態函數。
但不管怎樣,還是來說說那些Rust里有但C語言里沒有的東西吧。
自動資源管理Rust從C++那裡借鑒了一些想法,如RAII(,資源獲取即初始化)和智能指針,並加入了值的單一所有權原則,還提供了自動化的決策性資源管理機制。
自動化:不需要手動調用free()。
內存使用完後會自動釋放,文件使用完後會自動關閉,互斥鎖在作用域之外會自動釋放。
如果要封裝外部資源,基本上只要實現Drop這個trait就可以了。
封裝過的資源就像是編程語言的一部分,因為你不需要去管理它的生命周期。
決策性:資源被創建(內存分配、初始化、打開文件等),然後在作用域之外被銷毀。
根本不存在垃圾收集這回事:代碼執行完就都結束了。
程序數據的生命周期看起來就像是函數調用樹。
如果在寫代碼時老是忘記調用這些方法(free/close/destroy),或者發現以前寫的代碼已經忘記調用,甚至錯誤地調用,那麼以後我再也不想使用這些方法了。
泛型Vec真的就是元素T的vector,而不只是對象指針的數組。
在經過編譯之後,它只能用來存放類型T的對象。
在C語言里需要些很多代碼才能實現類似的功能,所以我不想再這么幹了。
trait不只是interfaceRust並不是一門類似那樣的面向對象編程語言,它有trait,看起來就像是里的interface——可以用來實現動態綁定。
如果一個對象實現了Drawable,那麼就可以肯定該對象帶有draw()方法。
不過不管怎樣,trait的威力可不止這些。
依賴管理以前實現依賴管理需要:手動調用或通過自動化工具宏來調用g-config。
指定頭文件和庫文件路徑。
基本上需要人為確保安裝了正確版本的庫文件。
而在Rust里,只需要編寫一個Cargo.toml文件,然後在文件里指明依賴庫的版本。
這些依賴庫會被自動下載下來,或者從某個指定的地方獲取。
測試C語言的單元測試非常困難,原因如下:內部函數通常都是靜態的。
也就是說,它們無法被外部文件調用。
測試程序需要使用#include指令把源文件包含進來,或者使用#ifdefs在測試過程中移除這些靜態函數。
需要編寫Makefile文件將測試程序鏈接到其中的部分依賴庫或部分代碼。
需要使用測試框架,並把測試用例注冊到框架上,還要學會如何使用這些框架。
衛生宏(HygienicMacro)Rust的衛生宏避免了C語言宏可能存在的問題,比如宏中的一些東西會掩蓋掉代碼里的標識符。
Rust並不要求宏中所有的符號都必須使用括弧,比如max(5+3,4)。
沒有自動轉型在C語言里,武漢北大青鳥http://www.kmbdqn.cn/發現很多bug都是因為在無意中將int轉成short或char而導致,而在Rust里就不會出現這種情況,因為它要求顯示轉型。
不會出現整型溢出這個就不用再多作解釋了。
『陸』 西安北大青鳥分享C語言編程技術的優勢和劣勢
隨著互聯網編程技術的不斷發展,現在大多數的軟體開發都是通過編程語言來實現的,今天我們就一起來了解一下C語言編程開發技術都有哪些優勢和劣勢。
C語言的一些好的體驗一次通過閱讀POV-Ray源代碼學會如何在C語言中實現面向對象編程。
通過閱讀GTK+源代碼了解C語言代碼的清晰、干凈和可維護性。
通過閱讀SIOD和Guile的源代碼,知道如何使用C語言實現Scheme解析器。
使用C語言寫出GNOMEEye的初始版本,並對MicroTile渲染進行調優。
C語言的一些不好的體驗在Evolution團隊時,很多東西老是崩潰。
那個時候還沒有Valgrind,為了得到Purify這個軟體,需要購買一台Solaris機器。
調試gnome-vfs線程死鎖問題。
調試Mesa,卻無果。
接手Nautilus-share的初始版本,卻發現代碼裡面居然沒有使用free()。
想要重構代碼,卻不知道該如何管理好內存。
想要打包代碼,卻發現到處是全局變數,而且沒有靜態函數。
但不管怎樣,還是來說說那些Rust里有但C語言里沒有的東西吧。
自動資源管理Rust從C++那裡借鑒了一些想法,如RAII(,資源獲取即初始化)和智能指針,並加入了值的單一所有權原則,還提供了自動化的決策性資源管理機制。
自動化:不需要手動調用free()。
內存使用完後會自動釋放,文件使用完後會自動關閉,互斥鎖在作用域之外會自動釋放。
如果要封裝外部資源,基本上只要實現Drop這個trait就可以了。
封裝過的資源就像是編程語言的一部分,因為你不需要去管理它的生命周期。
決策性:資源被創建(內存分配、初始化、打開文件等),然後在作用域之外被銷毀。
根本不存在垃圾收集這回事:代碼執行完就都結束了。
程序數據的生命周期看起來就像是函數調用樹。
如果在寫代碼時老是忘記調用這些方法(free/close/destroy),或者發現以前寫的代碼已經忘記調用,甚至錯誤地調用,那麼以後我再也不想使用這些方法了。
泛型Vec真的就是元素T的vector,而不只是對象指針的數組。
在經過編譯之後,它只能用來存放類型T的對象。
在C語言里需要些很多代碼才能實現類似的功能,所以我不想再這么幹了。
trait不只是interfaceRust並不是一門類似那樣的面向對象編程語言,它有trait,看起來就像是里的interface——可以用來實現動態綁定。
如果一個對象實現了Drawable,那麼就可以肯定該對象帶有draw()方法。
不過不管怎樣,trait的威力可不止這些。
依賴管理以前實現依賴管理需要:手動調用或通過自動化工具宏來調用g-config。
指定頭文件和庫文件路徑。
基本上需要人為確保安裝了正確版本的庫文件。
而在Rust里,只需要編寫一個Cargo.toml文件,然後在文件里指明依賴庫的版本。
這些依賴庫會被自動下載下來,或者從某個指定的地方獲取。
測試C語言的單元測試非常困難,原因如下:內部函數通常都是靜態的。
也就是說,它們無法被外部文件調用。
測試程序需要使用#include指令把源文件包含進來,或者使用#ifdefs在測試過程中移除這些靜態函數。
需要編寫Makefile文件將測試程序鏈接到其中的部分依賴庫或部分代碼。
需要使用測試框架,並把測試用例注冊到框架上,還要學會如何使用這些框架。
衛生宏(HygienicMacro)Rust的衛生宏避免了C語言宏可能存在的問題,比如宏中的一些東西會掩蓋掉代碼里的標識符。
Rust並不要求宏中所有的符號都必須使用括弧,比如max(5+3,4)。
沒有自動轉型在C語言里,西安北大青鳥http://www.kmbdqn.cn/發現很多bug都是因為在無意中將int轉成short或char而導致,而在Rust里就不會出現這種情況,因為它要求顯示轉型。
不會出現整型溢出這個就不用再多作解釋了。
『柒』 c語言的編程開發
GCC,GNU組織開發的開源免費的編譯器
MinGW,Windows操作系統下的GCC
Clang,開源的BSD協議的基於LLVM的編譯器
Visual C++ :: cl.exe,Microsoft VC++自帶的編譯器 CodeBlocks,開源免費的C/C++ IDE
CodeLite,開源、跨平台的C/C++集成開發環境
Orwell Dev-C++,可移植的C/C++IDE
C-Free
Light Table
Visual Stdio系列 起初,C語言沒有官方標准。1978年由美國電話電報公司(AT&T)貝爾實驗室正式發表了C語言。布萊恩·柯林漢(Brian Kernighan) 和 丹尼斯·里奇(Dennis Ritchie) 出版了一本書,名叫《The C Programming Language》。這本書被 C語言開發者們稱為K&R,很多年來被當作 C語言的非正式的標准說明。人們稱這個版本的 C語言為K&R C。
K&R C主要介紹了以下特色:
結構體(struct)類型
長整數(long int)類型
無符號整數(unsigned int)類型
把運算符=+和=-改為+=和-=。因為=+和=-會使得編譯器不知道使用者要處理i = -10還是i =- 10,使得處理上產生混淆。
即使在後來ANSI C標准被提出的許多年後,K&R C仍然是許多編譯器的最 准要求,許多老舊的編譯器仍然運行K&R C的標准。 1970到80年代,C語言被廣泛應用,從大型主機到小型微機,也衍生了C語言的很多不同版本。
1983年,美國國家標准協會(ANSI)成立了一個委員會X3J11,來制定 C語言標准。
1989年,美國國家標准協會(ANSI)通過了C語言標准,被稱為ANSI X3.159-1989 Programming Language C。因為這個標準是1989年通過的,所以一般簡稱C89標准。有些人也簡稱ANSI C,因為這個標準是美國國家標准協會(ANSI)發布的。
1990年,國際標准化組織(ISO)和國際電工委員會(IEC)把C89標準定為C語言的國際標准,命名為ISO/IEC 9899:1990 - Programming languages -- C 。因為此標準是在1990年發布的,所以有些人把簡稱作C90標准。不過大多數人依然稱之為C89標准,因為此標准與ANSI C89標准完全等同。
1994年,國際標准化組織(ISO)和國際電工委員會(IEC)發布了C89標准修訂版,名叫ISO/IEC 9899:1990/Cor 1:1994 ,有些人簡稱為C94標准。
1995年,國際標准化組織(ISO)和國際電工委員會(IEC)再次發布了C89標准修訂版,名叫ISO/IEC 9899:1990/Amd 1:1995 - C Integrity ,有些人簡稱為C95標准。 1999年1月,國際標准化組織(ISO)和國際電工委員會(IEC)發布了C語言的新標准,名叫ISO/IEC 9899:1999 - Programming languages -- C ,簡稱C99標准。這是C語言的第二個官方標准。
在C99中包括的特性有: 增加了對編譯器的限制,比如源程序每行要求至少支持到 4095 位元組,變數名函數名的要求支持到 63 位元組(extern 要求支持到 31)。 增強了預處理功能。例如: 宏支持取可變參數 #define Macro(...) __VA_ARGS__ 使用宏的時候,允許省略參數,被省略的參數會被擴展成空串。 支持 // 開頭的單行注釋(這個特性實際上在C89的很多編譯器上已經被支持了) 增加了新關鍵字 restrict, inline, _Complex, _Imaginary, _Bool 支持 long long, long double _Complex, float _Complex 等類型 支持不定長的數組,即數組長度可以在運行時決定,比如利用變數作為數組長度。聲明時使用 int a[var] 的形式。不過考慮到效率和實現,不定長數組不能用在全局,或 struct 與 union 里。 變數聲明不必放在語句塊的開頭,for 語句提倡寫成 for(int i=0;i<100;++i) 的形式,即i 只在 for 語句塊內部有效。 允許採用(type_name){xx,xx,xx} 類似於 C++ 的構造函數的形式構造匿名的結構體。 復合字面量:初始化結構的時候允許對特定的元素賦值,形式為:
struct test{int a[3],b;} foo[] = { [0].a = {1}, [1].a = 2 }; struct test{int a, b, c, d;} foo = { .a = 1, .c = 3, 4, .b = 5 }; // 3,4 是對 .c,.d 賦值的 格式化字元串中,利用 u 支持 unicode 的字元。 支持 16 進制的浮點數的描述。 printf scanf 的格式化串增加了對 long long int 類型的支持。 浮點數的內部數據描述支持了新標准,可以使用 #pragma 編譯器指令指定。 除了已有的 __line__ __file__ 以外,增加了 __func__ 得到當前的函數名。 允許編譯器化簡非常數的表達式。 修改了 /% 處理負數時的定義,這樣可以給出明確的結果,例如在C89中-22 / 7 = -3, -22% 7 = -1,也可以-22 / 7= -4, -22% 7 = 6。 而C99中明確為 -22 / 7 = -3, -22% 7 = -1,只有一種結果。 取消了函數返回類型默認為 int 的規定。 允許 struct 定義的最後一個數組不指定其長度,寫做 [](flexible array member)。 const const int i 將被當作 const int i 處理。 增加和修改了一些標准頭文件,比如定義 bool 的 <stdbool.h> ,定義一些標准長度的 int 的 <inttypes.h> ,定義復數的 <complex.h> ,定義寬字元的 <wctype.h> ,類似於泛型的數學函數 <tgmath.h>, 浮點數相關的 <fenv.h>。 在<stdarg.h> 增加了 va_ 用於復制 ... 的參數。里增加了 struct tmx ,對 struct tm 做了擴展。 輸入輸出對寬字元以及長整數等做了相應的支持。 GCC和其它一些商業編譯器支持C99的大部分特性。 2011年12月8日,國際標准化組織(ISO)和國際電工委員會(IEC)再次發布了C語言的新標准,名叫ISO/IEC 9899:2011 - Information technology -- Programming languages -- C ,簡稱C11標准,原名C1X。這是C語言的第三個官方標准,也是C語言的最新標准。
新的標准提高了對C++的兼容性,並增加了一些新的特性。這些新特性包括: 對齊處理(Alignment)的標准化(包括_Alignas標志符,alignof運算符, aligned_alloc函數以及<stdalign.h>頭文件。 _Noreturn 函數標記,類似於 gcc 的 __attribute__((noreturn))。 _Generic 關鍵字。 多線程(Multithreading)支持,包括: _Thread_local存儲類型標識符,<threads.h>頭文件,裡麵包含了線程的創建和管理函數。 _Atomic類型修飾符和<stdatomic.h>頭文件。 增強的Unicode的支持。基於C Unicode技術報告ISO/IEC TR 19769:2004,增強了對Unicode的支持。包括為UTF-16/UTF-32編碼增加了char16_t和char32_t數據類型,提供了包含unicode字元串轉換函數的頭文件<uchar.h>. 刪除了 gets() 函數,使用一個新的更安全的函數gets_s()替代。 增加了邊界檢查函數介面,定義了新的安全的函數,例如 fopen_s(),strcat_s() 等等。 增加了更多浮點處理宏。 匿名結構體/聯合體支持。這個在gcc早已存在,C11將其引入標准。 靜態斷言(static assertions),_Static_assert(),在解釋 #if 和 #error 之後被處理。 新的 fopen() 模式,(「…x」)。類似 POSIX 中的 O_CREAT|O_EXCL,在文件鎖中比較常用。 新增 quick_exit() 函數作為第三種終止程序的方式。當 exit()失敗時可以做最少的清理工作。
『捌』 佳音北大青鳥分享C語言編程技術的優勢和劣勢
隨著互聯網編程技術的不斷發展,現在大多數的軟體開發都是通過編程語言來實現的,今天我們就一起來了解一下C語言編程開發技術都有哪些優勢和劣勢。
C語言的一些好的體驗一次通過閱讀POV-Ray源代碼學會如何在C語言中實現面向對象編程。
通過閱讀GTK+源代碼了解C語言代碼的清晰、干凈和可維護性。
通過閱讀SIOD和Guile的源代碼,知道如何使用C語言實現Scheme解析器。
使用C語言寫出GNOMEEye的初始版本,並對MicroTile渲染進行調優。
C語言的一些不好的體驗在Evolution團隊時,很多東西老是崩潰。
那個時候還沒有Valgrind,為了得到Purify這個軟體,需要購買一台Solaris機器。
調試gnome-vfs線程死鎖問題。
調試Mesa,卻無果。
接手Nautilus-share的初始版本,卻發現代碼裡面居然沒有使用free()。
想要重構代碼,卻不知道該如何管理好內存。
想要打包代碼,卻發現到處是全局變數,而且沒有靜態函數。
但不管怎樣,還是來說說那些Rust里有但C語言里沒有的東西吧。
自動資源管理Rust從C++那裡借鑒了一些想法,如RAII(,資源獲取即初始化)和智能指針,並加入了值的單一所有權原則,還提供了自動化的決策性資源管理機制。
自動化:不需要手動調用free()。
內存使用完後會自動釋放,文件使用完後會自動關閉,互斥鎖在作用域之外會自動釋放。
如果要封裝外部資源,基本上只要實現Drop這個trait就可以了。
封裝過的資源就像是編程語言的一部分,因為你不需要去管理它的生命周期。
決策性:資源被創建(內存分配、初始化、打開文件等),然後在作用域之外被銷毀。
根本不存在垃圾收集這回事:代碼執行完就都結束了。
程序數據的生命周期看起來就像是函數調用樹。
如果在寫代碼時老是忘記調用這些方法(free/close/destroy),或者發現以前寫的代碼已經忘記調用,甚至錯誤地調用,那麼以後我再也不想使用這些方法了。
泛型Vec真的就是元素T的vector,而不只是對象指針的數組。
在經過編譯之後,它只能用來存放類型T的對象。
在C語言里需要些很多代碼才能實現類似的功能,所以我不想再這么幹了。
trait不只是interfaceRust並不是一門類似那樣的面向對象編程語言,它有trait,看起來就像是里的interface——可以用來實現動態綁定。
如果一個對象實現了Drawable,那麼就可以肯定該對象帶有draw()方法。
不過不管怎樣,trait的威力可不止這些。
依賴管理以前實現依賴管理需要:手動調用或通過自動化工具宏來調用g-config。
指定頭文件和庫文件路徑。
基本上需要人為確保安裝了正確版本的庫文件。
而在Rust里,只需要編寫一個Cargo.toml文件,然後在文件里指明依賴庫的版本。
這些依賴庫會被自動下載下來,或者從某個指定的地方獲取。
測試C語言的單元測試非常困難,原因如下:內部函數通常都是靜態的。
也就是說,它們無法被外部文件調用。
測試程序需要使用#include指令把源文件包含進來,或者使用#ifdefs在測試過程中移除這些靜態函數。
需要編寫Makefile文件將測試程序鏈接到其中的部分依賴庫或部分代碼。
需要使用測試框架,並把測試用例注冊到框架上,還要學會如何使用這些框架。
衛生宏(HygienicMacro)Rust的衛生宏避免了C語言宏可能存在的問題,比如宏中的一些東西會掩蓋掉代碼里的標識符。
Rust並不要求宏中所有的符號都必須使用括弧,比如max(5+3,4)。
沒有自動轉型在C語言里,佳音北大青鳥http://www.kmbdqn.cn/發現很多bug都是因為在無意中將int轉成short或char而導致,而在Rust里就不會出現這種情況,因為它要求顯示轉型。
不會出現整型溢出這個就不用再多作解釋了。
『玖』 數字密碼鎖C語言編程
近年來,隨著生活水平的不斷改善,個人財富日益增長,人們對安全防盜的要求也逐漸提高。安全可靠、使用方便的電子密碼鎖成了人們防盜的首選。以Max +PlusⅡ(Multiple Array Matrix and ProgrammingLogic User SystemⅡ,多陣列矩陣及可編程邏輯用戶系統Ⅱ)為工作平台,使用PLD可編程器件和VHDL語言設計的帶音樂的電子密碼鎖具有密碼預置,誤碼鎖死及開鎖音樂提示等功能。這種設計不僅簡化了系統結構,降低了成本,更提高了系統的可靠和保密性。採用PLD可編程邏輯器件開發的數字系統,可以方便地升級和改進。
1 設計思路
密碼鎖電路由鍵盤控制、密碼設置和音樂演奏三大功能模塊組成,原理如圖1所示。Count,Keyvalue,Contrl,Smdisplay構成鍵盤控制模塊,Songer是音樂演奏模塊,Set是密碼設置模塊。
1.1 鍵盤控制
鍵盤主要完成向系統輸入數據,傳送命令等功能。它是一個機械彈性按鍵開關的集合,利用機械觸點的合、斷作用產生高、低電平。通過對電平高低狀態的檢測,以確認按鍵按下與否。一個電壓信號通過機械觸點的斷開、閉合過程的波形如圖2所示。
在該鍵盤電路中,Count模塊提供鍵盤的行掃描信號Q[3..0]。在沒有按鍵按下時,信號EN為高電平,行掃描輸出信號Q[3..0]的循環變化順序為0001 OO100100 1000 0001(依次掃描4行按鍵);當有按鍵按下時,信號EN為低電平,行掃描輸出信號Q[3..0]停止掃描,並鎖存當前的行掃描值。例如按下第一行的按鍵,那麼Q[3..O]=0001。
Keyvalue模塊的主要功能是對輸入按鍵的行信號Q[3..0]和列信號14[3..0]的當前組合值進行判斷來確定輸入按鍵的鍵值。
Contrl模塊的主要功能是實現按鍵的消抖,判斷是否有按鍵按下。確保對按鍵的提取處於圖2所示的閉合穩定時間范圍內,這就對本模塊的輸入時鍾信號有一定的要求,在本設計中該模塊輸入的時鍾信號頻率為64 Hz。Smdisplay模塊主要是完成數碼管動態掃描和七段解碼顯示的功能。
1.2 音樂演奏電路Songer
根據聲樂學知識,組成樂曲的每個音符的發音頻率值及其持續的時間是樂曲能連續演奏所需的兩個基本要素。獲得這兩個要素所對應的數值以及通過純硬體的手段來利用這些數值實現所希望樂曲的演奏效果是關鍵。如圖3所示,該電路需要由NOTETABS(音調發生器)、TONETABA、SPEAKER(數控分頻器)三個模塊組成,分別實現了聲音產生、節拍控制、音調控制的功能。
1.3 密碼設置
Set模塊是實現密碼鎖功能的核心模塊。其主要作用是設置密碼,Set為設置密碼的有效信號,可以實現修改密碼的功能。En為輸入密碼確認信號,當輸入完六位密碼後確認輸入,一旦輸入的密碼跟所設置的密碼一致時,則輸出信號OP有效(高電平);OP控制演奏音樂,此時音樂響起。若密碼不正確,則指示輸入錯誤及輸入次數,輸完三次無效後密碼鎖鎖死,必須由RESET信號(啟動信號,給一個低電平)重新打開密碼鎖功能。
2 電路的VHDL描述
鍵盤控制電路,音樂演奏電路以及密碼設置模塊均使用硬體描述語言VHSIC Hardware Description Lan-guage(VHDL)設計而成。例如:TONETABA的VHDL模型如下:
VHDL語言具有很強的電路描述和建模能力,能從多個層次對數字系統進行建模和描述,支持各種模式的設計方法:自頂向下與自底向上或混合方法,從而大大簡化了硬體的設計任務,提高了設計效率和可靠性。它同時具有與具體硬體電路無關和與設計平台無關的特性,所以用VHDL進行電子系統設計,設計者可以專心致力於其功能的實現,而不需要對其他相關因素花費過多的時間和精力。
設計步驟
3.1 設計輸入
首先在合適的路徑下建立本設計的文件夾,然後用VHDL語言編輯Count,Keyvalue,Contrl,Smdisplay等電路,並在Max+PlusⅡ軟體中使用文本編輯器輸入上述各電路模塊的VHDL程序,編譯生成各模塊;最後在Max+PlusⅡ軟體中使用圖形編輯器以自底向上的方法編輯原理圖。先編輯圖3電路,以Singer.gdf命名,其次使用「Create default Symbol」生成Songer模塊,然後再編輯如圖1所示原理電路圖。
3.2 模擬測試及編程下載配置
將設計好的項目存檔,並將其設置成Project。選擇目標器件為ACEX系列中的EP1K30QC208-2,啟動編譯,如果發現編譯出現錯誤,修正後再次編譯。編譯後即可對波形文件進行模擬,並進行測試和波形分析。分析完成後進行編程下載配置。
3.3 硬體測試
在高電平時,通過鍵盤的0~F號鍵進行6位密碼輸入,密碼輸入完畢後通過單擊確認鍵進行密碼設置確認。當輸入的密碼與設置的密碼一致時,揚聲器開始循環演奏樂曲,且數碼管SM8顯示輸入密碼的次數,數碼管SM7顯示密碼輸入是否正確。如果密碼正確,則SM7顯示『0』;如果密碼錯誤,則SM7顯示『E』。數碼管SM6~SM1顯示輸入的6位密碼。在密碼輸入正確開始演奏樂曲時,如果將撥位開關KD4撥向上,則數碼管SM8顯示樂曲的音符,而此時若將撥位開關KD3撥向上則停止演奏樂曲。發光二極體LED1~LED4顯示輸入按鍵的鍵值,LED16監控是否有按鍵按下。
4 結 語
使用Max+PlusⅡ軟體和VHDL語言設計電路,思路簡單,功能明了;不僅可以進行邏輯模擬,還可以進行時序模擬;使用PLD器件不僅省去了電路製作的麻煩,還可以反復多次進行硬體實驗,非常方便地修改設計,且設計的電路保密性很強。總之,採用Max+PlusⅡ軟體和VHDL語言使得復雜的電子系統的設計變得簡單容易,大大提高了設計效率。
如果對您有幫助,請記得採納為滿意答案,謝謝!祝您生活愉快!
『拾』 密碼鎖c語言編程代碼
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
intmain()
{
charpassword[10],password2[10];
memset(password,0,sizeof(password));
memset(password2,0,sizeof(password2));
printf("請設置8位數以內密碼: ");
scanf("%s",password);
printf("請設置校驗密碼: ");
scanf("%s",password2);
if(atoi(password2)==atoi(password))
{
printf("密碼輸入正確!: ");
}
else
{
printf("密碼輸入錯誤!: ");
}
return0;
}