正文 第四章 C++對C的增強(二)(1 / 3)

4.9volatile修飾符

volatile的意思是“易失的、易變的”。它告訴編譯器,它所修飾的變量雖然在程序中沒有被改變,但該變量的值可能會由於其它外部的原因而發生變化。例如下麵的程序:

其中,變量dock記錄了係統時鍾的當前時間,它的值由一個時鍾中斷程序修改,每秒clock的值加1。而diff用來記錄兩次賦值語句的時間間隔。

在上麵的程序段中,我們看到變量dock並沒有被賦值。所以,編譯器認為在這段代碼的執行過程中,dock變量的值是不會被改變的。編譯器將會采取這樣的優化措施:從內存中讀取clock的值,並把這個值保存在一個內部寄存器中。以後要獲取clock的值,就從這個內部寄存器中去讀取。這樣,clock的值應該是不變的。

但是,在time1=clock;和time2=clock;的被值語句之間如果發生了一次或幾次時鍾中斷,而時鍾中斷程序會改變clock的值,改變後的值就與在內部寄存器中讀取的clock值不一樣。而此時diff的結果應為0。

那麼,編譯器就會知道dock變量會被程序以外的其它因素所改變,而不會采取上麵的優化措施。這樣就能達到我們所預期的目的。

4.10void

在Visual C++中,void的用法與在C語言中的用法基本相同。本節我們將介紹void的兩種用法:在函數中使用void以及void指針。

一、在函數中使用void

void的一層意思是無值的類型。在函數中可以在兩種地方使用它。

1.在函數名前加void。如:void fun();

說明此函數是沒有返回值的函數。在這種函數的函數體內如果包含有return語句,那麼這個return語句後麵就不能帶有任何表達式,也就是說不能給此種函數返回值。同理,對於非void類型的函數,return後麵必須跟有表達式,不能簡單地直接返回,否則編譯器會給出警告甚致出錯信息。

2.在函數的參數表位置上使用void。如:intfun(void);

說明此函數是沒有任何參數的函數。當然在Visual C++中對沒有參數的函數,其參數表也可以什麼都不寫。

二、void類型的指針

當我們無法確定一個指針變量為何種數據類型時,可以定義一個類型為void的指針變量,如:void*P;這種類型的指針叫做void類型的指針。對此種類型指針變量的使用應注意以下兩點:

1.任何類型的指針賦給void類型的指針變量都是被允許的。

2.在C++中,不允許將一個void類型的指針在沒有明確的類型轉換下賦給其它類型的指針變量。即如果要把void類型的指針賦給其它類型的指針變量,必須使用強製的類型轉換。

4.11域分辨操作符

我們都知道,對變量的使用是有一定範圍的,即隻能在其作用域中使用變量。請看下麵的例子:

在上麵的例子中,變量說明語句:doublea;在main()函數之外,因而它是一個全局變量;而說明語句:inta;在main()函數之內,因而,它是一個局部變量。在C語言中,對變量的使用有一條規則:局部變量的優先級要髙於全局變量6如果一個局部變量和一個全局變量同名,那麼在局部變量的作用域內,所有此名的變最都是指該局部變量。如例中,在main()函數體中,所有變量&都將是整型變量的a。那麼,是否我們在局部變量的作用域內就無法訪問同名的全局變量了呢?而這個要求恰恰是有時需要的。幸運的是在Visual C++中,我們可以通過域分辨操作符告訴編譯器去使用全局變量,而不是同名的局部變量。你所要做的隻是在變量名前加上作用域分辨符(::)。

例4.9通過作用域分辨符::訪問全局變量

應該注意,作用域分辨符::隻能用來訪問全局變量。如果在一局部變量的作用域外還有一個同名的變量,但它不是全局變量,你就不能用作用域分辨符去訪問它。例如:

那麼語句“::a=2.5;”將出錯。因為double型變量a並不是全局變量,它隻不過是int型變量a作用域外的一個局部變量。除非在程序中還有一個叫a的全局變量。

4.12引用類型

引用是C++中一種新的變量類型,主要用來向函數傳遞參數,以及從函數中返回值。

一、引用的基本概念,

引用的英文是“reference”。在計算機中,它還有“地址”的意思。你可以把某個變量的地址看作是該變量的別名。當初始化一個引用時就將它和一個變量聯係起來了,這個引用將一直與變量相聯係,以後就不能將它改變為其它變量的別名。

引用由一元作符來標識。

這兩條語句說明了一個名為mun的整數。又說明rcf是對num的引用。以後作用於這兩個名字上的所有操作都具有相同的結果。量,隻不過ref是num的別名。而這是由於語句:int&ref=num;的結果。該語句在執行時並沒有在內存中建立一個新的變量ref,而隻是告知編譯器num又有了一個名字ref。