C語言指針用法詳解 (四) 指針作為函數的參數


歡迎指正!!!!

標明出處,歡迎轉載!!!!


函數傳參:就是形參復制一份實參的值,抱回函數體里算

  • 函數內部修改外部變量的值,需要一級指針;
  • 函數內部修改外部指針變量的值,需要二級指針;

經典問題1 :交換CET1 和 CET2 的值(一級指針交換值)

  • Wrong:

void swap_val(int a, int b)
{
    int tmp = a;
    a = b;
    b = tmp;
}

  

錯誤:因為交換的是副本,真品沒改變的
 
  • Practice:

#include <bits/stdc++.h>
using namespace std;
/*** 通過一級指針交換值  */
void swap_val(int *a, int *b)
{
    /***
    **  ————>> here
    **   a == &CET1 , b == &CET2
    **  *a ==  CET1 ,*b ==  CET2
    ***/
    cout<<"      函數體 交換前  a == "<<a<<"   b == "<<b<<endl;
    cout<<"      函數體 交換前 *a == "<<*a<<" *b == "<<*b<<endl;
    int tmp = *a; /// 三變量換的不是值,是a、b 分別指向的值
    *a = *b;
    *b = tmp;
    cout<<"      函數體 交換后  a == "<<a<<"   b == "<<b<<endl;
    cout<<"      函數體 交換后 *a == "<<*a<<" *b == "<<*b<<endl<<endl<<endl;;
}
int main()
{
    int CET1 = 424;
    int CET2 = 426;
    cout<<"函數前 CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    cout<<"函數前  &CET1 == "<<&CET1<<" &CET2 == "<<&CET2<<endl<<endl<<endl;
    swap_val(&CET1,&CET2);
    /***
    **   傳入的是形參是&CET1和 &CET2
    **   相當於  int *a = & CET1 , int *b = &CET2
    **   三醒指針: 指針 a 的類型是 int * ,指向的類型 int  指向的值是 &CET1
    **   三醒指針: 指針 b 的類型是 int * ,指向的類型 int  指向的值是 &CET2
    **  ----->> 出門左轉
    ***/
    cout<<"函數后 CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    cout<<"函數后  &CET1 == "<<&CET1<<" &CET2 == "<<&CET2<<endl<<endl<<endl;
}

  • Reason

1.此時形參(a 、b )和實參建立的是 指針初始化,指向為&CET1,&CET2 的關系
2.通過改變指針指向完成交換
3.傳入的是地址,指針操作的是唯一的

經典問題2 :交換CET1 和 CET2 的地址(二級指針交換地址)

  • practice

#include <bits/stdc++.h>
using namespace std;
/*** 通過二級指針交換值的地址  */
void swap_val(int **a, int **b)
{
    /***
    **  ————>> here
    **   Int **a = &CET1
    **   1.a 賦值於&CET1,a == &CET1
    **   2.*a == CET1
    **   3.&(*a) ==a
    **   Int **b = &CET2
    **   1.b 賦值於&CET2,b == &CET2
    **   2.*b == CET2
    **   3.&(*b) ==b
    ***/
    cout<<"             函數體  交換前      a == "<<a<<" b == "<<b<<endl;
    cout<<"             函數體  交換前     *a == "<<*a<<" *b == "<<*b<<endl;
    cout<<"             函數體  交換前  &(*a) == "<<&(*a)<<" &(*b) == "<<&(*b)<<endl;
    cout<<"             函數體  交換前    **a == "<<**a<<" **b == "<<**b<<endl<<endl<<endl;
    int *tmp = NULL;
    tmp = *a;
    *a = *b;
    *b = tmp;
    cout<<"             函數體  交換后      a == "<<a<<" b == "<<b<<endl;
    cout<<"             函數體  交換后     *a == "<<*a<<" *b == "<<*b<<endl;
    cout<<"             函數體  交換后  &(*a) == "<<&(*a)<<" &(*b) == "<<&(*b)<<endl;
    cout<<"             函數體  交換后    **a == "<<**a<<" **b == "<<**b<<endl<<endl<<endl;
}
int main()
{
    int *CET1 = (int*)malloc(sizeof(int));
    int *CET2 = (int*)malloc(sizeof(int));
    ///**   三醒指針: 指針 CET1,CET2 的類型是 int * ,指向的類型 int  只是初始化指針,沒有給定指向  指針本身的內存是系統分配的 值也是組織分配的
    cout<<"初始化   CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    int mark1 = 424;
    int mark2 = 426;
    CET1 = &mark1;
    CET2 = &mark2;
    ///**    指針 CET1,CET2 指向  mark1 ,mark2  值是mark1 ,mark2 的地址
    cout<<"初始化 &mark1 == "<<&mark1<<" &mark2 == "<<&mark2<<endl;
    cout<<"函數前   CET1 == "<<CET1<<"   CET2 == "<<CET2<<endl;
    cout<<"函數前  &CET1 == "<<&CET1<<"  &CET2 == "<<&CET2<<endl<<endl<<endl;
    swap_val(&CET1,&CET2);
    /***
    **   本來 CET1,CET2 是個指針
    **   取址符后傳入的當然就是 指針的地址
    **   相當於  int **a = & CET1 , int **b = &CET2
    **   三醒指針: 指針 a 的類型是 int ** ,指向的類型 int * 指向的值是 &CET1
    **   三醒指針: 指針 b 的類型是 int ** ,指向的類型 int * 指向的值是 &CET2
    **  ----->> 出門左轉
    ***/
    cout<<"最后結果  CET1 == "<<CET1<<" CET2 == "<<CET2<<endl;
    cout<<"函數后   &CET1 == "<<&CET1<<"  &CET2 == "<<&CET2<<endl;
}

 

  • Reason

重點語句的解釋:


經典問題 3:函數體中為指針的指針分配地址(二級指針分配新的內存)

  • practice

#include <bits/stdc++.h>
using namespace std;
/*** 通過二級指針購置指針新的地址  */
void allocte(int **a)
{
    /***
    **   int **a = &ptr ;
    **     a = &ptr
    **     *a = ptr
    **   三省指針: 指針a的類型是 int ** ,指針 a的指向類型為int* ,指向&ptr
    ***/
   *a = (int *)malloc(sizeof(int));
   /// 新的地址 : 改變了*a的指向 ,改變了ptr
}
int main()
{
   int *ptr = NULL;
   /// 三省指針: 指針ptr的類型是 int * ,指針 ptr的指向類型為int ,指向NULL
   /// ** 記得 ptr 是指針 就是地址  *ptr 才是值
   cout<<"  ptr : "<<ptr<<endl;
   cout<<" &ptr: "<<&ptr<<endl<<endl<<endl;
  // cout<<" *ptr: "<<*ptr<<endl; /// ptr是空  然后 ptr的指向  當然是非法
   allocte(&ptr);
   cout<<"  ptr : "<<ptr<<endl;
   cout<<" &ptr: "<<&ptr<<endl;
   cout<<" *ptr: "<<*ptr<<endl; /// ptr是空  然后 ptr的指向
}

  • Reason

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM