變數是程式設計的核心概念,用於儲存和操作資料。理解變數的宣告、初始化和資料型別對於撰寫有效且可維護的程式至關重要。同樣地,常數的運用能提升程式碼的可讀性和可維護性,尤其在處理固定值,例如稅率或折扣率時,命名常數更能清晰地表達程式邏輯。然而,不恰當的變數使用或忽略初始化可能導致程式錯誤,例如使用垃圾值。算術運算的優先順序和結合性決定了運算的執行順序,正確理解這些規則才能避免邏輯錯誤。使用括號不僅能確保運算順序符合預期,也能提升程式碼的可讀性。

變數宣告與初始化

在程式設計中,變數是一個儲存資料的容器。宣告變數時,需要指定其資料型別和名稱。例如,someNumber = 3 + 7 這行程式碼宣告了一個變數 someNumber,並將其初始化為 3 + 7 的結果。

指派運運算元

指派運運算元(assignment operator)用於將一個值指派給變數。例如,someOtherNumber = someNumbersomeNumber 的值指派給 someOtherNumber。在每個案例中,指派運運算元的右側的表示式都會被評估並儲存在左側變數的記憶體位置。

lvalue

lvalue 是指指派運運算元的左側的結果,代表著記憶體位置的識別符。lvalue 總是代表著記憶體地址。

無效的指派

以下程式碼是無效的:

2 + 4 = someNumber
someOtherNumber * 10 = someNumber
someNumber + someOtherNumber = 10

因為指派運運算元的左側不代表著記憶體地址。

初始化變數

除了使用資料型別和識別符號外,還可以在宣告變數時指定初始值。這被稱為初始化變數。當你建立一個變數而不指定初始值時,你的意圖是稍後為其指派一個值。當你指派初始值時,你的意圖是使用該值在任何新值被指派之前。

例如,以下程式碼是有效的宣告:

num myPayRate
num yourPayRate = 24.55
string myName
string yourName = "Juanita"

在許多程式設計語言中,如果你宣告了一個變數而不初始化它,該變數將包含一個未知值,直到它被指派一個值。這個未知值通常被稱為「垃圾」。

垃圾值

如果你宣告了一個變數而不初始化它,該變數將包含一個未知值,直到它被指派一個值。這個未知值通常被稱為「垃圾」。在許多語言中,使用垃圾值的變數在算術或輸出陳述式中是非法的,即使某些語言允許你顯示垃圾值,也不應該這樣做,因為它沒有任何意義。

看圖說話:

  flowchart TD
    A[宣告變數] --> B[初始化變數]
    B --> C[指派值]
    C --> D[使用變數]
    D --> E[顯示結果]

在這個流程圖中,宣告變數、初始化變數、指派值、使用變數和顯示結果都是變數生命週期中的重要步驟。

變數宣告的重要性

在程式設計中,變數必須在使用前先宣告。有些語言要求所有變數必須在程式開始處宣告,而其他語言則允許變數在每個模組或任意位置宣告,只要在使用前宣告即可。為了保持程式的清晰度和可讀性,本文將遵循將所有變數一起宣告的慣例。

命名常數的宣告

除了變數外,大多數程式語言還允許建立命名常數。命名常數與變數相似,但只能被指定一次。當您想要為一個不會在程式執行期間改變的值賦予一個有意義的名稱時,使用命名常數。使用命名常數可以使您的程式更容易被理解。magic number(魔術數)是指那些沒有明確意義的未命名常數,例如0.06。

例如,如果一個程式使用6%的銷售稅率,您可能想要宣告一個命名常數如下:

SALES_TAX_RATE = 0.06

宣告SALES_TAX_RATE後,以下兩個陳述式具有相同的意義:

taxAmount = price * 0.06
taxAmount = price * SALES_TAX_RATE

不同程式語言中命名常數的宣告方式可能有所不同。本文將遵循使用全部大寫字母作為常數識別符,並使用底線分隔單詞以提高可讀性的慣例。使用這些慣例可以使命名常數更容易被識別。在許多語言中,常數必須在宣告時指定,但在一些語言中,常數可以稍後指定。不過,在兩種情況下,常數的值都不能在第一次指定後改變。本文將遵循在宣告時初始化所有常數的慣例。

當您宣告命名常數時,程式維護變得更容易。例如,如果銷售稅率從0.06改為0.07,您只需要修改命名常數SALES_TAX_RATE的值,然後重新編譯程式,所有對SALES_TAX_RATE的參照都會自動更新。如果您使用未命名的字面值0.06,則需要搜尋所有出現此值的地方並替換為新值。此外,如果字面值0.06在程式中的其他計算中使用(例如,作為折扣率或價格),您需要小心選擇哪些例項需要修改,並且很可能會犯錯誤。

有時候,在程式中使用未命名的字面常數是合適的,特別是當其意義對大多數讀者清晰時。例如,在計算一個值的一半時,您可能會選擇使用未命名的字面值2,而不是建立一個命名常數HALF並指定2給它。由於增加變數或指令而導致的額外時間和記憶體成本稱為overhead。

基本算術運算

大多數程式語言使用以下標準算術運運算元:

  • +(加號)- 加法
  • -(減號)- 減法
  • *(星號)- 乘法
  • /(斜線)- 除法

許多語言還支援其他運運算元,例如計算除法後的餘數、將一個數字提升到某個次方、操作儲存於值中的個別位元等。

