C++自修入門實境秀、C++ Primer 5版研讀秀 31/ ~頁196 Functions Are Exited during the Se...





第31集

對上次寫的Word VBA 選取範圍插入超連結添上錯誤處理

頁189

5.4.4. The do while Statement

12:45



1.最末有個分號

2.條件式不能空

condition cannot be empty.

3.在條件式裡頭使用的變數一定要在while區塊外定義

Variables used in condition must be defined outside the body of the do while statement.

39:10

43:00因為在block(區塊)中就會用到的變數,當然就不能在區塊執行一行後才會執行的條件式中定義了。否則就會變成使用了未經定義的變數。(the identifier is not defined)

Visual Studio 2019 with GitHub

51:00 在Visual Studio 2019用GitHub,只要不用branch,其實就可以把GitHub直接當作雲端硬碟作為同步用了 1:14:00 1:16:00本地修改後要「push」到雲端GitHub才能由另一台機器pull或sync同步。push一個版本(或「別本」詳下)其實就是upload to the GitHub。1:25:00一定要經過commit push將change的commit push 才有作用,光push不行。至於push 與commit push 的異同,有俟來日。1:43:00

commit 是接受修改,確認修改。但修改的版本仍在修改的本機上,尚未「推」push去出(可以理解為「推播」出去,像twitter推特這樣。)。所以commit和push是兩個不同的動作,有先後順序,必須先commit(確認修改)後才能pusu(推)出去。這裡的commit是確認的意思,⑧找對主詞 確認什麼?確認修改無誤,準備發行(push)出去的意思。可見,沒有commit的push是推不出去的,有了commit後未必push,此時push出去才有作用。

那是在不同人使用,或有不同版本須並存,或另起一支(或類似子目錄時才需要用到branch、push、pull request、merge、pull、sync)

1:4:00 branch的意思是整套程式的分支副本,並不是某個檔案的而已;所以branch應翻成「別本」比較好意即另外一個版本的程式碼。1:27:001:29:44在版本學意義上,別本就是同一書的不同版本,同版本控制的概念。一個程式repository也好像一本書book

快捷鍵:

在一關鍵字(identifier)上(不必選取)按下ctrl+, 會直接如ctrl+t,再貼上所要找的關鍵字

2:2:00 原來標頭檔是這麼用的(可作為調用函式的資源庫repository)

當Visual Studio自動幫我們創建一個與目前cpp檔相同名稱的標頭檔時,也同時會加入 #include<該名稱.h>

Visual Studio左邊行號右傍和右邊捲軸列的黃標,就是指明有被修改被動過的地方

3:35:00

prog1.vcxproj、prog1.vcxproj.filters 這兩個檔案的作用

prog1.vcxproj.filters 應是Visual Studio的設定檔,其介面的不能英文化的中文還保留著。呵呵





頁190

練習5.18

47:40 55:10

following loops. Correct any problems you detect.

翻譯

科學語言 的翻譯:

下列的迴圈。更正你所偵測到的任何問題。

文學語言的翻譯 → 發現 訂正你發現的問題 any不必翻出來

1:51:00

//(a)

do{

int v1, v2;

cout << "Please enter two numbers to sum:";

if (cin >> v1 >> v2)

cout << "Sum is: " << v1 + v2 << endl;

} while (cin);

2:25:00

#include "prog1.h"//此行為VisualStudio 在創建標頭檔後自動帶出的。空不空半形空格都沒關係,但不能用角括弧,只能用雙引號

//(b)

int i = 0,ival = get_response(i);

do {

// . . .

++i;//可作為測試自己cpu遞增計算效率的小程式

} while ( ival=get_response(i) );

cout << "遞增3億(300000000)需時……秒"<<endl;

以下是Visual Studio自動創建的標頭檔內容int以下程式碼是我寫的:

#pragma once

void test();

int get_response(int i) {



return i % 300000000;

}

2:35:00

//(c)

int ival = get_response(1);

do {

} while (ival);

後兩題主要是考do while變數定義的地方

練習5.19

2:37:50

2:59:30

{

string rsp;

do

{

cout << "請輸入兩串文字以比較其長短" << endl;

string s1, s2;

cin >> s1 >> s2;

switch (s1.size()>s2.size())

{

case 1:

cout << s1 << " 長於 " << s2 << endl;

break;

case 0:

if (s1.size() != s2.size())

cout << s1 << " 短於 " << s2 << endl;

else cout << s1 << " and " << s2 <<" 等長 "<< endl;

break;

default:

break;

}//參見中文版頁86,字串比較運算,但string的大小於是比字母,不是比字串長度



cout << "要繼續請輸入y" << endl;

cin >> rsp;

} while (!rsp.empty() && rsp=="y");

}

5.5. Jump Statements 5.5跳躍述句

應該是相當於於VBA裡的GoTo

Jump statements interrupt the flow of execution.

可見 flow of control也應翻成控制的流程,是說控制(程式進行 ⑧找對主詞 ⑤添字還原 )的流程

