之前以為虛擬碼的作用僅僅是讓程式的邏輯更加清晰,並且只能給自己看。今天看了code complete有亮點非常深的體會。首先是虛擬碼的作用不僅僅是給寫代碼的使用,可以把它直接作為程式的注釋。看一個例子,看看如何寫出好的虛擬碼,並且如何使用它。
increment resource number by 1
allocate a dlg struct using malloc
if malloc() returns NULL then return 1
invoke OSrsrc_init to initialize a resource for the operating system
*hRsrcPtr = resource number
return 0
這是一個寫的非常不好的虛擬碼,首先邏輯不清晰,寫的程式讓人不明白。作為虛擬碼,包含了c語言的代碼細節*hRsrcPtr。還有return 0,這些實現細節完全可以封裝起來。修改後的代碼如下:
Keep track of current number of resources in use
If another resource is available
Allocate a dialog box structure
If a dialog box structure could be allocated
Note that one more resource is in use
Initialize the resource
Store the resource number at the location provided by the caller
Endif
Endif
Return TRUE if a new resource was created; else return FALSE
可以看到使用這個代碼實現的語言可以不僅用c實現,用其它語言的開發人員看到這個虛擬碼也可以很輕鬆的實現。原因在於它的封裝程度高了一層,用自然語言實現,並且邏輯更清晰。
為什麼使用虛擬碼了?可以看到虛擬碼的實現和修改非常容易,相當於在語言層級上的編程,不必設計語言細節。在語言細節上的修改代價是非常大的,但是在虛擬碼層次修改容易。
將虛擬碼如何修改直接作為注釋使用了?再看一個例子:
如何使用這些虛擬碼了?
- /* This routine outputs an error message based on an error code
- supplied by the calling routine. The way it outputs the message
- depends on the current processing state, which it retrieves
- on its own. It returns a value indicating success or failure.
- */
- Status ReportErrorMessage(
- ErrorCode errorToReport
- ) {
- // set the default status to "fail"
- Status errorMessageStatus = Status_Failure;
- // look up the message based on the error code
- Message errorMessage = LookupErrorMessage( errorToReport );
- // if the error code is valid
- if ( errorMessage.ValidCode() ) {
- // determine the processing method
- ProcessingMethod errorProcessingMethod = CurrentProcessingMethod();
- // if doing interactive processing, display the error message
- // interactively and declare success
- if ( errorProcessingMethod == ProcessingMethod_Interactive ) {
- DisplayInteractiveMessage( errorMessage.Text() );
- errorMessageStatus = Status_Success;
- }
- // if doing command line processing, log the error message to the
- // command line and declare success
- else if ( errorProcessingMethod == ProcessingMethod_CommandLine ) {
- CommandLine messageLog;
- if ( messageLog.Status() == CommandLineStatus_Ok ) {
- messageLog.AddToMessageQueue( errorMessage.Text() );
- messageLog.FlushMessageQueue();
- errorMessageStatus = Status_Success;
- }
- else {
- // can't do anything because the routine is already error processing
- }
- else {
- // can't do anything because the routine is already error processing
- }
- }
- // if the error code isn't valid, notify the user that an
- // internal error has been detected
- else {
- DisplayInteractiveMessage(
- "Internal Error: Invalid error code in ReportErrorMessage()"
- );
- }
- // return status information
- return errorMessageStatus;
- }
直接將虛擬碼作為注釋,空白處添加語言代碼。這樣的過程極好的利用了虛擬碼,也可以讓編程的思路更加清晰。其本質是將過程拆分,也是分割的思想。初看
code complete這段的確給我震驚的感覺。虛擬碼的直接利用。
總結下就是先寫出虛擬碼,作為理清思路發現錯誤一個協助,然後再直接將虛擬碼作為注釋在注釋處寫出語言代碼。例子中是c++代碼。