C語言函式內部改變指標本身

2021-05-26 04:35:19 字數 1776 閱讀 1108

今天發乙個c語言基礎的小知識點:c語言中函式引數傳遞方式只有一種:值傳遞。

舉個簡單的例子,乙個改變某個整型變數引數的函式

int change_value(int *pchange, int val)

*pchange = val;

return *pchange;

那麼pchange所指向位址內容的指改變了嗎?確實改變了。

因此一些教材就認為該方式是傳址,其實過程應該是這樣

比如呼叫的 時候有如下:

int a = 0x55aa;

change_value(&a, 0xaa55);

這樣a的值改變了,真正的情況是引數傳遞後,編譯器做了乙個引數拷貝過程,比如宣告乙個整型指標pcopy = &a;

這樣,pcopy只是傳進來引數&a的乙份拷貝,但是他們都指向了a的位址,因此用這種方法可以改變a 的值。

那麼現在有個問題,通過傳遞乙個指標,可以改變該指標所指向位址的內容,那麼如何改變指標本身呢?即如何改變指標的指向?

先看乙個錯誤的例子

void change_ptr(void *ptr, void *dest)

ptr = dest;

如果是這樣,能達到改變指標本身的目的嗎?

顯然不能!

那該怎麼做才能改變ptr呢?

既然ptr也是乙個變數,我要在函式內部改變它,那麼就傳遞乙個指向ptr的指標!也就是二級指標!

正確的函式形式如下

void change_ptr(void **ptr, void *dest)

*ptr = dest;

其實指標也是乙個變數,我們如果要改變它,必須找到它在記憶體中的位址,也就是指標的位址。

當然,也可以通過另一種方式,只不過該方式需要繫結呼叫者的行為

void *change_ptr(void *ptr, void *dest)

return (ptr = dest);

這樣在呼叫的時候必須做如下形式的呼叫

char *string;

string = change_ptr(string, dest);

否則string本身是不會改變的!但是這樣做意義不大,不如直接來個string = dest方便。

能用到在函式內部改變指標指向的地方通常是:乙個函式完成某項功能後,得到乙個指標,需要把這個指標以引數的 形式返回。

比如: foo(..., type **value);

在使用的時候通常這樣:

type *val = null;

foo(..., &val);

這樣之後,val指標就指向了正確的位置。

這裡申明一點,想去改變乙個變數本身的位址是不可能的,無論你怎麼做,在宣告(定義)變數的時候,它的位址就由編譯器決定好了。

比如這裡,你能修改val本身的位址嗎?這就如同你能修改常量嗎?

另外,如果我們想改變結構體中某個變數,需要傳遞乙個指向該結構體的指標!

這樣,不管你想改變的是結構體中的成員是乙個普通變數還是乙個指標,都是可以改變的,因為通過該結構體指標,可以獲得該結構體(也是該結構體中第乙個成員)的位址,進而也就知道了結構體中任一成員的位址,因此對於結構體內容,想怎麼改變就怎麼改變!

比如typedef struct *** ***_t;

***_t my_struct;

void change(***_t *dst, void *src)

dst->head = str; //dst->head已經改變!

呼叫時change(&my_struct, src);

這時my_struct.head本身已經改變了。

c 語言本身

預設引數和佔位引數在一起 int func int a,int b,int 0 函式過載 include using namespace std iostream 提供乙個叫命名空間的東西,標準的命名空間是 std include 方式二 if 0 using std cout 宣告命名空間中的乙個...

改變函式內部 this 指向

var o function fn a,b fn.call o,1,2 var arr 1 66,3 99,4 var max math.max.math,arr var min math.min.math,arr console.log max,min bind 方法 bind 方法不會呼叫函式。...

C語言 改變指標變數的值

例35 c語言程式設計實現改變指標變數的值。解題思路 指標p的值是可以變化的,printf函式輸出字串時,從指標變數p當時所指向的元素開始,逐個輸出各個字元,直到遇 0 為止。而陣列名雖然代表位址,但是它是常量,它的值是不能改變的。源 演示 include 標頭檔案 intmain 主函式 編譯執行...