英文多是後位修飾

C++ offers four jumps: break,continue, and goto, which we cover in this chapter, and the return statement,which we’ll describe in § 6.3 (p. 222).

cover 和 describe 抽換字面

可見cover有涵蓋的意思,因為這裡不光談goto也



3:10:50

5.5.1. The break Statement

頁191

3:20:00

section 翻成「區段」,不錯

練習5.20

3:27:18

3:50:20

Personalize Visual Studio with custom keyboard shortcuts

3:55:00 這樣子就知道怎麼把GitHub當作雲端硬碟來用了 4:4:10把GitHub當雲端硬碟來用:

本機電腦(來源電腦)commit and push

雲端電腦(目的電腦) pull

4:6:25

string r;

string s1, s2;

bool rt=0;

while (cin >> s1) {

if (s1 == s2) {

rt=1; break;

}

s2 = s1;

}

if (rt==0)

cout << "there is no word was repeated." << endl;

else cout << "Print the word if it occurs twice in succession:" << s2 << endl;

5.5.2. The continue Statement

4:8:55

continue要在switch中出現,只能在這個switch是在一個迭代(iterate)的迴圈中才可以

continue 並不終止迴圈,它只是中斷迴圈目前的迭代,而繼續下一次的迭代。所以叫「jump statement」.

這裡是跳躍到它迴圈的判斷式,交由該判斷式(條件式)來決定迴圈是否要繼續

頁192

練習5.21

string s1, s2;

bool rt=0;

while (cin >> s1) {

if (s1 == s2) {

if (isupper(s1[0]))

{

rt = 1; break;

}

else

continue;

}

s2 = s1;

}

if (rt==0)

cout << "there is no word was repeated." << endl;

else cout << "Print the word if it occurs twice in succession:" << s2 << endl;

4:38:10

5.5.3. The goto Statement

原來C++的goto只能在一個函式裡跳躍(其實VBA好像也一樣——在一個Sub或Function)

A goto statement provides an unconditional jump from the goto to a another statement in the same function.



養成好習慣:

Programs should not use goto s. goto s make programs hard to understand and hard to modify.

A labeled statement is 和VBA的幾乎一樣



The goto and the labeled statement to which it transfers control must be in the same function.

goto與它向之轉移控制權的帶標籤述句必須位在同一個函式(function)中。

goto和它指向的陳述句必須在同一個函式中。

也就是goto和goto要轉移程式執行流程的目的地必須同在一個函式中,不可逾越。





As with a switch statement, a goto cannot transfer control from a point where an initialized variable is out of scope to a point where that variable is in scope:

和 switch一樣(其實是程式的根本憲法法則)沒有經過執行的宣告與定義,其變數是不能使用的,不管是用switch、goto anything 任何手段都不行!要用一個變數就一定要經過定義與初始化(至少也要有內建初始化或預設初始化)

scope這裡可以理解為變數的「有效區域」,或「可視區域」visibility,或者「生命週期」。

頁193

5:5:56

練習5.22

5:19:30

int get_size(int i) {//這個函式在.h(標頭檔)中,可見之所以叫header標頭,就是因為它是程式在執行時可能需要參照到的資源,所以須先載入,以備參考!就像這個函式不能寫下下面那個後面一樣,因為下面要調用它,未經定義與初始化的,不管是變數或函式等等,都是不能被調用的。程式先後順序是絕對的。

return i % 130;

}

//要用loop,連標籤也不能用了

int sz,i=-30;

do{

++i;

sz= get_size(i);



} while (sz <= 0);



//begin:

// int sz = get_size();

// if (sz <= 0) {

// goto begin;

// }

5.6. try Blocks and Exception Handling

5.6 try區塊與例外處理



5:36:00

例外處理是包括偵測和處理兩大部分的:

Exception handling supports this cooperation between the detecting and handling parts of a program. In C++, exception handling involves

例外處理支援程式偵測問題的部分(detecting part)和處理問題的部分(handling part)之 間的這種合作。在C++中,例外處理涉及了



throw和catch 兩部分(兩輪)

throw expressions ,

We say that a throw raises an exception.

一個throw發現了一個例外情形,是屬於偵測部分的權限;處理的權限則交給try block:

try blocks , which the handling part uses to deal with an exception.

A try block starts with the keyword try and ends with one or more catch clauses.

由try……catch……組成 try block,來處理相對應的例外情形

Because they “handle” the exception, catch clauses are also known as exception handlers .

原來C++裡的錯誤處理程序(錯誤處理式)指的即是catch clauses (catch子句)

例外處理器(exception handlers )。



5.6.1. A throw Expression

5.6.1 throw 運算式

運算式述句(expression statement)。

頁194

The type runtime_error is one of the standard library exception types and is defined in the stdexcept header. We’ll have more to say about these types in § 5.6.3 (p. 197 ).



runtime_error型別需要用string或C式字元字串來初始化

