C++ —— 使用指针
- 解引用
- 指针用于函数的参数
解引用
声明指针变量
后,在没有赋值
之前,这时候不能使用指针。因为,此时我们不知道指针里面装的是什么。
在声明变量后,应该养成对变量赋初始值
的好习惯。
指针
存放的是变量的地址
,因此,指针名
表示的是地址
(就像变量名
可以表示变量的值
一样)
*
运算符被称为间接值
或解除引用(解引用
)运算符,将它用于指针,可以得到该地址的内存中存储的值
,*
也是乘法符号,C++根据上下文来确定所指的是乘法还是解引用。
#include <iostream>
using namespace std;int main() {int a = 123;int *pa = &a;int *paa = &a;cout << "a = " << a << endl;cout << "*pa = " << *pa << endl;cout << "*paa = " << *paa << endl;a = 456;// 通过对pa、paa解引用再修改a的值,与直接修改a的值效果一样。 // *pa = 456;// *paa = 456;cout << "a = " << a << endl;cout << "*pa = " << *pa << endl;cout << "*paa = " << *paa << endl;cout << "&a = " << &a << ", pa = " << pa << ", paa = " << paa << endl;return 0;
}
运行结果如下:
a = 123
*pa = 123
*paa = 123
a = 456
*pa = 456
*paa = 456
&a = 0x7ffeb1a9b334, pa = 0x7ffeb1a9b334, paa = 0x7ffeb1a9b334
不同PC在每次运行程序时,输出的变量地址都不一样,内存地址系统随机分配
的。
程序在存储数据的时候,必须要跟踪数据的三种属性:数据存储的位置
、数据是什么类型
、数据值
是多少。
指针用于函数的参数
先看一段函数的代码:
#include <iostream>
using namespace std;void func(int num, string name) {cout << "Hello no." << num << ", " << name << endl;
}int main() {int num = 123;string name = "John";func(num, name);return 0;
}
运行结果如下:
Hello no.123, John
如果把函数的形参
声明为指针
,调用的时候把实参的地址
传进去,形参中存放的是实参的地址
,在函数中通过解引用
的方法直接操作
内存中的数据,可以修改实数的值,这种方法被通俗的称为地址传递
或传地址
。使用传地址的方法修改上述代码,修改后的代码如下:
#include <iostream>
using namespace std;void func(int *num, string *name) {cout << "Hello no." << *num << ", " << *name << endl;*num = 456;*name = "Doe";
}int main() {int num = 123;string name = "John";func(&num, &name);cout << "Hello no." << num << ", " << name << endl;return 0;
}
运行结果如下:
Hello no.123, John
Hello no.456, Doe
从运行结果可以看出,实参int num = 123
和string name = "John"
的值,在函数func
内部被修改了。
值传递
:函数的形参
是普通变量
。调用函数的时候,形参中存放的是变量的值
,是实参
的拷贝
。在函数中修改
形参的值是不会改变
实参的。
传地址的意义如下:
- 可以在函数中修改实参的值。
- 减少内存拷贝,提升性能。(下面解释一下这一点)
先打印一下string
类型的变量占用内存的大小:
cout << "sizeof(string): " << sizeof(string) << endl;
显示的是:
sizeof(string): 32
函数在每次调用时,都会为形参分配内存。如果func
函数是地址传递
,形参是指针int *num
和 string *name
,一个指针占用8字节的内存空间,那么内存开销一共是:8字节+8字节=16字节
。如果func
函数是值传递
,形参是普通变量int num
和 string name
,内存开销一共是:4字节+32字节=36字节
。比值传递的内存开销打了36-16=20字节
。
感谢浏览,一起学习!