1. 程式人生 > >改善一個劣質的C++程式碼

改善一個劣質的C++程式碼

在C++論壇裡發了一個與本文題目相同的貼子如下:

下面是一個我在一個應用系統中發現的我認為很醜陋的一段C++程式碼.顯然,程式碼的意圖是將string中的內容變成相應的小寫字母.請大家指出它的問題之所在,並給出改善後的程式碼.我自已已經有了一個答案,只用一條語句就能實現這個功能.待兩日後我給出我的答案.但然,也許你的答案比我的更好.
void IniReader::string_lower(string& str)
{
    int size=str.length();
    string temp;
    char c;
    for(int i=0;i <size;i++)
    {
        c=str.at(i);
        if(c>=65&&c <=90)
        {
            c+=32;
        }
        else
        {
            continue;
        }
        temp=c;
        str.replace(i,1,temp);
    }
}

我給出的改善的程式碼是:

# include  <string>
inline std::string& string_tolower(std::string& str)
{
   std::transform(str.begin(), str.end(), str.begin(), std::tolower);
   return str;
}

將函式的介面做了調整。這個函式沒有涉及到任何的類的變數,顯然不應該屬於類函式。將修改後的string作為返回值,將使得使用起來更加方便。例如可以如下使用:

std::cout << string_tolower("Hello, UPPER string TO LOWER STRING");

函式的實現使用了stl的模版函式transform實現,這就是我說的用一條語句就實現的地方。首先跟貼的那個表示懷疑的朋友現在是否明白了。

海嘯朋友最先給出transform的解答,其他幾個朋友都寫出了transform的改善方法。基本上符合了我的答案。細節的地方做個說明:那個tolower函式最好加上std::的字首修飾,因為有些系統將tolower定義成了巨集,缺少std的修飾說明,有可能會編譯出錯。另外,這個函式由於簡短,適合於放在標頭檔案中,作為inline函式。

朋友們在注重改善實現的時候,忘記了我還還有一句:請大家指出它的問題之所在。

在這裡我舉出下面幾點:

  • 那麼temp = c 將構成string類的物件,並且在迴圈體內,將嚴重影響效率。而使用replace進行字元替換,顯然是小題大做。因為這裡要進行的是一個字元的更改,並不是將這個字元替換成一個字串。
  • continue語句可以省去。雖然continue語句好於goto語句,但仍然屬於影響正常流程的跳轉語句。
  • 使用數字65表示字元A,可讀性差。
  • 格式風格的美觀可讀性差。比如 if(c>=65&&c <=90) 密密麻麻的擠壓在一起,很難看。寫成  if ( (c >= 64) && (c <= 90) )會更好看一些。

其實,我還可以舉出一些問題。先慢慢來吧。

我只所以說這個程式醜陋,並非是說它一定要用一句tranform來實現就算漂亮了。如果你還不熟悉STL模版庫。也可以寫成下面這樣:

for ( int i = 0; i < str.size(); i++ )
  str[i] = tolower(str[i]);

如果,你還不知道tolower這個函式,也可以寫成下面:


  int c = str[i];
  if ( (c >= 'A') && (c <= 'Z') )
    str[i] = c + ('a' – 'A');

這裡,str.size()由於是inline函式,放在迴圈判斷上不會影響程式的效率,並不需要像原來程式一樣,設一個size的中間變數。同樣,tolower也是inline函式,也不會增加程式的函式呼叫開銷。

如果看了我這篇的解釋,你還不以為然。那我到真希望你來維護一下我看到的這個系統:那可以延長到兩頁的迴圈體裡,佈滿了continue;那充滿了硬編碼的需要你從一堆程式碼中去尋找含義的魔數;那一個類裡面竟然設計了一大堆毫不相關的函式。實在的,我都有快崩潰的感覺。寫醜陋的程式碼,實際上是在給後來使用和維護程式碼的人挖陷阱。當然,跳進這個陷阱的有可能就是你自己。

相關推薦

改善一個劣質C++程式碼

在C++論壇裡發了一個與本文題目相同的貼子如下: 下面是一個我在一個應用系統中發現的我認為很醜陋的一段C++程式碼.顯然,程式碼的意圖是將string中的內容變成相應的小寫字母.請大家指出它的問題之所在,並給出改善後的程式碼.我自已已經有了一個答案,只用一條語句就能實現這個功

C#VS中一個函式呼叫另一個函式的程式碼樣例

//主函式 說明:下面的函式是想求許可證的十六位編號,最後一位是許可編號的校驗碼,是以本體碼("JY" + xukbh)為基礎來計算 entities[0].XuKeZhengBianHao = "JY" + xukbh + xukebianhaojiaoyanma(xukbh);  