We must initialize a runtime_error by giving it a string or a Cstyle character string (§ 3.5.4, p. 122).

6:11:20

5.6.2. The try Block

5.6.2 try 區塊

典型的try block有如下形式:

try {

program-statements

} catch ( exception-declaration ) {

handler-statements

} catch ( exception-declaration ) {

handler-statements

} // . . .

頁195

Following the try block is a list of one or more catch clauses.

所以 try block其實只有try和它後面帶著的一個block——即{……},並不包括catch子句;各子句各有一個block。

6:16:50

catch子句

A catch consists of three parts:

1)the keyword catch,

2)the declaration of a (possibly unnamed) object within parentheses (referred to as an exception declaration), and

3)a block.{}

6:19:20

所以catch其實類似switch裡的case,程式執行它只會選一個吻合的case或catch來執行其後的block(即one or a set of statements)。只是case如果在它的block末沒有加上break述句,那麼後面的case或default也會被執行,而catch則不會。

6:24:00

總之在{}中宣告或定義的變數,生命週期是無法超過這個區塊的

6:30:05

The program-statements inside the try constitute the normal logic of the program.

try內的program-statements構成了程式的正常邏輯。

以上真不知所云!參見頁195的實例才好懂:

6:43:25 7:10:10

while (cin >> item1 >> item2) {

try { // execute code that will add the two Sales_item s

// if the addition fails, the code throws a runtime_error exception

} catch (runtime_error err) {

// remind the user that the ISBN s must match and prompt for another pair

cout << err.what()

<< "\nTry Again? Enter y or n" << endl;

char c;

cin >> c;

if (!cin || c == 'n')

break; // break out of the while loop

}

}

比較while、for、if和catch才發現很類似的結構:都有(){}圓括號+大括號。且大括號{}中即是它要執行的東西(述句s),而圓括號()即是它們的條件式。只要符合條件,{}區塊裡的述句就會被執行。所以這些應該都屬於條件述句。7:42:00

可見所謂「the normal logic of the program」是說這部分如果沒有try來干涉的話,就像一般正常程式會會寫的那樣(即一般可執行的程式碼)。就是把正常或一般的程式碼用try括起來成個區塊而已。

這裡normal翻成「一般」,在中文語境下才比較好懂。所以它下文才會有「ordinary」「code」:

The ordinary logic of the program that manages the interaction with the user appears inside the try block.

管理與使用者互動的程式一般邏輯出現在那個try區塊內。(真按:這裡翻「一般」前面又翻「正常」)

The statements in the block following the catch are executed if code inside the try block throws a runtime_error .

If the code described in the previous section threw an exception, then this catch would print(頁196) 7:53:30

如果前一節所描述的程式碼擲出一個例外,那麼這個catch就會印出(真按:這裡「section」不是書的前一節,是catch子句前面的區段!也就是try block 在這裡叫做「the previous section」)

logic在這裡就是指 code,翻成程式(碼)才好懂。叫做「logic」因為程式是有一定的順序邏輯規則的嘛,所以以它此特性來「借代」codes的意思。

try block裡頭的述句,就是一般程式會執行的述句就是了。只是用try括起來{}:

appears inside the try block

This part of the program is wrapped inside a try because it might throw an exception of type runtime_error.

如果發生問題,就可以讓它仲介、轉介——就是控制流程轉移jump到catch block去處理。如果try中的程式執行成功,沒有異常、例外,當然後面的catch clauses就都不會執行了。

如前所比喻,catch 就像 case,而try 就像 switch

和頁194的throw expression statement 實例相較:

// first check that the data are for the same item

if (item1.isbn() != item2.isbn())

throw runtime_error("Data must refer to same ISBN");

// if we're still here, the ISBNs are the same

cout << item1 + item2 << endl;

這裡「runtime_error」後是加()來初始化的。和catch這裡用的「catch (runtime_error err)」是不一樣的!catch只作宣告,故曰「exception declaration」用這個宣告的例外物件(即不具名)或變數(即具名物件)來儲存程式執行時丟出產生的錯誤訊息。



6:28:00 6:31:22

Writing a Handler

撰寫一個處理器

中文版翻成「處理器」會和processor混淆,不如如其他地方翻成「處理式」或「處理程式」「處理程序」才好。

來處理所擲出的例外:

to handle the exception that was thrown:

去 處理 可能發生 的 例外情形。

②單字想複詞 發→舉發→發生 舉→舉出、舉起 raise

thrown 在這裡翻成「丟出」就不合中文語境!很唐突,不知所云。





6:40:20

可見throw 運算式述句 與try blockand catch block是二種處理例外情形的方式,並不合用(不同時用)。是二選一的。



falls through

掉落至

前面不是這麼翻的



程式庫的例外類別都有定義一個叫what的成員函式:

Each of the library exception classes defines a member function named what. These functions take no arguments and return a C-style character string (i.e., a const char* ).

頁196

8:0:35

Functions Are Exited during the Search for a Handler

搜尋處理器時會退出函式

留言

熱門文章