内容全部转自:https://blog.csdn.net/zx3517288/article/details/53363798/
指针:与普通变量不同的是它的存储的是变量的地址。就内存的分布来说,指针和一个变量在内存中存放是没有任何区别的,无非指针存放的是变量的地址。
传值:将实参拷贝给形参,是单向传递(实参-》形参),赋值完后形参实参没有任何联系,对形参的修改就不会影响到实参。形参和实参是相互独立的。
传地址:也是一种传值,是将实参内存储的地址变量值赋值给形参,之后如果对形参所指向的对象修改,那么也直接反映在实参中;但是如果对形参所存储的地址变量修改,也就是让它指向别的地址,那么对实参不会有任何影响。
传引用:没有任何值的拷贝,一句话,就是让另外一个变量也执行该实参。就是两个变量指向同一个对象。这时对形参的修改,必然反映到实参上。
例子代码:
#include<iostream> using namespace std; void Value(int n) { cout << "Value(int n)"<< endl; cout << "{" << endl; cout << " &n=" << &n << endl;//传值,肯定n是不同的地址,也就是和主函数中的n并不是一个变量。 cout << "}" << endl; n++; } void Reference(int &n)//传引用,还是一块地址, { cout << "Reference(int &n)" << endl; cout << "{" << endl; cout << " n=" << n << " &n=" << &n << endl; cout << "}" << endl; n++; } void Pointer(int *n)//传指针,是两块地址。 { cout << "Pointer(int *n)" << endl; cout << "{" << endl; cout << " n=" << n << " &n=" << &n << endl;//这个引用,肯定也和主函数中的不同。 (*n)++; int b = 20; cout << " b=" << b << " n = &b" << endl; n = &b; cout << " n=" << n << " &n=" << &n << endl; (*n)++; cout << "}" << endl; } int main() { int n = 10; cout << "n = " << 10 << " &n=" << &n << endl<< endl; Value(n); cout << "after Value() n=" << n << endl << endl; Reference(n); cout << "after Reference() n=" << n << endl << endl; Pointer(&n); cout << "after Pointer() n=" << n << endl << endl ; //system("pause"); return true; }
运行结果:
引用传递操作地址是实参地址 ,形参相当于实参的一个别名,对它的操作就是对实参的操作。
为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:
程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。
最后,总结一下指针和引用的相同点和不同点:
★相同点:
●都是地址的概念;
指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。
★不同点:
●指针是一个实体,而引用仅是个别名;
●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;
●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有 的, 前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)
●引用不能为空,指针可以为空;
●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小(这都和编译符号表中变量所对应地址有关);
●指针和引用的自增(++)运算意义不一样;
●引用是类型安全的,而指针不是 (引用比指针多了类型检查)