[爆卦]為什麼要用指標是什麼?優點缺點精華區懶人包

為什麼這篇為什麼要用指標鄉民發文收入到精華區:因為在為什麼要用指標這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者Feis (坐吃山空)看板C_and_CPP標題Re: [問題] 自己練習運用基礎的指標小問題時...

為什麼要用指標 在 陳小洛?裏科變態 Instagram 的最佳解答

2021-09-24 13:47:41

G點在性愛中令許多人好奇​ 過去我也是上網看介紹​ 但無論是用公分來做指標​ 或是講陰道內比較粗糙的那區​ 我還是不太能意會​ 後來我自己摸索的過程​ 找到了另一種尋找方式​ 也許你也可以參考看看​ ​ G點(G-Spot)是什麼?​ 他是陰道周圍的敏感帶之一​ 由德國醫學家Gräfenberg發現...


※ 引述《M013020058 (帥翰)》之銘言:
: 非常感謝先進的分析
: 目前初學者小弟我為指標分類為下,並提出幾個疑惑的地方。
: 1, 很多書籍都透過變數位址來修改/定義變數資料,但今天不是直接修改/定義變數資料
: 就好?為什麼要繞一圈?

誠如之前所提到的,主要有兩個方向,一個是你不用指標做不到,另一個是這樣做可能
比較快。

後者牽涉到的問題比較多,而且也不是主要的用途,所以我講一下前者。

首先我們知道,在 C 裡面你要存取某個物件/變數的值的時候,
你有兩種方法,一個是你要寫出他的名字,另一個是你要知道他的位址:

方法一: 使用名字

int main() {
int a = 3;
a = 5; // 透過名字去修改變數內容
// 此時 a 的值是 5
return 0;
}

方法二: 使用位址

int main() {
int a = 3;
int *b = &a;
*b = 5; // 透過位址去修改變數內容
// 此時 a 的值是 5
return 0;
}

上述兩種方法都可以達到修改變數 a 內容的效果,而一般的時候我們會建議使用前者,
因為後者看起來就是繞了一圈不知道在幹嘛。

那後者甚麼時候有用呢 ?

最常見的就是在函式呼叫的時候:

void f(int b) {
b = 5;
}

int main() {
int a = 3;
f(a);
// 此時 a 是 3 還是 5 ?
return 0;
}

初學者如果在學習函式的時候沒有對引數傳遞和可視範圍 (scope) 有比較清楚的了解,
那這個例子可能就弄不清楚應該是 3 或是 5

在呼叫完 f(a) 之後,main 裡面的 a 應該還是 3,他不會受到 f 的影響。

這可以從很多面向來解釋,首先呼叫函式的時候,a 會被複製一份變成 f 裡面的 b,
所以 b = 5 修改的是一個複製品,無法修改到原始的變數 a。

那如果我們把 b = 5 改成 a = 5 呢 ?

void f(int a) {
a = 5;
}

結果還是一樣沒用,而 f 裡面的 a 只是一個剛好同名同姓的複製品。

f 函式的定義是在 main 裡面的 a 的可視範圍外,所以是無法用變數名字直接去存取
main 裡面的 a。

此時我們可以使用指標來逃過可視範圍的限制,透過 "位址" 來修改變數內容:

void f(int *b) {
*b = 5;
}

int main() {
int a = 3;
f(&a);
// 此時 a 是 5
return 0;
}

為什麼這裡要特別傳遞指標呢? 就是希望 f 裡面可以透過 "位址" 去存取 main 裡面
的 a 。因為位址是個 "值",是可以複製到 f 裡面的,沒有跟名字一樣有可視範圍限
制。


還有甚麼時候我們可能會需要位址而不能用名字去存取呢 ?

我舉個簡化的例子:

int main() {
int a = 3;
int b = 5;
int c = 9;
int d = 4;

// 可能因為某些原因,我們當初沒有宣告陣列而是使用四個獨立的變數名字
// 如果現在我想要用迴圈去批次處理這些變數怎麼辦 ?

int* t[] = {&a, &b, &c, &d}; // 我們可以使用陣列去存變數位址

for (int i = 0; i < 4; i++) { // 此時就可以使用迴圈去依序存取不同名字的變數
f(t[i]);
}
return 0;
}

