zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    适配器模式
    快排变种
    美团面试问题
    gulp前端自动化构建工具新手入门篇
    javascript继承
    .call()和.apply()相同点与不同点
    JavaScript原型,原型链 !
    锚点链接和hash属性
    构造函数与普通函数的比较
    JS的作用域和作用域链
  • 原文地址:https://www.cnblogs.com/sxy-798013203/p/7640661.html
Copyright © 2011-2022 走看看