C++編程思想 第二卷 勘誤

注:這是我本人在看C++編程思想 第二卷:實用編程技術(刁成嘉譯)時發現的翻譯問題。特此列一表,供各位參考及討論 。

本人收集的翻譯不妥之處大部分爲那些狗屁不通之句,影響讀者理解之句以及誤人子弟之句。關於名詞翻譯的修改較少,希望能夠給各位軟件初學者以一定幫助。

若本人勘誤有錯,歡迎指正。

 

勘誤連接
第一章 異常處理 P3 P4 P9 P9 P17 P29
第二章 防禦性編程 P32 P36 P48 P50 P52 P52 P52 P53 P53
第三章 深入理解字符串 P63 P65 P67 P75 通篇錯誤
第四章 輸入輸出流 P91 P91 P95 P96 P96 P102 P109 P117 P124 P127 P128 P129 P129
第五章 深入理解模板 P138 P154 P156(1) P156(2) P158 P160 P167 P179 P184
   
   
   
   
   
   

 

 

 

 

 

 

 

 

 

第一部分 建立穩定的系統

第一章 異常處理

 P3 函數setjmp( )的行爲很特別,因爲如果直接調用它,它便會將所有與當前處理器相 關的狀態信息(比如指令指針的內容、運行時棧指針等)保存到jmp_buf中去並返回0。在這種情況下,它的 表現和一個普通函數一樣。然而,如果使用同一個jmp_buf調用longjmp( ),則函數返回時就像剛從setjmp( )中返回時一樣——又回到了剛剛從setjmp( )返回的地方。

原文:The setjmp( ) function is odd because if you call it directly, it stores all the relevant information about the current processor state (such as the contents of the instruction pointer and runtime stack pointer) in the jmp_buf and returns zero. In this case it behaves like an ordinary function. However, if you call longjmp( ) using the same jmp_buf, it’s as if you’re returning from setjmp( ) again—you pop right out the back end of the setjmp( ).

勘誤:setjmp( )是一個特殊的函數,因爲如果你直接調用,它會保存關於當前處理器狀態 的所有相關信息(比如指令指針和運行時棧指針的內容)到jmp_buf中並返回0。假如是這樣的話,它與普通函數的表現無異。 然而,如果你調用longjmp( )去使用同一個jmp_buf的話,它(的行爲)就會好像你又從setjmp( )回來一樣——你 恰好從setjmp( )(函數體)的末端跳出來。

P4 在C++中使用longjmp()的問題是它不能識別對象。

原文:The problem in C++ is that longjmp( ) doesn’t respect objects;

 勘誤:在C++中的問題是,longjmp()它不關心對象。

P9 如果try塊之後的異常處理器不能匹配所拋出的異常,那麼這個異常就會被傳遞給位於更高 一層語境中的異常處理器,也就是說函數或try塊周圍的try塊不捕獲這個異常。

原文: If none of the exception handlers following aparticular try block matches an exception, that exception moves to the next-higher context, that is,the function or try block surrounding the try block that did not catch the exception.

 勘誤:如果某一個特定try塊後面的catcher沒有一個能匹配所拋出的異常,那個異 常就會移動到更高語境中去,更高的語境即:框在那個不能catch異常的try塊外面的函數或try塊

P9 在下列兩種情況下terminate( )函數也會執行:局部對象的析構函數拋出異常時,棧正在進 行清理工作……

原文:The terminate( ) function also executes if a destructor for a local object throws an exception while the stack is unwinding...

勘誤:terminate( )函數會在下列兩種情況下執行:正在進行stack unwinding時,局部對 象的析構函數拋出了一個異常

P17 length_error 表明程序試圖產生一個長度大於等於npos的對象(語境長度的最大可能值 的類型通常爲std::size_t)

原文:length_error  Indicates an attempt to produce an object whose length is greater than or equal to npos (the largest representable value of context’s size type, usually std::size_t).

勘誤:length_error  表明試圖產生一個對象,其長度大於等於npos(npos是環境尺 寸類型所能表示的最大可能值,通常是爲std::size_t)