: 2,同上,是否是為了讀寫檔案所建立指標功能?

不全然是,讀寫檔案只是指標的一種應用。

因為讀寫檔案的時候是使用函式傳遞、生命週期與可視範圍脫鉤、檔案大小不固定、存
取有效能考量等等,用指標去操作是比較可能的設計。

: 3,以矩陣為例,可用指標來取代矩陣。而兩種在記憶體上或其他地方哪裏不一樣?

你可能有甚麼誤會

指標跟陣列的愛恨情仇有兩個主要的問題:


一個是常見的存取問題,指標可以用來存取所指向的陣列元素。

實際上照 C 的陣列設計,所有陣列的存取都是透過指標。
其實沒有甚麼取不取代的問題。

只是當你要在函式間傳遞陣列的時候,因為 C 函式無法直接傳遞陣列型別的物件,
所以你只能透過傳遞指標去存取。


另一個問題是空間配置問題,

陣列的大小如果是編譯期已知,我們可以透過變數定義來配置:

int a[10];

但是如果在編譯期還不知道的話,我們就需要透過動態配置:

int size;
scanf("%d", &size);
int *a = (int *) malloc(size *sizeof(int));

(C++ 或 C99 後有其他作法)

(註: 有些時候因為編譯器的限制,在函式內能配置的陣列大小會受到限制,
此時也有可能改用後者來動態配置或者改為全域變數。)

所以實際上需要考量的是空間配置問題,看你是屬於哪一種就用哪一個。

: 4, 最後,指標能有一般變數沒有的「動態」功能,所以才需要指標?

不知道動態功能是甚麼意思 ?

: 在指標上的學習,小弟我一直在想這幾個問題?為何需要指標?每本書籍都把指標列為程
: 式碼重要的地方,無法理解~~~~~

因為你寫太少練習,簡單說就是如果你不需要用就可以把程式寫好,看起來程式碼又沒有
亂七八糟。那就不要用指標。

初學者與其練習怎麼用,不如先練習不要用怎麼寫 ?

PS:

我常開玩笑說,如果你完全不要用函式,那你大概就快不需要用指標了。
但是你要怎麼不用函式呢 @@

了解函式呼叫的運作與限制是使用指標一個很重要的基礎

--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.122.83.198
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1438725786.A.D8F.html
xjpjeass: 推,現在學指標真的會有點混亂 08/05 09:23
※ 編輯: Feis (140.122.83.198), 08/05/2015 11:43:38
KawasumiMai: 一樓你把變數跟指標想成姓名跟住址就好了,要寄東西 08/05 17:01
KawasumiMai: 給某某人你可以指定拿給他,或寄到他家。前者是不管 08/05 17:01
KawasumiMai: 他在哪都會讓他收到,後者是寄過去可能其實他搬走了 08/05 17:02
KawasumiMai: 但對郵差來說後者可以說幾乎一定比較快。 08/05 17:03
KawasumiMai: 然後就是物件跟物件之間要溝通,你不用指標就是存一 08/05 17:04
KawasumiMai: 堆變數呼叫一堆方法然後return 來return去,但如果在 08/05 17:04
KawasumiMai: 初始化就把指標傳過去記憶,就很方便呼叫其他物件 08/05 17:05
KawasumiMai: 不過用指標就要注意記憶體複寫的問題,如同前面說的 08/05 17:05
KawasumiMai: 郵差寄信過去其實是別人收到。可能會出錯或結果有誤 08/05 17:06
xjpjeass: 哇...謝謝川澄大的解釋,用讓自己有畫面的方式來想會方 08/05 17:39
xjpjeass: 便很多 08/05 17:39
coal511464: 好文 08/05 19:01
chuegou: 我不用函式的話大概會是滿滿的go to 08/05 22:13
MIKEmike07: 推 08/06 03:39
smilephoto: 查到這篇文 kawasum大 感謝啟發 03/02 21:15

你可能也想看看

搜尋相關網站