C/C++書寫規範(尾附帶兩篇程式碼做參考)
對於不同的程式語言來說,具體的編碼規範可以有很大的不同,但是其宗旨都是一致的,就是保證程式碼在高質量完成需求的同時具備良好的可讀性、可維護性。例如我們可以規定某個專案的C語言程式要遵循這樣的規定:變數的命名,標頭檔案的書寫和#include 等等。
下面是一些廣為採用的編碼規範:
• GNU Coding Standards
• Guidelines for the Use of the C Language in Vehicle Based Software
• C++ Coding Guidelines
• SUN Code Conventions for Java
以下是一些介紹編碼、編碼規範的書籍:
• C++編碼規範,陳世忠,人民郵電出版社,2002
• 高質量程式設計指南:C++/C語言,林銳等,電子工業出版社,2003
注:以下只是根據課題組已有的經驗給出的總結,並非對所有場景均適用。
對於高質量的工程,一般會做到:
1.程式碼簡潔精煉,美觀,可讀性好,高效率,高複用,可移植性好,高內聚,低耦合,沒有冗餘,不符合這些原則,必須特別說明。
2.規範性,程式碼有規可循。特殊排版、特殊語法、特殊指令,必須特別說明。
一、檔案排版方面
1. 包含標頭檔案
• 先系統標頭檔案,後用戶標頭檔案。
• 系統標頭檔案,穩定的目錄結構,應採用包含子路徑方式。
• 自定義標頭檔案,不穩定目錄結構,應在dsp中指定包含路徑。
• 系統標頭檔案應用:#include <xxx.h>
• 自定義同文件應用:
#include "xxx.h"
• 只引用需要的標頭檔案。
2. h和cpp檔案
• 標頭檔案命名為.h,內聯檔案命名為.inl;C++檔案命名為*.cpp
• 檔名用大小寫混合,或者小寫混合。例如DiyMainview.cpp
,infoview.cpp
。不要用無意義的名稱:例如XImage.cpp
;SView.cpp
;xlog.cpp
;
• 標頭檔案除了特殊情況,應使用#ifdef
控制塊。
• 標頭檔案#endif
應採用行尾註釋。
• 標頭檔案,首先是包含程式碼塊,其次是巨集定義程式碼塊,然後是全域性變數,全域性常量,型別定義,類定義,內聯部分。
• CPP檔案,包含指令,巨集定義,全域性變數,函式定義。
3. 檔案結構
• 檔案應包含檔案頭註釋和內容。
• 函式體類體之間原則上用2個空行,特殊情況下可用一個或者不需要空行。
4. 空行
• 檔案頭、控制塊,#include
部分、巨集定義部分、class
部分、全域性常量部分、全域性變數部分、函式和函式之間,用兩個空行。
二、註釋方面
1. 檔案頭註釋
• 作者,檔名稱,檔案說明,生成日期(可選)
2. 函式註釋
• 關鍵函式必須寫上註釋,說明函式的用途。
• 特別函式引數,需要說明引數的目的,由誰負責釋放等等。
• 除了特別情況,註釋寫在程式碼之前,不要放到程式碼行之後。
• 對每個#else
或#endif
給出行末註釋。
• 關鍵程式碼註釋,包括但不限於:賦值,函式呼叫,表示式,分支等等。
• 善未實現完整的程式碼,或者需要進一步優化的程式碼,應加上 // TODO …
• 除錯的程式碼,加上註釋 // only for DEBUG
• 需要引起關注的程式碼,加上註釋 // NOTE …
• 對於較大的程式碼塊結尾,如for,while,do
等,可加上 // end for|while|do
三、命名方面
1. 原則
• 同一性:在編寫一個子模組或派生類的時候,要遵循其基類或整體模組的命名風格,保持命名風格在整個模組中的同一性。
• 識別符號組成:標識符采用英文單詞或其組合,應當直觀且可以拼讀,可望文知意,用詞應當準確,避免用拼音命名。
• 最小化長度 && 最大化資訊量原則:在保持一個識別符號意思明確的同時,應當儘量縮短其長度。
• 避免過於相似:不要出現僅靠大小寫區分的相似的識別符號,例如"i"與"I"
,"function"
與"Function"
等等。
• 避免在不同級別的作用域中重名:程式中不要出現名字完全相同的區域性變數和全域性變數,儘管兩者的作用域不同而不會發生語法錯誤,但容易使人誤解。
• 正確命名具有互斥意義的識別符號:用正確的反義片語命名具有互斥意義的識別符號,如:"nMinValue"
和"nMaxValue"
,"GetName()"
和"SetName()"
….
• 避免名字中出現數字編號:儘量避免名字中出現數字編號,如Value1,Value2等,除非邏輯上的確需要編號。這是為了防止程式設計師偷懶,不肯為命名動腦筋而導致產生無意義的名字(因為用數字編號最省事)。
2. T,C,M,R類
• T類表示簡單資料型別,不對資源擁有控制權,在析構過程中沒有釋放資源動作。
• C表示從CBase繼承的類。該類不能從棧上定義變數,只能從堆上建立。
• M表示介面類。
• R是資源類,通常是系統固有型別。除了特殊情況,不應在開發程式碼中出現R型別。
3. 函式名
• M類的函式名稱應採用HandleXXX
命名,例如:HandleTimerEvent;
不推薦採用java風格,例如handleTimerEvent;
除了標準c風格程式碼,不推薦用下劃線,例如,handle_event
。
• Leave函式,用字尾L。
• Leave函式,且進清除棧,用字尾LC。
• Leave函式,且刪除物件,用字尾LD。
4. 函式引數
• 函式引數用a作為字首。
• 避免出現和匈牙利混合的命名規則如apBuffer
名稱。用aBuffer
即可。
• 函式引數比較多時,應考慮用結構代替。
• 如果不能避免函式引數比較多,應在排版上可考慮每個引數佔用一行,引數名豎向對齊。
5. 成員變數
• 成員變數用m最為字首。
• 避免出現和匈牙利混合的命名規則如mpBuffer名稱。用mBuffer即可。
6. 區域性變數
• 迴圈變數和簡單變數採用簡單小寫字串即可。例如,int i;
• 指標變數用p
打頭,例如void* pBuffer;
7. 全域性變數
• 全域性變數用g_
最為字首。
8. 類名
• 類和物件名應是名詞。
• 實現行為的類成員函式名應是動詞。
• 類的存取和查詢成員函式名應是名詞或形容詞。
9. 風格相容性
• 對於移植的或者開源的程式碼,可以沿用原有風格,不用C++的命名規範。
四、程式碼風格方面
1. Tab和空格
• 每一行開始處的縮排只能用Tab,不能用空格,輸入內容之後統一用空格。除了最開始的縮排控制用Tab,其他部分為了對齊,需要使用空格進行縮排。這樣可以避免在不同的編輯器下顯示不對齊的情況。
• 在程式碼行的結尾部分不能出現多餘的空格。
• 不要在"::","->","."
前後加空格。
• 不要在",",";"
之前加空格。
2. 型別定義和{
• 類,結構,列舉,聯合:大括號另起一行
3. 函式
• 函式體的{需要新起一行,在{之前不能有縮排。
• 除了特別情況,函式體內不能出現兩個空行。
• 除了特別情況,函式體內不能巨集定義指令。
• 在一個函式體內,邏揖上密切相關的語句之間不加空行,其它地方應加空行分隔。
• 在標頭檔案定義的inline
函式,函式之間可以不用空行,推薦用一個空行。
4. 程式碼塊
• "if"、"for"、"while"、"do"、"try"、"catch"
等語句自佔一行,執行語句不得緊跟其後。不論執行語句有多少都要加 “{ }” 。這樣可以防止書寫和修改程式碼時出現失誤。
• "if"、"for"、"while"、"do"、"try"、"catch"
的括號和表示式,括號可緊挨關鍵字,這樣強調的是表示式。
5. else
• if語句如果有else語句,用 } else { 編寫為一行,不推薦用 3 行程式碼的方式。
6. 程式碼行
• 一行程式碼只做一件事情,如只定義一個變數,或只寫一條語句。這樣的程式碼容易閱讀,並且方便於寫註釋。
• 多行變數定義,為了追求程式碼排版美觀,可將變數豎向對齊。
• 程式碼行最大長度宜控制在一定個字元以內,能在當前螢幕內全部可見為宜。
7. switch語句
• case關鍵字應和switch對齊。
• case子語句如果有變數,應用{}包含起來。
• 如果有並列的類似的簡單case語句,可考慮將case程式碼塊寫為一行程式碼。
• 簡單的case之間可不用空行,複雜的case之間應考慮用空行分割開。
• case字語句的大括號另起一行,不要和case寫到一行。
• 為所有switch語句提供default分支。
• 若某個case不需要break一定要加註釋宣告。
8. 迴圈
• 空迴圈可用 for( ;; )
或者 while( 1 )
或者 while( true )
9. 類
• 類繼承應採用每個基類佔據一行的方式。
• 單繼承可將基類放在類定義的同一行。如果用多行,則應用Tab縮排。
• 多繼承在基類比較多的情況下,應將基類分行,並採用Tab縮排對齊。
• 過載基類虛擬函式,應在該組虛擬函式前寫註釋 // implement XXX
• 友元宣告放到類的末尾。
10. 巨集
• 不要用分號結束巨集定義。
• 函式巨集的每個引數都要括起來。
• 不帶引數的巨集函式也要定義成函式形式。
11. goto
• 儘量不要用goto
。
五、型別
• 定義指標和引用時*和&緊跟型別。
• 儘量避免使用浮點數,除非必須。
• 用typedef
簡化程式中的複雜語法。
• 避免定義無名稱的型別。例如:typedef enum { EIdle, EActive } TState;
• 少用union,如果一定要用,則採用簡單資料型別成員。
• 用enum
取代(一組相關的)常量。
• 不要使用魔鬼數字。
• 儘量用引用取代指標。
• 定義變數完成後立即初始化,勿等到使用時才進行。
• 如果有更優雅的解決方案,不要使用強制型別轉換。
六、表示式
• 避免在表示式中用賦值語句。
• 避免對浮點型別做等於或不等於判斷。
• 不能將列舉型別進行運算後再賦給列舉變數。
• 在迴圈過程中不要修改迴圈計數器。
• 檢測空指標,用 if( p )
• 檢測非空指標,用 if( ! p )
七、函式
1. 引用
• 引用型別作為返回值:函式必須返回一個存在的物件。
• 引用型別作為引數:呼叫者必須傳遞一個存在的物件。
2. 常量成員函式
• 表示該函式只讀取物件的內容,不會對物件進行修改。
3. 返回值
• 除開void
函式,建構函式,解構函式,其它函式必須要有返回值。
• 當函式返回引用或指標時,用文字描述其有效期。
4. 行內函數
• 行內函數應將函式體放到類體外。
• 只有簡單的函式才有必要設計為行內函數,複雜業務邏輯的函式不要這麼做。
• 虛擬函式不要設計為行內函數。
5. 函式引數
• 只讀取該引數的內容,不對其內容做修改,用常量引用。
• 修改引數內容,或需要通過引數返回,用非常量應用。
• 簡單資料型別用傳值方式。
• 複雜資料型別用引用或指標方式。
八、類
1. 建構函式
• 建構函式的初始化列表,應和類的順序一致。
• 初始化列表中的每個項,應獨佔一行。
• 避免出現用一個成員初始化另一個成員。
• 建構函式應初始化所有成員,尤其是指標。
• 不要在建構函式和解構函式中丟擲異常。
2. 純虛擬函式
• M類的虛擬函式應設計為純虛擬函式。
3. 構造和解構函式
• 如果類可以繼承,則應將類解構函式設計為虛擬函式。
• 如果類不允許繼承,則應將類解構函式設計為非虛擬函式。
• 如果類不能被複制,則應將拷貝建構函式和賦值運算子設計為私有的。
• 如果為類設計了建構函式,則應有解構函式。
4. 成員變數
• 儘量避免使用mutable
和Volatile
。
• 儘量避免使用公有成員變數。
5. 成員函式
• 努力使類的介面少而完備。
• 儘量使用常成員函式代替非常成員函式,const
函式
• 除非特別理由,絕不要重新定義(繼承來的)非虛擬函式。(這樣是覆蓋,基類的某些屬性無初始化)
6. 繼承
• 繼承必須滿足IS-A的關係,HAS-A應採用包含。
• 虛擬函式不要採用預設引數。
• 除非特別需要,應避免設計大而全的虛擬函式,虛擬函式功能要單一。
• 除非特別需要,避免將基類強制轉換成派生類。
7. 友元
• 儘量避免使用友元函式和友元類。
九、錯誤處理
• 申請記憶體用new操作符。
對於不同的程式語言來說,具體的編碼規範可以有很大的不同,但是其宗旨都是一致的,就是保證程式碼在高質量完成需求的同時具備良好的可讀性、可維護性。例如我們可以規定某個專案的C語言程式要遵循這樣的規定:變數的命名,標頭檔案的書寫和#include 等等。下面是一些廣為採用的編碼規範 系統 must 那是 一點 class xxx 編程規範 自己 ++ 本文總結一些經驗教訓,以使編出來的代碼更為健壯。
1、定義類/結構體的時候不要和系統函數沖突(尤其是不同系統/平臺之間移植的時候)
有時候在windows系統下編譯沒問題,但是在linux系統下就
總體原則
1、清晰第一
2、簡潔為美
3、選擇合適的風格,與程式碼原有風格保持一致
1 標頭檔案
對於C語言來說,標頭檔案的設計體現了大部分的系統設計。
原則1.1 標頭檔案中適合放置介 edit 成員 擴展 ati art info ets 簡單 ole C# 7.0已經出來一段時間了,大家都知道新特性裏面有個對元組的優化,並且網上也有大量的介紹,這裏利用詳盡的例子詳解Tuple VS ValueTuple(元組類VS值元組),10分鐘讓你更了解Value 項目 回車 pop ace log () client protocol comm 這個例子只是簡單實現了如何使用 Socket 類實現面向連接的通信。
註意:此例子的目的只是為了說明用套接字寫程序的大概思路,而不是實際項目中的使用程序。在這個例子中,實際上還有很多問題
題意
給出 n和m並且
1
<
n
整理gets、getchar、scanf的異同前,一個很重要的概念是輸入流緩衝區及鍵盤緩衝區。
鍵盤緩衝區就是當你鍵盤鍵入內容時,內容儲存的地方。
而當裡面的內容遇到回車的時候,它們就會被存入輸入流緩衝區。
注意,回車的"\n"也會被存入輸入流緩衝區。
getchar和scanf就是從輸入流
C++ STL中最基本以及最常用的類或容器無非就是以下幾個:
string
vector
set
list
map
下面就依次介紹它們,並給出一些最常見的最實用的使用方法,做到快速入門。
string
首先看看我們C語言一般怎麼使用字串的
c
1 提前求值
1 概念
上一篇介紹了“延緩求值”——lazy evalute策略,其實質是:只有在真正需要資料的時候,才對計算進行求值。同時,常用的一種的策略是“馬上求值”——eager evaluate,即只要出現計算表示式,就進行求值。
上面兩種方案都沒有考
Problem C. Dynamic Graph Matching
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Su
https://ac.nowcoder.com/acm/contest/337#question
A—新年快樂
無腦printf就行了
B—平均身高
注意 / 兩邊都是整數時,計算結果是整數部分,比如, 1 / 2 的結果不是0.5,而是0
可以加個 首先show一把報錯資訊
“Missing semicolon.” : “缺少分號.”,
“Use the function form of \”use strict\”.” : “使用標準化定義function.”,
“Unexpected space after ‘-’.” : “在’-'後面不應
在C語言中,對陣列進行賦值的三種形式
1、通過迴圈的形式 即:陣列名[下標] 對陣列的元素進行依次賦值
#include <stdio.h>
int main()
{
int i;
int a[10] = {0}
C#程式碼與javaScript函式的相互呼叫:
1.如何在JavaScript訪問C#函式?
2.如何在JavaScript訪問C#變數?
3.如何在C#中訪問JavaScript的已有變數?
4.如何在C#中訪問JavaScript函式?
問題1答案如下:
一、類模板定義
定義一個類模板:template<class 模板引數表>
class 類名{
// 類定義......
};其中,template 是宣告類模板的關鍵字,表示宣告一個模板,模板引數可以是一個,也可以是多個,可以是型別引數,也可以是非型別引數。型
public 所有均可訪問private 類自己的成員函式訪問,不能被類物件訪問protected 類自己以及子類訪問,不能被類物件訪問friend 友元,別人是你的朋友,他可以訪問我的東西。(但不是我可以訪問他的東西)友元關係不能被繼承。友元關係是單向的,不具有交換性。若
這個例子只是簡單實現瞭如何使用 Socket 類實現面向連線的通訊。
注意:此例子的目的只是為了說明用套接字寫程式的大概思路,而不是實際專案中的使用程式。在這個例子中,實際上還有很多問題沒有解決,如訊息邊界問題、埠號是否被佔用、訊息命令的解析問題等。。
下面是兩個
原文網址:http://www.360doc.com/content/14/0508/15/11029609_375813213.shtml
研究了下用oc實現常用的演算法,參考了一些資料後自己用程式碼檢驗了下,以下程式碼均測試可用。其中arr引數是一個可變陣列,其中存 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
char str[9999]; // str 刪除多餘空格後的
int cint[25],cmain[25
獲取當前的時間的秒數和微秒數本方法需要用到gettimeofday()函式,該函式需要引入的標頭檔案是sys/time.h 。
函式說明int gettimeofday (struct timeval * tv, struct timezone * tz)
• 釋放記憶體用delete操作符。
• new
和
相關推薦
C/C++書寫規範(尾附帶兩篇程式碼做參考)
C++編程規範(不斷更新)
華為C語言程式設計規範(整理)
詳解C# Tuple VS ValueTuple(元組類 VS 值元組)
C# Socket簡單例子(服務器與客戶端通信)
codeforces511div1_b Little C Loves 3 II (二分圖匹配+打表+找規律)
C的輸入整理(gets、getchar、scanf的異同)
C++常用的容器(vector、set、list、map)
13 More Effective C++—條款18/19(提前求值/臨時物件的來源)
杭電多校第三場1003 C. Dynamic Graph Matching(狀壓dp 處理圖匹配計數)
哈理工2018大一上學期C語言期末考試題(也是牛客第六場)題解
TypeScript的書寫規範(TSLint)配置修改
C語言之陣列(陣列賦值的三種形式)
C#和JavaScript互動(asp.net前臺和後臺互調)
C++ 類模板小結(雙向連結串列的類模板實現)
C++之訪問控制(public、private、protected以及friend)
C# Socket簡單例子(伺服器與多個客戶端通訊)
用objective-c 實現常用演算法(冒泡、選擇、快速、插入)
綜合實踐報告(7)C程式原始碼操作(內附五套程式碼)
Linux 下c獲取當前時間(精確到秒和毫秒或者微秒)