P29 每當函數被調用的時候,有關這個函數的信息被壓到運行棧頂部的活動記錄實例 (activation record instance, ARI)中,也叫棧結構(stack frame)。典型的棧結構包含調用函數的指令所在的地址(這 樣,程序的執行流程可以返回到這個地址),指向這個函數靜態父對象的ARI(某個作用域,它在詞法上包含被調用函數,這樣 這個函數就可以訪問全局變量了)的指針,指向調用函數的指針(它的動態父函數)。沿着動態父函數鏈反覆追蹤得到的邏輯 結果路徑就是動態鏈,或稱其爲調用鏈,讀者在這一章的前面見到過它。這就是爲什麼當異常拋出時執行流程能夠回溯,這種 機制使得在彼此缺乏瞭解的情況下開發出來程序的各個部分,能夠在運行時互相傳遞出錯信息。

原文:Whenever a function is called, information about that function is pushed onto the runtime stack in an activation record instance (ARI), also called a stack frame. A typical stack frame contains the address of the calling function (so execution can return to it), a pointer to the ARI of the function’s static parent (the scope that lexically contains the called function, so variables global to the function can be accessed), and a pointer to the function that called it (its dynamic parent). The path that logically results from repetitively following the dynamic parent links is the dynamic chain, or call chain, that we’ve mentioned previously in this chapter. This is how execution can backtrack when an exception is thrown, and it is the mechanism that makes it possible for components developed without knowledge of one another to communicate errors at runtime.

