程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 改善C++程序的建議:語法篇1

改善C++程序的建議:語法篇1

編輯:C++入門知識

改善C++程序的建議:語法篇1


 

建議0 不要讓main函數返回void

操作系統將main作為程序入口,main函數執行程序代碼,最後返回程序的退出狀態。但是C++中有一個好壞難定的規定:

在main函數中,return語句用於離開main函數(析構掉所有的具有動態生存時間的對象),並將其返回值作為參數來調用exit函數。如果函數執行到結尾而沒有遇到return語 句,其效果等同於執行了return 0;。

也就是說編譯器會協助完成返回值的問題。

然而,這樣的壞處就是,當編譯器不支持這個規定的時候,程序就會出錯,比如

int main()

{

}

在VC下編譯是成功的,在g++下編譯,就會提示錯誤:‘main’必須返回’int‘

 

 

建議1 區分0的4個面孔

1 整型0

2 空指針NULL

3 字符串結束標記''

' '是一個字符,占8位,其二進制位表示是 00000000,在C/C++中,''作為字符串的結束標記,是唯一的結束標記

4 邏輯FALSE/false

false/true是標准C++語言裡新增的關鍵字,而FALSE/TRUE是通過#define定義的宏:

#ifndef FALSE

#define FALSE 0

#endif

#ifndef TRUE

#defineTRUE 1

#endif

也就是說FALSE/TRUE是int類型,而false/true是bool型,兩者是不一樣的,bool在C++裡是占用1個字節

 

建議2 避免那些有運算符引起的混亂

 

=和== :在if語句中 比較兩個表達式是否相等,

if( nValue == 0)

{ ... }

如果程序員出現疲勞或精神不集中,把’==‘寫成’=‘,這樣if(nValue = 0),那麼這個if條件是恆成立,並且nValue被賦值為0,並且不會提示錯誤

這恐怕不是程序員想要的。。。

但如果把常量寫在前面,如if(0 == nValue){ },這樣如果程序員寫成if(0 = nValue){ },編譯器會直接的提示錯誤

但是對於&和&& 、|和|| 這類運算符,就需要平時養成謹慎的習慣了。

 

 

建議3 對表達式計算順序不要向當然

讓我們來看一個例子

if(nGrade & MASK == GRAND_ONE)

{...}

我們的本意是,通過nGrade和MASK取與,然後在比較是否等於GRAND_ONE,

可是,實際上上面的代碼的真實效果是if( nGrade & (MASK == GRAND_ONE)){}

這個建議的核心是,不要吝啬括號,讓語義表達的更准確,這樣可以減少出錯

 

如: a = p() + q() * r();

三個函數p() 、q() 、r()的執行順序可能是6種組合中的一個,所以a的值是不確定的,在這種情況下,就需要明確一種執行順序,

int x=p();

int y = q();

a = x+y*r();

 

類似的: expr1 ? expr2 : expr3

建議4 小心宏#define使用中的陷阱

定義宏時,要使用完備的括號:

比如定義兩個參數相加, #define ADD(a,b) ((a)+(b))是一個安全的方式

使用宏時,不允許參數發生變化,

 

定義宏時,用大括號將宏所定義的多條表達式括起來

 

建議5 不要忘記指針變量的初始化

局部變量的指針未初始化,可能導致程序崩潰

全局變量的指針,編譯器會悄悄完成變量的初始化(0)。

 

建議6 明晰逗號分隔表達式的奇怪之處

逗號表達式是從C繼承來的,其中每個表達式都會被執行,不過,整個表達式的值僅是最右邊表達式的結果

如:if(++x,--y,x<20 && y >0),該語句返回的是“ x<20 && y>0”與0比較的結果

另外,逗號表達式既可以用作左值,也可以用作右值。

 

建議7 時刻提防內存溢出

C語言中的字符串庫沒有響應的安全保護措施,strcpy、strcat等函數操作時沒有檢查緩沖區大小,容易引起安全問題

好的方法是,定義一個函數,並傳遞確定的長度,如:

const int DATA_LENGTH = 16;

void DataCopy(char* src ,int len)

{

char dst[DATA_LENGTH];

for(int i=0;src[i] != 0 && i

cout<

if(len < DATA_LENGTH)

strcpy(dst,src);

}

這裡如果,src的長度是10,當i=10時,src[10]就已經越界了。。。

 

 

建議8 拒絕晦澀難懂的函數指針

比如 void (*p[10]) (void (*)() );

1 聲明一個無參數、返回空的函數指針的typedef,如:typedef void (*pfv)();

2 聲明一個指向參數為pfv且返回空的函數指針, 如 : typedef void (*pFun_taking_pfv) (pfv));

3 定義數組,pFun_taking_pfv p[10];

 

建議9 防止頭文件重發包含

方式一:

#ifndef __TEST_H__

#define __TEST_H__

......

#endif

方式二:

#pragma once

優缺點:方式一的缺點是宏導致的編譯時間長

方式二的缺點是只是針對物理路徑相同的文件,而不是文件的內容

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved