接触过c的小伙伴大多现在没有使用c了,但是如果要问到对c印象最深(最苦逼)的是什么,绝对会回答各种******的指针
c是博主大学开始第一门学习的编程语言,满怀各种幻想,后来学了指针,就又爱又恨了.
话不多说,上简单代码demo来体会一下,用不用指针的区别,以下是完整代码
完整测试代码
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
using namespace std;
class SimpleClass {
private:
int param;
public:
SimpleClass() {
this->param = 0;
}
int getParam() {
return param;
}
void setParam(int value) {
this->param = value;
}
};
//测试简单传值
void testValue(int param) {
cout << "in function testValue" << endl;
cout << "传入的参数 value:" << param<<endl;
cout << "传入的参数 address:" << ¶m<<endl;
param = param + 1;
}
//测试指针
void testPoint(int * param) {
cout << "in function testPoint" << endl;
cout << " param 的 address:" << ¶m << endl;
cout << " * param 的 address:" << &(*param) << endl;
cout << " * param:" << *param << endl;
*param = *param + 1;
}
//测试引用
void testReference(SimpleClass & obj) {
cout << "in function testReference" << endl;
cout << "&obj:"<<&obj<<endl;
obj.setParam(obj.getParam() + 1);
}
int main()
{
int a = 0;
cout << "a 的address:" << &a<<endl;
//testValue(a);
cout << a << endl;
int* pointA = &a;
int** pointB = &pointA;
testPoint(pointA);
cout << a << endl;
SimpleClass obj;
cout <<" main &obj:" <<&obj << endl;
testReference(obj);
cout << obj.getParam()<<endl;
}
将上述代码分成三部分解读:
代码分解
第一部分:不用指针
函数:
//测试简单传值
//测试简单传值
void testValue(int param) {
cout << "in function testValue" << endl;
cout << "传入的参数 value:" << param<<endl;
cout << "传入的参数 address:" << ¶m<<endl;
param = param + 1;
}
main函数:
int main()
{
int a = 0;
cout << "a 的address:" << &a<<endl;
testValue(a);
cout << a << endl;
}
输出结果:
这是为什么???
经常听见的解释就是,函数是传值的,但是很多时候,值可能也指的是地址,如果拿到地址,自然是为所欲为了.
debug调试:
进入到testValue函数中:
退出testValue 回到main,发现param的value的确是变成了1(原来是0)
观察debug过程或者是测试的输出,不难发现,在函数里面的参数不是函数外的参数,也就是传递的是value的复制品,函数结束,复制品也就消失,对原版不产生影响.
第二部分 使用指针
函数定义:
//测试指针
void testPoint(int * param) {
cout << "in function testPoint" << endl;
cout << " param 的 address:" << ¶m << endl;
cout << " * param 的 address:" << &(*param) << endl;
cout << " * param:" << *param << endl;
*param = *param + 1;
}
main函数:
int main()
{
int a = 0;
cout << "a 的address:" << &a<<endl;
//testValue(a);
cout << a << endl;
int* pointA = &a;
testPoint(pointA);
cout << a << endl;
}
输出结果:
观察输出并且结合代码发现:
a的地址 &a 与 *param 的地址 &(*param) 是一模一样的,那么这就说明
a 与 *param 是完全等价的 ,*param 的修改也就是对a的修改,所以这里最后main中输出的
a是1
当然还有多级指针,比如二级指针,对 一级指针取& 就得到二级指针
比如:
int a = 0;
cout << a << endl;
int* pointA = &a; // pointA 是 类型 int *
int** pointB = &pointA;// pointB 是类型 int** ,表达式 (&pointA) 也是类型 int ** (是对一级指针 pointA 取 &得到的)
第三部分 引用
引用,是c++ 里面出现的,当然其他面向对象的语言里面也有(几乎是将指针给隐形了),比如java
定义一个简单的cpp类;
class SimpleClass {
private:
int param;
public:
SimpleClass() {
this->param = 0;
}
int getParam() {
return param;
}
void setParam(int value) {
this->param = value;
}
};
测试函数:
//测试引用
void testReference(SimpleClass & obj) {
cout << "in function testReference" << endl;
cout << "&obj:"<<&obj<<endl;
obj.setParam(obj.getParam() + 1);
}
mian函数:
int main(){
SimpleClass obj;
cout <<" main &obj:" <<&obj << endl;
testReference(obj);
cout << obj.getParam()<<endl;
}
测试结果:
观察发现 在main和testReference 中对obj 取 & 都是一模一样的,是不是感觉有点像指针,只是指针是 多了一层 指针->对象
而引用直接是对象
如果真正的理解了指针,使用还是很方便的,指针的大小只是一个int的大小,需要在使用指针做一些操作时一定要赋值(指向真正要操作的内存或者是对象),不然容易出现空指针的问题,当然也可能有些其他的问题.
指针仔细理解起来,还是比较容易,但是一旦投入到开发中,常常会有一种感觉,这里的参数是 * 还是** 呢? 然后抱着尝试的态度,都试了一遍,但是要认真地分析是为什么的话,得发一会儿工夫.
所以,还是少用指针吧(特别是多级指针),多使用引用,避免一些无所谓的烦恼.