iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
0
自我挑戰組

30 Days 如何把 C 語言偽裝成高階語言 OWO /系列 第 6

Days 6: 重溫指標:不使用回傳地址方式的函數(續.)

▌繼續昨天的問題,整合一下。


源代碼:

void function(int **get_a){
    static int a;
    *get_a = &a;
}
int main(){
    int *get_a;
    function(&get_a);
    *get_a = 1;
    return 0;
}

圖:
https://ithelp.ithome.com.tw/upload/images/20181020/20111788wPhbcJB29W.png
https://ithelp.ithome.com.tw/upload/images/20181020/20111788hBrhm4Vv39.png
https://ithelp.ithome.com.tw/upload/images/20181020/20111788hvdxZnoY4w.png
https://ithelp.ithome.com.tw/upload/images/20181020/20111788G5o7suv41F.png


▌欸。

愚蠢細心的人類可能已經發現,
其實 函數的 get_a 的 第二層虛擬取值層級 並沒有被使用
(即函數中沒有用到 **get_a )

(話說 虛擬取值層級 這名字是我作出來的,事實上並沒有這玩意。
(所以我也不敢把它粗體,以免你們以為這是專業名詞。

▌那我可不可以把:

void function(int **get_a){

改成

void function(int *get_a){

呢?

當然是可以的,也不影響程序的行為。
不過編譯器會給你兩個警告
https://ithelp.ithome.com.tw/upload/images/20181021/20111788JQVRxcBrcL.png ( Visual Studio 2017 中 )
因為取值層級的不同,可能會導致非法存取

取值層級等於或小於的情況可能沒事,(像上面這個例子)
但是如果在...:

int *a;
function(&a)
void function(int ******get_a){
    ******get_a = 1;  //非法存取! 不是允許存取的空間 或者是不存在
}

大於的情況會出事。


如果你在只允許 一層虛擬取值層級 的變數中使用 第二層虛擬取值層級 的話,

void function(int *get_a){
    **get_a = 1;  //錯誤
}

它會給你一個錯誤......
https://ithelp.ithome.com.tw/upload/images/20181021/20111788pjewaM9g2J.png


錯誤不能編譯成功的,
警告可以編譯成功的。


以我所知,虛擬取值層級是不會佔空間也不會影響效率的。
畢竟是虛擬的。

▌但是哪種寫法比較好呢?

第一種寫法,可以讓編譯器不給出警告
第二種寫法,可以給函數最小的存取權限,反正存取超出權限時,編譯器會給出錯誤
我也不知道ww。


▌下一篇預告:

function(int **get_a) 可以換成 function(int *get_a)
反正只是純粹進行地址的儲存,又可不可以再換成
function(void *get_a) 呢? (int* -> void*)

竟然是不行的。 ∑(っ °Д °;)っ
下一篇再說。


三十天還真難呢,繼續拖一會指標好了。


上一篇
Days 5: 重溫指標:不使用回傳地址方式的函數
下一篇
Days 7: 重溫指標:數據、數據類型的本質
系列文
30 Days 如何把 C 語言偽裝成高階語言 OWO /31

尚未有邦友留言

立即登入留言