C语言指针用法详解 指针作为函数的参数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于C语言指针用法详解 指针作为函数的参数的主要内容,如果未能解决你的问题,请参考以下文章