引用与指针
一、引用
引用为变量提供了一个别名,对引用所作的任何操作都作用于它所指向的对象。声明方式:
int& score = myScore;
注意:1.引用必须在声明的时候指向另一个值,如果不对其进行初始化会导致编译错误。
2.关于引用运算符&的位置,可以是"int& score"或"int & score"或"int &score"都可以,但是它只能修饰离它最近的变量名。例如:"int& score = myScore,age = myAge;"中,只有前者的score引用了myScore,后者的age是普通的数值赋值。
3.引用的关联只在声明时创建,之后对引用变量的赋值都是对与之关联的变量进行操作。例如:"int& score = myScore;score = hisScore;score = 100;"的作用是声明了一个与myScore关联的引用,然后将hisScore赋值给myScore,然后将100赋值给myScore,至始至终hisScore的数值没有发生改变。
C语言中也有按值传递与引用传递,在JAVA中,函数间进行传参时,基本数据类型是值传递,对象类型是引用传递。而在C++中,则根据声明的参数来确定是值传递还是引用传递。例如:
void swap1(int a,int b); //值传递,函数中的参数a,b不会对传入的实参产生影响
void swap2(int& a,int& b);//引用传递,函数中的参数a,b就是传入参数的别名。
值传递是将实参进行一次拷贝生成了形参,形参具有独立的内存空间且其改变不会影响到实参。但是这种传递是要进行复制的,当传入的是结构体、对象或大数组时,值传递十分低效。因此当函数中的形参值不需要改变,只是用来读操作的话,可以用常量引用声明参数:
void display(const vector<string>& vec);//引用传递向量,不允许函数对其修改
同理,在返回一个数据并赋值时,同样要进行拷贝操作。如果返回的类型过大,我们也可以考虑返回一个引用:
string& refToMain(vector<string>& inventory, int i)
{
return inventory[i];
}
以上函数返回的是向量inventory中第i个元素的值。主函数中可以声明一个引用来接收该函数的返回值:
string& rStr = refToMain(inventory,1)
由于是引用返回,因此不需要进行拷贝操作。但是要注意的是,必须保证函数结束后,返回的引用还在。例如下面的函数是不可取的,因为它返回的引用在函数结束后将不复存在:
string& refToMain()
{
string s = "stringwilldestroy";
return s;
}
二、指针
指针的本质是一个包含内存地址的变量。指针的声明方式如下:
int* pAPointer = 0;
注意:1.与引用运算符&类似,星号的位置也有三种情况,都可以。而且也只能修饰最近的那个变量。
2.以上将0赋给指针有特殊的含义,即该指针不指向任何内存。或在定义时指向NULL(iostream中的常量)。
因为指针存储对象的地址,所以需要有为指针赋予地址的方法。一种方法是获取已有变量的内存地址,并将其赋值给指针。如下面代码所示:
int* pScore;
int score;
pScore = &score;
这里的“&”是放在变量前的,它的作用是取地址,因此在这里它叫取址运算符。
而要用pScore来访问score则需要用到解引用。前面的迭代器已经提到过,解引用运算符“*”。以下代码是用来访问score中的值:
*pScore = 100;//这一句与score = 100;是同一个效果
注意:1.不要对空指针做解引用操作。
2.修改指针指向的对象的值时不要修改指针的值。例如pScore + 500并不是对score增加500,而是将存储在pScore中的地址增加500指向了另一块内存空间。
另外特别注意以下的写法,这是用来获取score的地址:
cout << pScore;//这一句与cout << &score;是同一个效果,输出的是score这个变量的内存地址。
与引用不同,指针可以在程序运行期间的不同时刻指向不同的对象。对指针重新赋值与变量的重新赋值一样。下面一行代码对pScore进行了重新赋值。
pScore = &newScore;//注意*pScore = newScore;则是将newScore的值赋给score
指针可以使用“->”运算符以一种更具有可读性的方式来访问对象成员。例如:
cout << pStr->size();
cout << (*pStr).size();
这两条语句是等价的。但是上面一条更具有可读性。
引用中常量引用。同样的,指针中也有常量指针。通过在声明和初始化指针时使用const来限制指针的行为。这些限制如同保护措施,可以让程序的意图更加明确。例如以下语句:
int score = 100;
int * const pScore = &score;
上面的代码创建了一个指向score的常量指针pScore。创建的方法是在声明时将const置于指针名称之前。第一次声明常量指针时必须对其进行初始化。实际上常量指针与引用是可以相互转化的。
pScore是常量指针,因此它永远不能指向其他任何内存地址,但是可以用它来改变其指向的值。这一点跟引用是很类似的。
除了常量指针外,还有一种用const来修饰的指针,可以实现无法用该指针来修改其指向的值。这种指针叫做指向常量指针。声明的方式是将const关键字置于指针所指向值的类型之前。例如以下语句:
const int* pNumber;
这种声明方式可以不给指针赋初值,而且在编程中可以改变指针的指向,但是不能修改这个指针所指向的变量的值。例如下面的代码是非法的:
*pNumber = 1;
如果希望指针所指的变量不能改变,指向变量的值也不能修改,那么只需要结合常量指针与指向常量指针就能定义指向常量的常量指针。例如以下语句:
const int* const pBONUS = &BONUS;
顾名思义,指向常量的常量指针是限制条件最多的一条指针,它既不能改变指向,也不能修改指向的变量,而且定义时必须赋初值。
对于C++,在函数传递中,除了值传递和引用传递,还有第三种传递,就是指针传递。其实原理跟引用传递差不多,而指针与引用本身就是一种原理。所以在此不再赘述。
还要注意一点,那就是指针与数组有着密切的联系。实际上,数组名是指向数组第一个元素的常量指针。因为数组元素存储在连续的内存块中,所以可以把数组名当做指针使用来实现数组元素的随机访问。
分享到:
相关推荐
比如auto和decltype让我们从书写冗长的类型和繁琐的类型推断中解脱出来,智能指针让我们再也不用担心内存泄漏的问题,右值引用避免了无谓的临时对象拷贝,type_traits和可以变模板参数让我们可以更方便地写更加泛化...
详细分析了指针与引用的区别,适合初学者了解
C++指针与引用,专门讲述c++中指针与引用的区别与使用。
C++程序设计:8 指针.ppt
Thinking in C: Foundations for Java & C++ by Chuck Allison produced by Bruce Eckel Chapter 1: Introduction and Getting Started40 MinutesStart Lecture Chapter 2: Fundamental Data Types41 ...
C++程序设计:第十章 指针.ppt
指针和引用是c++中的一个重要概念,在学习c++语言过程中,深刻理解指针和引用的本质是必不可少的本文通过举例子,作比较等方法,阐述c++程序设计中引用与指针的区别与联系,揭示引用的本质以及使用引用的好处。
C++高效编程:内存与性能优化(pdf版),深入C++经典好书!
C++重要的谨记指针和引用的区别,学好C++。
C++ Templates: The Complete Guide 英文版
C++习题 6数组与指针.doc (填空 选择 解答)
C#调用C++DLL,C++DLL中的函数参数包含指针。 绝对可用。
C++ 与C#之间的指针参数传递,实现无限量数据的传递,轻松无压力,方便在C++里面获取或者从C#传递数据到C++的动态库调用内。
java及C++中传值传递、引用传递和指针方式的理解.docx
我们知道,在C层有*.SO,它有全局变量,不要将Java或C++对象参考储存于C层的全局变量,把动态的对象指针放在全局变量是不好的。这样可以增加C函数的稳定度,包括它的通用性,可适应于更多更多的环境里使用,表示它...
该文档给出两个关于c++高阶指针与引用的应用实例,是一个非常不错的C++学习资源!
Java面向对象编程:从C++到Java—理解面向对象
java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket java c++ socket
4、 可以管理用new分配的内存块中的部分内存空间,即可以替代C++引用,并且保证内存正常释放,如: class A{}; class B{public: A a;}; shared_ptr<B> pb=new(ydsh,(B*)0) B; shared_ptr<A> pa=&pb->a; 5、 ...
Tangible Software Solutions 是功能齐全的源代码转换软件,可在 VB.NET、C#、Java、C++和Python之间,使用简单,功能丰富,灵活的进行选择和操作,界面友好。 C# to C++ 转换 C# to Java 转换 C# to VB 转换 C++ ...