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

原文地址:https://www.cnblogs.com/sxy-798013203/p/7640661.html