隨筆- 234 文章- 0 評論- 81
二級指針
void change_val(char *p)
{
char new_val[3] = {2, 3, 4}; // [2]
p = new_val; //[3]
return; // [4]
}
char val[3] = {1, 2, 3};
char *p = val; // [1]
change_val(p);
執行到語句[1]時,val和p如下圖,val的起始地址爲0x0000,指針p指向val首地址
執行到語句[2]時,val不變,指針p作爲傳入參數,拷貝其值,以p_copy代替,仍指向val首地址,函數內的new_val的起始地址爲0x0020
執行到語句[3]時,將p_copy更改爲指向new_val首地址,即:
執行到語句[4]時,函數返回,由於傳入的只是p的拷貝p_copy(指針傳入的也是拷貝?),故改變的只是p_copy的指向,對於指針p沒有任何變化
改進一:[使用拷貝]
void change_val(char *p)
{
char new_val[3] = {2, 3, 4}; // [2]
memcpy(p, new_val, 3);
return; // [3]
}
char val[3] = {1, 2, 3};
char *p = new char[3]; // [1]
change_val(p);
執行到語句[3]時,將p_copy指向的地址(0x0000)填充爲new_val的值,此時p_copy的值並沒有發生變化,而是p_copy指向的值,即函數外p指向的值發生了變化,因此當函數返回時,p指向的內容已經發生了改變,即:
改進二:[使用二級指針]
void change_val(char **p)
{
static char new_val[3] = {2, 3, 4}; // [2]
*p = new_val;
return; // [3]
}
char val[3] = {1, 2, 3};
char *p = val; // [1]
change_val(&p);
執行到語句[3]時,函數傳入的是p指針的地址,即p_copy_double,將p_copy_double指向的地址(0x0020)填充爲new_val的地址,即p指針的值發生了變化,因此當函數返回時,p指向的內容已經改變,即:
小結一下:如果直接使用賦值操作(如p = q),需要使用二級指針
如果使用拷貝,即重新分配了內存(如strcpy, memcpy),使用一級指針即可
使用二級指針,也就是指針的指針時,其中一級指針是存放的是一個地址,二級指針存放的是一級指針的地址。也就是上面所說的p指針的值發生了變化。