您現在的位置是:首頁 > 垂釣

VBVBA中的ByValByRef傳參關鍵字,與指標相關,都知道嗎?

  • 由 BtOfficer 發表于 垂釣
  • 2022-04-18
簡介尤其是ByVal修飾實參時,與形參的Any型別相結合,可以讓VBVBA程式碼變得異常靈活,也是使用VBVBA指標最通常的方式哦

byref在vb中什麼意思

VBVBA中的ByValByRef傳參關鍵字,與指標相關,都知道嗎?

小小知識點,有大大的用處

1、對於ByVal/ByRef關鍵字,想必很多人都能說一番用途。

沒錯,這倆關鍵字就是用來傳參的。

筆者在《

為什麼VB/VBA中傳遞數值時,ByVal比ByRef更高效?

》一文中,也是詳細而深入地講解了二者的效能區分和適用場景,有興趣的讀者可以關注閱讀,說不定就有不小的收穫哦。

2、對於傳參,一般都是在宣告引數時使用。

在VB/VBA中,宣告引數有兩個場景,一個是Declare宣告API函式中的引數,另一個則是自定義函式的引數。

總之,我們均可以將其歸納為宣告形參時,才會使用這倆關鍵字,

其中ByRef更是預設關鍵字。

3、除了宣告形參時可使用ByVal和ByRef關鍵字外,還有沒有其他場景可以使用這倆關鍵字呢?既然這麼說了,那肯定是有的。

其實在實參被傳遞前,可以使用這倆關鍵字修飾實參。

4、對於VB/VBA中的指標,

想必大家對CopyMemory函式情有獨鍾。雖然筆者認為這是一個笨重的函式,並不適合承擔起VB/VBA的指標重任。

但就本文要介紹的內容而言,是可以作為一個例子來說的。

5、還記得《

VB/VBA中Variant不僅是容器,充當傳參的Any,更可以當函式用哦

》中的Any吧?

Any讓API的使用更具靈活性,比如字串指標,既可以扔字串變數,也可以丟字串資料指標,這樣一個宣告就可以使用多種方式的傳參。

6、為了提高CopyMemory函式的靈活性,對其前兩個引數,一般都宣告為Any型別。這樣既能直接傳變數,也能直接傳資料指標,大大方便了程式碼的書寫。但是,這裡面對坑肯定不少,比如:

CopyMemory LngDes,VarPtr(LngSrc),4

,原本是想將LngSrc的值複製到LngDes變數,結果卻錯得離譜(為LngSrc變數地址)。

7、為何會這樣呢?其實這

跟Any型別的傳址特徵相關

。在《VB/VBA的ByVal和ByRef》中講了,

任何實參傳遞給形參時,都是一個確定的值

。所以,VarPtr(LngSrc)在傳遞前是會檢索LngSrc變數的地址,然後再傳遞這個地址。

在前面的分享中,筆者說了

VarPtr函式名其實是一個臨時變數,其指向返回值

。LngSrc變數的地址就存放在VarPtr函式名,這個臨時變數地址裡。當傳遞給Any宣告的變數時,就會自動傳遞這個臨時變數的地址,所以LngDes的結果為VarPtr(LngSrc)的返回值,

相當於LngDes=VarPtr(LngSrc)

。傳遞的地址不是LngSrc變數的地址,結果自然就不對啦。

8、要如何解決呢?這就與

本文的主角ByVal/ByRef有關了。它們不僅可以修飾形參,更可以修飾實參。

絕大部分時候,都是直接將實參傳遞給形參,這裡面其實就是預設使用了ByRef,只不過該關鍵字是預設的,跟形參中的一樣。所以,大傢伙就很容易忽略ByVal修飾實參的作用。

當ByVal修飾實參時,跟修飾形參時一樣,同樣表示傳值。如果該關鍵字後是1個地址,就會將該地址傳遞給形參。

如果上例中,加上該關鍵字,就表示將VarPtr(LngSrc)的結果值傳遞給形參,這樣結果就正確了(不信的,可以去試一試)。

9、

如此一來,反而是ByVal可以傳遞地址。

看到這裡,估計很多專業人士又要認為VB/VBA很反智,很奇葩了。

的確容易讓人感覺迷糊,究竟什麼時候傳址,什麼時候傳值?這裡的ByVal的傳值與Any的傳址不是互相矛盾麼?

這個其實並不矛盾,這裡全是為了提高VB/VBA程式碼的靈活性才有的。如果從根源上看就很清楚了,

這裡的根源有兩個。一個是系統API引數原型都要求指標,簡單說是個整數值。另一個是VB/VBA的編譯器或直譯器裡,存在自動轉換機制,從而避免使用者直接使用指標。

這裡的迷糊,僅跟VB/VBA自身的機制有關,因為到系統API呼叫層面,肯定都是指標了。

這裡實參的ByVal,其實是和Any形參傳址要求是一致的,並不存在矛盾。

怎麼樣,有沒有驚喜呢?

ByVal/ByRef不僅可修飾形參,更可修飾實參。尤其是ByVal修飾實參時,與形參的Any型別相結合,可以讓VB/VBA程式碼變得異常靈活,也是使用VB/VBA指標最通常的方式哦。

ByVal的機制,還有更多更深入的妙用哦。

歡迎關注BtOfficer(收藏、點贊、關注+轉發)

,更多精彩仍在繼續哦(

專欄文章將更系統,更全面,但需要閣下支援哦

),有嚴肅的技術,也有輕鬆的嘮嗑,期待你的加入!

Top