與指定運運算元類別似,每個標準算術運運算元都是二元運運算元,即需要在運運算元兩側都有表示式。例如,以下陳述式將兩個測試成績相加並將結果指定給一個名為totalScore的變數:

totalScore = test1 + test2

以下陳述式將10加到totalScore上並將結果儲存在totalScore中:

totalScore = totalScore + 10

換句話說,這個例子增加了totalScore的值。

在程式設計語言中,您可以結合算術陳述式。當您這樣做時,每個運運算元都遵循一套優先順序規則(也稱為運算順序),它們決定了相同陳述式中運算的順序。基本算術陳述式的優先順序規則如下:

  1. 括號內的表示式首先被評估。如果有多個括號集,則最內層括號內的表示式首先被評估。
  2. 乘法和除法從左到右評估。
  3. 加法和減法從左到右評估。

看圖說話:

  graph LR
    A[開始] --> B[宣告變數]
    B --> C[指定]
    C --> D[進行算術運算]
    D --> E[評估優先順序]
    E --> F[執行運算]
    F --> G[輸出結果]

這個流程圖描述了變數宣告、指定、算術運算和結果輸出的基本流程。瞭解這個流程可以幫助您更好地掌握程式設計的基礎概念。

變數與常數的宣告與使用

在程式設計中,變數的資料型別決定了變數可以持有的值型別以及可以對其進行的操作。例如,如果 name 是一個字串變數,那麼指定陳述式 name = "Ed" 就是有效的。然而,關於指定運運算元的運作,有一項重要的規則需要注意:運運算元左邊的運算元必須是代表記憶體地址的名稱,即結果將被儲存的位置。這與第三個陳述「運運算元右邊的運算元必須是代表記憶體地址的名稱」相反。

執行算術運算

在算術運算中,指定運運算元具有很低的優先順序。因此,在像 d = e * f + g 這樣的陳述式中,指定運運算元右邊的運算(在此例中為乘法和加法)始終在最終指定給左邊的變數之前執行。當學習特定的程式語言時,您將學習到該語言中使用的所有運運算元。各種程式語言的參考檔案通常包含表格,以指定語言中每個運運算元的相對優先順序。

優先順序規則

例如,考慮以下兩個算術陳述式:

firstAnswer = 2 + 3 * 4
secondAnswer = (2 + 3) * 4

在這些陳述式執行後,firstAnswer 的值為 14。根據優先順序規則,乘法在加法之前執行,因此:

  • 3 乘以 4 得到 12。
  • 然後 2 和 12 相加,結果 14 被賦予 firstAnswer

然而,secondAnswer 的值為 20,因為括號強制包含的加法運算首先執行,如下所示:

  • 2 和 3 相加,得到 5。
  • 然後 5 乘以 4,結果 20 被賦予 secondAnswer

忘記算術優先順序規則或忘記增加括號可能會導致難以在程式中找到的邏輯錯誤。例如,以下陳述式可能看起來像是平均兩個測試成績:

average = score1 + score2 / 2

然而,它並不會這樣做。由於除法的優先順序高於加法,因此前面的陳述式取 score2 的一半,加到 score1,然後將結果儲存到 average 中。正確的陳述式是:

average = (score1 + score2) / 2

您可以自由增加括號,即使您不需要它們來強制執行不同的運算順序;有時您使用它們只是為了使您的意圖更加清晰。例如,以下陳述式運作相同:

totalPriceWithTax = price + price * TAX_RATE
totalPriceWithTax = price + (price * TAX_RATE)

在兩種情況下,price 都乘以 TAX_RATE,然後加到 price,最後結果儲存到 totalPriceWithTax 中。由於乘法在指定運運算元右側的加法之前執行,因此兩個陳述式相同。然而,如果您覺得帶有括號的陳述式使您的意圖更清楚,那麼您應該使用它們。

所有算術運運算元都具有左到右的關聯性,這意味著具有相同優先順序的運算從左到右執行。考慮以下陳述式:

answer = a + b + c * d / e - f

乘法和除法的優先順序高於加法或減法,因此乘法和除法從左到右執行,如下所示:c 乘以 d,然後結果除以 e,得到新的結果。因此,陳述式變成:

answer = a + b + (臨時結果) - f

然後,加法和減法從左到右執行,如下所示:ab 相加,臨時結果相加,然後 f 相減。最終結果然後被賦予 answer

另一種說明方式是,以下兩個陳述式是等效的:

answer = (a + b) + ((c * d) / e) - f
answer = ((a + b) + ((c * d) / e)) - f

這些陳述式透過遵循優先順序規則和左到右的關聯性來評估。

從程式設計師的視角來看,變數宣告與初始化是程式碼運作的基本。分析變數生命週期,從宣告、初始化、指定到使用,每一步都環環相扣,任何疏忽都可能埋下難以察覺的錯誤。lvalue 的概念凸顯了變數作為記憶體地址的本質,釐清了指派運算的運作機制。挑戰在於避免垃圾值的產生以及理解運運算元優先順序和結合性,這些是程式正確執行的關鍵。展望未來,隨著程式語言的發展,變數管理的機制可能會更加精細化,例如自動型別推斷和更嚴格的變數作用域控制。對於追求程式碼品質的開發者而言,掌握變數宣告和初始化的最佳實踐至關重要,這將有助於減少錯誤、提高程式碼可讀性和可維護性。 玄貓認為,深入理解變數的本質並遵循良好的程式設計習慣,才能寫出高效且穩定的程式碼。