【C/C++】指针,传参,引用的一些个人理解。
(以下均为个人理解)
函数访问的传参两种方式大致为:
- 值传递;
- 地址传递。
但是实际上可以都理解为,传进来的【形参】是主函数里的实参值的【一种复制】。
举个例子,哪怕我们将地址作为子函数的输入变量,形参依然只是一种复制,只在子函数运行期间存在:
#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");
}
引用看起来就很简单,对于需要修改值的形参传入的时候在前面写&,不需要的不写就行了。
【总结】
- 函数形参都是暂存量,只有修改指针的指向关系(地址->值的映射关系)才会被保存,也是看起来使用地址、使用指针能让子函数修改主函数值的原因。
- 引用使用起来最方便。
【更新】
考虑全局变量的存在,其实主函数中的变量只是存在了主函数时间的变量。
【C/C++】指针,传参,引用的一些个人理解。的更多相关文章
- [ 随手记6 ] C/C++ 形参、实参、按值传参、指针传参、引用传参
个人原创: 1. 形参:形式上的参数,一般多在函数声明.函数定义的参数上: 2. 实参:实体参数,有实际的值,在运算上被循环使用的值: 3. 按值传参:按值,就是把实际的值传给函数内部: 4. 指针传 ...
- c/c++指针传参
首先要理解参数传递,参数传递分值传递,指针传递,引用传递.(就我自己理解,就是把实参对形参进行赋值) 值传递: 形参是实参的拷贝,改变形参的值并不会影响外部实参的值.从被调用函数的角度来说,值传递是单 ...
- C和C++引用传递和数组传参引用
引用传递有两种传参方式,具体可参考文章 概括地讲,就是 *声明一个形参是指针,所以需要传递指针实参,对应的函数实现也应当遵循指针的语法.这种实现思路并不针对于C或者C++,因为它们都有指针,所以都可以 ...
- python 传值引用和传参引用
调用同事的函数,传入goods_list,获取商品信息,然后将商品信息与goods_list的信息进行匹配,合并. 但是同事返回数据的同时改变了我传入的参数,goods_list.相当于传参引用,也就 ...
- C++单纯的指针传参的问题
C++指针传参也是单纯的复制一份地址,如下代码: #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace st ...
- C++的结构体指针传参
typedef struct node{int n;node *left;}*tnode; 传参的时候注意用** void init(node **nn);int main(){tnode nna;i ...
- python3.x 类似cpp引用指针传参修改
#同名局部变量调用外部全局变量: num=100def fun(): global num#告诉编译器是全局的num num+=100 print(num)print(fun)print(fun()) ...
- C++二级指针和指针引用传参
前提 一级指针和引用 已经清晰一级指针和引用. 可参考:指针和引用与及指针常量和常量指针 或查阅其他资料. 一级指针和二级指针 个人觉得文字描述比较难读懂,直接看代码运行结果分析好些,如果想看文字分析 ...
- C++ 传参的方式 值传递,指针传递,引用传递
关于传参总是搞晕,这里总结下: 值传递: void func(int n) { } void main() { int x = 1; func(x); return; } 这种就是值传递,在func函 ...
随机推荐
- SpringCloud config native 配置
1.概述 最近项目使用springCloud 框架,使用config搭建git作为配置中心. 在私有化部署中,出现很多比较麻烦的和鸡肋的设计. 每次部署都需要安装gitlab 有些环境安装完gitla ...
- RabbitMQ保证消息的顺序性
当我们的系统中引入了MQ之后,不得不考虑的一个问题是如何保证消息的顺序性,这是一个至关重要的事情,如果顺序错乱了,就会导致数据的不一致. 比如:业务场景是这样的:我们需要根据mysql的b ...
- IIS设置URL重写,实现页面的跳转的重定向方法
默认IIS是不提供URL重写模块的. 请注意,不要将IIS默认的HTTP重定向理解为url重写. 安装url重写模块 url重写,是要从iis的应用市场下载url重写组件才可以的. URL重写工具的下 ...
- Django 小实例S1 简易学生选课管理系统 0 初步介绍与演示
Django 小实例S1 简易学生选课管理系统 第0章--初步介绍与演示 点击查看教程总目录 作者自我介绍:b站小UP主,时常直播编程+红警三,python1对1辅导老师. 1 初步介绍 先介绍下这个 ...
- JDBC连接MySQL数据库代码
******************************************************1********************************************* ...
- 安装mysql会出现start service错误
安装MySQL时无法启动服务(could not start the service MYSQL .Error:0)安装mysql会出现start service错误安装mysql时 配置到start ...
- [bzoj2743]采花
预处理出每一个点下一个相同颜色的位置,记为next,然后将询问按左端点排序后不断右移左指针,设要删除i位置,就令f[next[next[i]]+1,同时还要删除原来的标记,即令f[next[i]]-1 ...
- [atARC094D]Worst Case
首先,容易证明满足条件的$ip_{i}$必然是一个前缀 将其看成一张二分图,$i$向满足$ip_{i}<xy$的$p_{i}$连边,即找到一个前缀满足其有完美匹配 二分枚举前缀长度$k$,根据h ...
- AtCoder Beginner Contest 188题解
A 题意 问\(x,y\)相差是否小于\(3\) #include<iostream> #include<cstdio> #include<cmath> #defi ...
- Codeforces 1464F - My Beautiful Madness(树的直径)
Codeforces 题面传送门 & 洛谷题面传送门 树上数据结构大杂烩(?) 首先考虑什么样的点能够在所有路径的 \(d\) 邻居的交集内.显然如果一个点在一条路径的 \(d\) 邻居内则必 ...