一個c#程式碼

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace experment5_1 { class

C# 程式碼開啟一個網路連線

2018年11月02日 14:34:23 maba007 閱讀數:2 個人分類: C#

一個有趣的C程式碼

之前寫的一個小程式碼,但只在Windows下有效果: #include <stdio.h> #include <stdlib.h> #define decode(p,r,i,n,t,f) r##f##r##i##t##p #define puts d

如何在WINFORM中彈出一個又控制元件的對話方塊 能給個簡單的示範C#程式碼嗎 以及一些小問題 菜鳥想學

如何在WINFORM中彈出一個又控制元件的對話方塊  能給個簡單的示範C#程式碼嗎順便問問 這段程式碼是啥意思啊        private void btn_catchMe_Click(object sender, System.EventArgs e)        {

C#程式碼生成一個簡單的PDF檔案(轉)

using System; using System.IO; using System.Text; using System.Collections; namespace PDFGenerator { /// /// Application : Generation of PDF file from

如何將一個C++程式碼工程轉換為matlab的mex檔案直接呼叫呢

1)首先我們要寫一個介面函式mexFunction(),這個介面函式就是類似C++的main函式,它是入口函式,傳遞引數給我們的C++函式。 #include "mex.h" //mx函式,mex函式用到的標頭檔案 #include "exp.h"//呼叫函式用到的標頭檔

一個例子告訴你什麼是封裝,繼承和多型(C++ 程式碼例項) (一)

add by WJB   date 2018/08/30 面向物件的三大特性:封裝,繼承和多型; 封裝:將事物擁有的屬性和動作隱藏起來,只保留特定的方法與外界聯絡。 繼承:子類可以擁有父類的屬性和方法; 多型:以說是“一個介面,多種實現”或者說是父類的引用變數可以指向

從標準輸入裡面不需要按回車得到一個輸入字元 (C程式碼

#include <termios.h> #include <unistd.h> #include <stdio.h> int main(void) {char c;     struct termios tTTYState;    

一個C++編寫的WebSocket客戶端示例程式碼

  上次寫了WebSocket服務端,這次工作當中需要一個用C++實現的WebSocket客戶端,寫好後這裡記一下,免得以後忘記。 本示例共有三個檔案組成,依賴Websocket++第三方庫 其中main.cpp是使用示例 #include <iostream>

一個簡易的打log的c程式碼

log.h  #ifndef _log_h__ #define _log_h__ #define LEVEL_DEBUG 0 #define LEVEL_TUNNINT 1 #define

C#程式碼執行一個程序

程式碼執行一個程序 使用語言:C# 環境:.net Framework 4.6.1 (當前使用) (貌似支援所有環境,我就不多說了) using System.Diagnostics; na

<More Effective C#: 改善C#程式碼的50個有效方法>中文版翻譯答疑

最近, 有一本很讚的.NET技術書中文版出版了 - <More Effective C#: 改善C#程式碼的50個有效方法>.    從廣州\西安\長沙\上海等各地.NET俱樂部都收到反饋, 說這本書是用google翻譯出來的.   然而, 事實上不是

如何利用C# Roslyn編譯器寫一個簡單的程式碼提示/錯誤檢查?

OK, 廢話不多說,這些天在寫C#程式碼時突然對於IDE提示有了一些想法,之前也有了解過,不過並沒有深入。 先看個截圖:      一段再簡單不過的程式碼了,大家注意看到 count 欄位下面的綠色波浪線了嗎,我們通常為理解一個 warning ,滑鼠移上去:  

生成淘口令發現的一個趣事 c#

illegal 技術分享 查看 出錯 設置 www 淘寶聯盟 淘寶客 對象 1、今天,查看網站log,發現如下報錯 詳細錯誤:未將對象引用設置到對象的實例。 報錯url:http://www.94dazhe.com/mobile/goods/show-5

一個C++到Java,再到Hadoop的學習歷程

規則 hadoop 標題 練習 過程 學習過程 又一 學習c++ 改善 在說學習Hadoop之前,先說說我是怎麽學習c++的。因為我是先學的c++,後學的Hadoop。2013年,做著研究生二年級,專業是機械設計,專業方向是智能布局,主要研究的是裝箱問題,什麽是裝箱問題就不

搞清楚ourhdr.h是什麽及運行第一個UNIX C程序

和我 pan 哪裏 char col 函數庫 oot 文件 style 好多人開始學;UNIX 環境高級編程這本書時;看到書裏面說的頭文件ourhdr.h而找不到她在哪裏;而且無法開始繼續學習;其實這個就是系統的內核標準頭文件; 而她的位置在:/usr/include/un

一個簡單c#爬蟲程序

count www 數據 排名 其他瀏覽器 pytho 分享 很多 attr 這篇文章只是簡單展示一個基於HTTP請求如何抓取數據的文章,如覺得簡單的朋友,後續我們再慢慢深入研究探討。 圖1: 如圖1,我們工作過程中,無論平臺網站還是企業官網,總少不了新聞展示。

C程式碼實現從FTP上下載檔案

從FTP上下載檔案這個功能我早就想實現了,但是苦於百度的文章大多是下載連結,一直沒捨得積分下載,這次通過查閱MSDN,將一套下載流程函式摸了一下,寫出程式碼實現從FTP下載檔案 環境 VS2015 程式碼: #include <iostream> #include <