(以下均为个人理解)

函数访问的传参两种方式大致为:

  1. 值传递;
  2. 地址传递。

但是实际上可以都理解为,传进来的【形参】是主函数里的实参值的【一种复制】。

举个例子,哪怕我们将地址作为子函数的输入变量,形参依然只是一种复制,只在子函数运行期间存在:

#include <stdio.h>
#include <stdlib.h> void swap(int* a, int* b)
{
printf("a is %p, b is %p\n", a, b);
int* t = a;
a = b;
b = t;
printf("a is %p, b is %p\n", a, b);
printf("a is %d, b is %d\n", *a, *b);
} int main()
{
int a = 5, b = 10;
swap(&a, &b);
printf("a is %d, b is %d\n", a, b);
system("pause");
}

可以看到,在函数运行的过程中,a=5和b=10两个int数字的地址都被成功传入,并且完成了交换。

但是因为地址交换只发生在了子函数中。



所以仅仅是地址的交换对于主函数中值修改是无意义的

那么为什么可以通过指针作为参数交换变量。



参考上面这段代码,这段代码没有改变传进来的a和b的地址,而是改变了a和b指针指向的值

所以在函数运行后什么会保存。

指针指向的值。

也就是【指针】和【指针指向的内存里存储东西】的映射关系会被保存。

并不是牵扯到地址就会决定性地改变变量。

也就是,只有改变值才会被保存。

考虑到我们之前接触过的【结构体指针】。

指针作为传参形式的好处是可以节约空间。

根据我们上文中提到的子函数的形参是实参的一份复制来看,无论什么放在里面都是复制了那一份实参作为形参。

而拷贝指针,就可以只拷贝很少的空间。

再来说【数组】。

子函数中,对于数组的【修改】(非只读,包含写)都是会修改主函数的值的。

我理解为【数组操作】就是对于数组的地址中的内容进行修改。

因此子函数中对数组的操作会对主函数中产生影响。

再说C++的引用。

C++中的引用使用方式大致如下:

#include <iostream>
#include <stdlib.h>
using namespace std; void swap2(int& a, int& b)
{
int t = a;
a = b;
b = t;
} int main()
{
int a = 3, b = 4;
swap2(a, b);
cout << a << " " << b << endl;
system("pause");
}

引用看起来就很简单,对于需要修改值的形参传入的时候在前面写&,不需要的不写就行了。

【总结】

  1. 函数形参都是暂存量,只有修改指针的指向关系(地址->值的映射关系)才会被保存,也是看起来使用地址、使用指针能让子函数修改主函数值的原因。
  2. 引用使用起来最方便。

【更新】

考虑全局变量的存在,其实主函数中的变量只是存在了主函数时间的变量。

【C/C++】指针,传参,引用的一些个人理解。的更多相关文章

  1. [ 随手记6 ] C/C++ 形参、实参、按值传参、指针传参、引用传参

    个人原创: 1. 形参:形式上的参数,一般多在函数声明.函数定义的参数上: 2. 实参:实体参数,有实际的值,在运算上被循环使用的值: 3. 按值传参:按值,就是把实际的值传给函数内部: 4. 指针传 ...

  2. c/c++指针传参

    首先要理解参数传递,参数传递分值传递,指针传递,引用传递.(就我自己理解,就是把实参对形参进行赋值) 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单 ...

  3. C和C++引用传递和数组传参引用

    引用传递有两种传参方式,具体可参考文章 概括地讲,就是 *声明一个形参是指针,所以需要传递指针实参,对应的函数实现也应当遵循指针的语法.这种实现思路并不针对于C或者C++,因为它们都有指针,所以都可以 ...

  4. python 传值引用和传参引用

    调用同事的函数,传入goods_list,获取商品信息,然后将商品信息与goods_list的信息进行匹配,合并. 但是同事返回数据的同时改变了我传入的参数,goods_list.相当于传参引用,也就 ...

  5. C++单纯的指针传参的问题

    C++指针传参也是单纯的复制一份地址,如下代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace st ...

  6. C++的结构体指针传参

    typedef struct node{int n;node *left;}*tnode; 传参的时候注意用** void init(node **nn);int main(){tnode nna;i ...

  7. python3.x 类似cpp引用指针传参修改

    #同名局部变量调用外部全局变量: num=100def fun(): global num#告诉编译器是全局的num num+=100 print(num)print(fun)print(fun()) ...

  8. C++二级指针和指针引用传参

    前提 一级指针和引用 已经清晰一级指针和引用. 可参考:指针和引用与及指针常量和常量指针 或查阅其他资料. 一级指针和二级指针 个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析 ...

  9. C++ 传参的方式 值传递,指针传递,引用传递

    关于传参总是搞晕,这里总结下: 值传递: void func(int n) { } void main() { int x = 1; func(x); return; } 这种就是值传递,在func函 ...

随机推荐

  1. mybatis中批量插入的两种方式(高效插入)

    MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用 ...

  2. Python 爬取 拉钩

    ... from urllib import request from urllib import parse from urllib.error import URLError import jso ...

  3. SQL语句修改字段类型与第一次SQLServer试验解答

    SQL语句修改字段类型 mysql中 alert table name modify column name type; 例子:修改user表中的name属性类型为varchar(50) alert ...

  4. [loj2245]魔法森林

    枚举携带的"A型守护精灵"数$A_{0}$,那么即只能经过$A_{i}\le A_{0}$的边,并最小化1到$n$路径上最大的$B_{i}$ 将所有边按照$A_{i}$从小到大排序 ...

  5. Swift-技巧(八)CVPixelBuffer To CGImage

    摘要 Swift 中图像的表现形式不只是 Image,还有更加底层的方式,比如 CVPixelBuffer 像素缓存形式,那么像素缓存转换为可以在应用中展示的 CGImage,就要知道有哪些处理了. ...

  6. SpringBoot 动态代理实现三方接口调用

    目录 一.定义注解 二.建立动态代理类 三.注入spring容器 四.编写拦截器 五.创建客户端调用类 六.main方法测试 七.启动项目 在某些业务场景中,我们只需要业务代码中定义相应的接口或者相应 ...

  7. 洛谷 P6624 - [省选联考 2020 A 卷] 作业题(矩阵树定理+简单数论)

    题面传送门 u1s1 这种题目还是相当套路的罢 首先看到 \(\gcd\) 可以套路地往数论方向想,我们记 \(f_i\) 为满足边权的 \(\gcd\) 为 \(i\) 的倍数的所有生成树的权值之和 ...

  8. 洛谷 P6199 - [EER1]河童重工(点分治+虚树)

    洛谷题面传送门 神仙题. 首先看到这样两棵树的题目,我们肯定会往动态树分治的方向考虑.考虑每次找出 \(T_2\) 的重心进行点分治.然后考虑跨过分治中心的点对之间的连边情况.由于连边边权与两棵树都有 ...

  9. R语言与医学统计图形-【10】ggplot2图形映射

    ggplot2绘图系统--图形映射 颜色的映射. #aes中映射变量 ggplot()+geom_point(aes(x=carat,y=price,color='blue'),#color视为单一变 ...

  10. 前端4 — jQuery — 更新完毕

    1.下载jQuery 网址:Download jQuery | jQuery  最好下载最新版的,因为有什么bug问题,最新版的都会有,所以学技术就用最新版的,实际开发用的时候就要讲究了 2.开始用j ...