1. 程式人生 > >二級指針

二級指針

alt ble comm nbsp bsp 指針的指針 chang str clas

程序:

  1. void change_val(char *p)
  2. {
  3. char new_val[3] = {2, 3, 4}; // [2]
  4. p = new_val; //[3]
  5. return; // [4]
  6. }
  7. char val[3] = {1, 2, 3};
  8. char *p = val; // [1]
  9. 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沒有任何變化

             技術分享

改進一:[使用拷貝]

  1. void change_val(char *p)
  2. {
  3. char new_val[3] = {2, 3, 4}; // [2]
  4. memcpy(p, new_val, 3);
  5. return; // [3]
  6. }
  7. char val[3] = {1, 2, 3};
  8. char *p = new char[3]; // [1]
  9. change_val(p);

執行到語句[3]時,將p_copy指向的地址(0x0000)填充為new_val的值,此時p_copy的值並沒有發生變化,而是p_copy指向的值,即函數外p指向的值發生了變化,因此當函數返回時,p指向的內容已經發生了改變,即:

             技術分享

改進二:[使用二級指針]

  1. void change_val(char **p)
  2. {
  3. static char new_val[3] = {2, 3, 4}; // [2]
  4. *p = new_val;
  5. return; // [3]
  6. }
  7. char val[3] = {1, 2, 3};
  8. char *p = val; // [1]
  9. change_val(&p);

執行到語句[3]時,函數傳入的是p指針的地址,即p_copy_double,將p_copy_double指向的地址(0x0020)填充為new_val的地址,即p指針的值發生了變化,因此當函數返回時,p指向的內容已經改變,即:

          技術分享

小結一下:如果直接使用賦值操作(如p = q),需要使用二級指針
     如果使用拷貝,即重新分配了內存(如strcpy, memcpy),使用一級指針即可

     使用二級指針,也就是指針的指針時,其中一級指針是存放的是一個地址,二級指針存放的是一級指針的地址。也就是上面所說的p指針的值發生了變化。

二級指針