勘誤:無論一個函數何時被調用,其信息都會被壓入(push)到存在於ARI(activation record instance)中的運行時棧(runtime stack)的頂部,ARI也被稱爲stack frame。一個典型的stack frame包含正在被調 用的函數的地址(因此執行流程可以返回至那個地址),一個指向函數靜態根源的ARI的指針(函數靜態根源,function's static parent,是一個在語法上包含被調函數的轄域(scope),因此,被調函數能夠訪問到對其而言是全局的變量),和一個 調用該函數的函數的指針(被調函數的動態根源)。在邏輯上通過反覆跟蹤動態根源鏈而得到路徑就是動態鏈(dynamic chain ),或稱爲調用鏈(call chain),這個我們在本章前面提到過它。這就是當一個異常被拋出時一個執行流程怎樣回溯的過程 。這個機制也使得,在彼此不瞭解的情況下開發出來的組件,能夠在運行時交換報錯信息成爲可能。 


第二章 防禦性編程

P32 在程序某個特定的地方,應該能夠大膽地聲明某些條件或其它一些控制方法

原文:At certain points in your program, you should be able to make bold statements that some condition or other holds.

勘誤:在程序的某一個地方,你應該能夠明確的陳述一些條件或把握。

 P36 由於經營成本方面的考慮,迫使編程人員損害系統的功能性,放棄了代碼的可擴展 性,而這正是保持代碼持久性所需要的。“如果程序沒有壞掉,就不要修改它”,最後的方法是“沒法修改它 ——重寫算了。”這種情況必須改變。

原文:Management's reluctance to let you tamper with a functioning system robs code of the resilience it needs to endure.“If it’s not broken, don’t fix it” eventually gives way to, “We can’t fix it—rewrite it.” Change is necessary.

勘誤:讓你玩弄機能系統的而導致的管理上的難度,使你放棄了其(機能系統)持續發展 所需要的有彈性的代碼。“如果它沒壞,就不要修”最終就導致成了“我們無法修復,重寫吧”的情況 。因此,改寫代碼是必需。

P48 這部分和下面部分內容所包含的代碼已經被C++標準正式拒絕了。

原文:DISCLAIMER: This section and the next contain code which is officially unsanctioned by the C++ Standard.

勘誤:免責聲明:本節及下一節所包含的代碼還未被C++標準接受。

P50 它們之間沒有什麼差別,雖然在編譯時沒有反對對動態存儲區使用輸入輸出流,但是當嘗 試使用輸入輸出流時,有些編譯器會報錯。

原文:It shouldn't make a difference, since we're not interfering with iostreams's use of the free store, but when we tried it, some compilers complained.

勘誤:這樣做應該不會有什麼差別,因爲iostream使用free storage的時候我們不會受到 妨礙,但是當我們試圖這樣做的話(iostream使用free storage),有些編譯器會報錯。

P52 MemCheck工具在Info結構類型的數組中保存全部內存地址、文件名和行號:內存地址是使 用operator new()分配內存時得到的,文件名是new運算符所在的文件的文件名,而行號是new運算符所在行的行號。

原文:The MemCheck facility tracks memory by keeping all addresses allocated by operator new( ) in an array of Info structures, which also holds the file name and line number where the call to new occurred.

勘誤:MemChecd組件通過把所有用new()分配的內存地址存放在一個Info結構體數組來跟蹤 內存,這個數組也存放了new()被調時所在的文件名和行號。

P52 但是,在這裏這樣做的目的是發現內存泄漏,而不是調試庫。

原文:but our purpose here is to find your leaks; we’re not debugging the library.

勘誤:但是我們的目的是找出你自己的內存泄漏。我們不是在對庫進行調試。

P52 簡單的說,現在做的所有工作就是排列new和delete,將它們進行匹配。

原文:For simplicity, we forward all work for array new and delete to their scalar counterparts.

勘誤:爲了簡單起見,我們將new[],delete[]的工作交給它們的單體版本(就是非數組 new,delete)。

P53 這個例子證實了,可以在如下場合使用MemCheck:代碼中使用了流,代碼中使用了標準容 器(standard containers),以及代碼中某個類的構造函數分配了內存。

原文:This example verifies that you can use MemCheck in the presence of streams, standard containers, and classes that allocate memory in constructors.

勘誤:這個例子說明了你可以在有流、標準容器、在構造函數中分配內存的類的情況下使 用MemCheck。

P53 因爲調用了MEM_OFF( ),所以後面vector和ostream對operator delete( )的調用過程沒 有進行。

原文:Because of the call to MEM_OFF( ), no subsequent calls to operator delete( ) by vector or ostream are processed.

勘誤:因爲調用了MEM_OFF( ),所以沒有對後續vector和ostream對delete( )的調用進行 處理(就是跟蹤)。

 


第二部分 標準C++庫

 

第三章 深入理解字符串

本章的通篇錯誤:引用字符串,引用字符數組 全部都改成 引 號內的字符串 引號內的字符數組

P63 如果要生成的新字符串的規模比當前的字符串大或者說是需要截短原字符串,resize( ) 函數就會在字符串的末尾追加空格。

原文:A resize( ) function appends spaces if the new size is greater than the current string size or truncates the string otherwise.

勘誤:如果新尺寸比當前尺寸大的話,resize( )函數會在當前字符串後面追加空格,或相 反的,resize( )也可以截斷當前字符串。

P65 將變量LookHere表示的位置傳送到替換串,這是很重要的,以防字符串from是字符串to的 字串。

原文:It is important to advance the position held in the variable lookHere past the replacement string, in case from is a substring of to.

勘誤:將lookHere所表示的位置向前推並超過替換字符串(的長度)是非常重要的,以防 from是to的子串的情況。(舉個例子,如果from是"n",to是"nn",如果lookHere的增量是1的話,那麼 這個這個字符串就會無限變長)

P67 在語句的右邊,程序員幾乎可以採用任何一種樣式對由單個或多個字符構成的分組進行賦 值。

原文:On the right side of the statement, you can use almost any type that evaluates to a group of one or more characters.

勘誤:在語句的右邊,你可以使用幾乎任何(數據)類型,只要它們可以變成一個由一個 或多個字符構成的組合。

P75 引用文字

原文:quoted literals

勘誤:引號內的文字

 


第四章 輸入輸出流

 

P91 把類型安全檢查交給I/O庫來完成似乎是欠妥的,尤其是進行大量I/O操作時。

原文:It seems a shame to throw type safety away for an I/O library, especially since I/O is used a lot.

勘誤:既然I/O用得很多,那麼拋棄對I/O庫的類型安全支持顯得尤其遺憾。

P91 救助輸入輸出流

原文:Iostream to the rescue

勘誤:來自iostream的幫助 

P95 例如,看看本章前面是如何在頭文件中聲明Date流操作符的。

原文:Consider, for example, how you would declare the Date stream operators introduced earlier in the chapter in a header file.

勘誤:舉個例子,設想一下你會如何在頭文件裏聲明本章前面介紹的Date類的流操作符。

P96 可以通過調用流的成員函數來測試錯誤

原文:You can detect stream errors by either calling certain stream member functions to see if an error state has occurred...

勘誤:你可以調用流成員函數來偵測是否有錯誤狀態發生

P96 ...或者如果不關心到底發生了什麼錯誤,而僅僅用來評估流中這個布爾變量的來龍去脈 。

原文:...or if you don’t care what the particular error was, you can just evaluate the stream in a Boolean context.

勘誤:或者如果你並不關心到底發生了什麼錯誤,你可以直接把流放入一個邏輯判斷語境 中進行評估。(注:諸如if(cin)這樣的邏輯判斷語句)

P102 重置失敗位

原文:不需要原文,這種翻譯太噁心

勘誤:重置fail bit

P109 ios::showpoint 顯示浮點值的小數點並截斷字末尾的0

原文:Show decimal point and trailing zeros for floating-point values.

勘誤:爲浮點值顯示小數點及其後面的0

P109 ios::skipws 跳過空格(輸入流的默認情況)

原文:ios::skipws Skip white space. (For input; this is the default.)

勘誤:ios::skipws跳過空白格(輸入流的默認情況)。注:空白格white space指的是空 格,tab,換行符

P117 在這裏,不需要知道應用算子是如何創建操縱算子的;僅需知道操縱算子的存在。

原文:You don’t need to know how applicators work to create your own manipulator; you only need to know that they exist.

勘誤:你若想創建你自己的操縱符,你沒有必要知道應用操作符是如何工作。你只需知道 應用操縱符的存在即可。

P124 當所有的文件處理結束後,關閉文件(到達文件範圍末尾)

原文:When the whole file is processed, it is closed (by reaching the end of a scope)

勘誤:整個文件處理完畢後,文件關閉(到達作用域末端時)

P127 注意必須將參數設置爲char*類型,因爲write( )使用專用流(narrow stream)

原文:—notice it must be cast to a char* because that’s what write( ) expects for narrow streams.

勘誤:注意將其轉換成char*,因爲write( )要求窄流(narrow stream)。 PS.後面我們的 刁成嘉副教授又將narrow stream 翻譯成了窄字符流

P128 總而言之,讀者用這些方法可以創建不同字符類型的流。

原文:In a perfect world, this is all you’d need to create streams of different character types.

勘誤:理想狀態下,你只需這樣就可以創建不同字符類型的流。

P129 例如,對錶達式widen('-')來說就是將其參數轉變成L'-'(文字語法相當於wchar_t ('-')轉變),如果爲寬字符流則不進行轉換。

原文:The expression widen('-'), for example, converts its argument to L'-' (the literal syntax equivalent to the conversion wchar_t('-')) if the stream is a wide stream and leaves it alone otherwise.

勘誤:例如,如果流爲寬流,則widen('-')表達式將其參數轉換成L'-'(語法上等價於 wchar_t('-')轉換),如果不是,就不轉換。

P129 如果需要,函數narrow( )將字符轉換成char類型

原文:There is also a narrow( ) function that converts to a char if needed.

勘誤:如果需要,也有一個轉換爲char型的narrow( )函數

 


 

第五章 深入理解模板

P138 如果還沒有聲明Seq是一個模板類型的模板參數,編譯器就不會在這裏將Seq解釋爲一 個模板,儘管已經如此使用了它。

原文:If we hadn’t declared Seq to be a template template parameter, the compiler would complain here that Seq is not a template, since we're using it as such.

勘誤:(刁成嘉你難道看不出來if hadn't..., would是虛擬語氣麼?)如果我們沒有將 Seq聲明爲模板的模板型參數,編譯器會報錯說Seq不是一個模板,因爲我們正將它當作一個模板來使用。

P154 一個函數模板要考慮多種特化,在這些特化的模板中對於某個特定的函數模板來說, 如果每一種可能的參數列表的選擇都能夠匹配該模板的參數列表,那麼,這些可能的參數列表選擇也都能夠匹配另一個函數模 板的參數列表,但反過來卻不成立。(我們的刁成嘉教授在寂靜了16頁之後,終於忍不住又開始即興發揮了)

原文:A function template is considered more specialized than another if every possible list of arguments that matches it also matches the other, but not the other way around.

勘誤:如果每一個能匹配這個函數模板的參數列表,也能夠匹配另外一個函數模板的參數 列表,但反過來卻不成立,那麼這個函數模板被認爲比另一個函數板更爲特化(more specialized)

P156 ……還因爲所有基本的模板參數都由令人感到滿意的一個參數列表附加到類名中。

原文:...and because all the primary template's parameters are satisfied by the argument list appended to the class name.

勘誤:……還因爲跟在類名後面的參數列表符合主模板的所有參數的要求。

P156 這意味着在模板特化的某些方法中至少還有一個方法,其模板參數是“開放的”。

原文:meaning that at least one of the template parameters is left “open” in some way in the specialization.

勘誤:意思是在特化時,至少有個一個模板參數可以以某種方式保留“開放”狀態。

 P158 ——在這兩個模板中無法進行進一步取捨。同樣的邏輯錯誤存在於 第9行到第12行。 (到底是什麼邏輯錯誤,上下文根本沒有講清,請問刁副教授,到底是什麼邏輯錯誤?)

原文:—one is not more specialized than the other. Similar logic applies to lines 9 through 12.

勘誤:——沒有一個比另外一個更爲特化。同樣的邏輯也適用於第9~12行。( 我來告訴你吧刁副教授,所謂的邏輯錯誤就是“沒有一個比另外一個更爲特化”)

P160 無論何時,一旦對某個類模板進行了實例化,伴隨着所有在程序中調用的該模板的成 員函數,類定義中用於對其進行詳盡描述的特化代碼也就會生成。

原文:Whenever a class template is instantiated, the code from the class definition for the particular specialization is generated, along with all the member functions that are called in the program.

勘誤:無論一個類模板何時被實例化,因特定的特化而產生的類定義的代碼就會被生成, 該代碼同時包含所有在程序中被調用的成員函數。

P167 ("::"左邊的限定詞必須爲關聯的限定名稱提及一個模板參數)

原文:(The qualifier on the left of the "::" must mention a template parameter for a qualified name to be considered dependent.)

勘誤:(要讓一個限定名被認爲是依賴性的(關聯性),"::"左邊的限定符必須 提及一個模板參數。)

P179 程序輸出了由參數12!實例化後的正確值!並沒有警告發出。那麼警告是什麼呢?警告就是:在程序開始運行前就已經完成了計算! (點評:這翻譯很腦殘)

原文:That this program prints the correct value of 12! is not alarming. What is alarming is that the computation is complete before the program even runs!

勘誤:這段程序輸出了12!的正確值並不是一件令人驚奇的事情。令人驚奇的是在程序運行前計算就已經完成了!

P184 (在STATIC_CHECK()中的sizeof調用裏面的特殊圓括號,是爲了防止編譯器認爲程序正在試圖將sizeof作爲函數調用,這是不合法的)

原文:(The extra parentheses inside the sizeof invocation in STATIC_CHECK( ) are to prevent the compiler from thinking that we're trying to invoke sizeof on a function, which is illegal.)

勘誤:(在STATIC_CHECK()中,調用sizeof時內部額外的括號是爲了防止編譯器認爲我們正在試圖爲一個函數調用sizeof,而這樣做是非法的)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章