【Linux C++ 系列 】05 C++ 指针和引用
1 指针和引用
C++语言和C语言类似,都可以直接对内存进行操作,而这个操作就需要借助指针(pointer)。所谓的指针,就是可以存储变量地址或者内存位置。指针存储的不是变量的值,而是变量值在内存中的地址,由于指针本身所占内存大小非常小,如果他指向的对象非常大,比如一个图片,那么通过指针的传递和操作,可以共享内存,而避免了对象在不同函数堆栈中进行拷贝,从而降低内存占用和提升程序效率。C++中的引用(reference)也可以避免变量的相互拷贝,它可以看作是一个变量名的别名,通过别名可以直接操作被引用的变量。C++语言中的 & 符号可以取变量地址。
2 指针示例
C++语言的指针是用 * 进行定义的,一般和 & 进行配套使用。声明指针对象需要同时指定指向的变量是什么类型的,声明语法如下所示:
dataType *ptr_name ;
下面给出一个简单的示例 :
#include <iostream>
using namespace std;
namespace mycom{
namespace subns{
int a = 7 ;
}
class Car{
public:
float h = 1.5 ;
void Drive(){
cout << " Car Drive..." << endl ;
}
};
}
int main()
{
int a = 5 ;
int *ptr_a ;
cout << " *ptr_a -> " << ptr_a << endl ;
ptr_a = &a ;
cout << " *ptr_a -> " << ptr_a << endl ;
*ptr_a = 6 ;
cout << " a -> " << a << endl ;
int b = 7 ;
ptr_a = &b ;
*ptr_a = 8 ;
cout << " a -> " << a << endl ;
cout << " b -> " << b << endl ;
ptr_a = &mycom::subns::a ;
*ptr_a = 9 ;
cout << " mycom::subns::a -> " << mycom::subns::a << endl ;
mycom::Car car ;
car.Drive();
float* ptr_f = &car.h ;
*ptr_f = 1.6 ;
cout << " car.h -> " << car.h << endl ;
return 0;
}
指针可以在不同变量地址进行切换,比如 int *ptr_a 定义的指针ptr_a可以指向Int类型的变量,那么只要通过&var方式获取到了变量地址,那么就可以通过*ptr_a修改变量的值。同样的值,对于命名空间中的变量以及类实例来说,都是适用的。执行如下代码进行编译和执行:
g++ demo05.cpp -o demo05
./demo05
输出结果如下所示:
3 引用示例
C++语言的指针是用 * 进行定义的,一般和 & 进行配套使用。而引用的定义也用到符号 & ,不过位置不同,这里需要注意二者区别。引用声明语法如下所示:
dataType &ref_name = var_name;
下面给出一个简单的示例 :
#include <iostream>
using namespace std;
namespace mycom{
namespace subns{
int a = 7 ;
}
class Car{
public:
float h = 1.5 ;
void Drive(){
cout << " Car Drive..." << endl ;
}
};
void change(Car &c){
c.h = 1.6 ;
}
void change_val(Car c){
c.h = 1.7 ;
}
}
int main()
{
int a = 5 ;
int &ref_a = a;
ref_a = 6 ;
cout << " a -> " << a << endl ;
a = 9 ;
cout << " ref_a -> " << ref_a << endl ;
// int b = 7 ;
// &ref_a = b ; //error
mycom::Car car ;
car.Drive();
mycom::change_val(car) ;
cout << " car.h -> " << car.h << endl ;
mycom::change(car) ;
cout << " car.h -> " << car.h << endl ;
return 0;
}
执行如下代码进行编译和执行:
g++ demo06.cpp -o demo06
./demo06
输出结果如下所示:
通过上述示例对比分析可知,引用和指针具有异同点,引用好比一个常量的指针,只能指向一个变量,不能再次赋值,而指针则可以。引用可以避免大变量的内存拷贝,当作为一个函数参数时,共享内存地址,也可以修改变量的值。下面为了验证指针和引用都指向同一个变量,下面再给一个打印内存地址的示例 :
#include <iostream>
using namespace std;
namespace mycom{
namespace subns{
int a = 7 ;
}
class Car{
public:
float h = 1.5 ;
void Drive(){
cout << " Car Drive..." << endl ;
}
};
void change(Car &c){
cout << " car addr in change -> " << &c << endl ;
c.h = 1.6 ;
}
void change_val(Car c){
cout << " car addr in change_val -> " << &c << endl ;
c.h = 1.7 ;
}
void change_ptr(Car* c){
cout << " car addr in change_ptr -> " << c << endl ;
*c.h = 1.8 ;
}
}
int main()
{
int a = 5 ;
int &ref_a = a;
ref_a = 6 ;
cout << " a -> " << a << endl ;
a = 9 ;
cout << " ref_a -> " << ref_a << endl ;
// int b = 7 ;
// &ref_a = b ; //error
mycom::Car car ;
cout << " car addr -> " << &car << endl ;
car.Drive();
mycom::change_val(car) ;
cout << " car.h -> " << car.h << endl ;
mycom::change(car) ;
cout << " car.h -> " << car.h << endl ;
mycom::change_ptr(&car) ;
cout << " car.h -> " << car.h << endl ;
return 0;
}
其中的mycom::change_ptr(&car) 是把指针作为函数函数,编译执行后打印如下结果:
root@ega-VirtualBox:/home/ega/mycpp# g++ demo07.cpp -o demo07
root@ega-VirtualBox:/home/ega/mycpp# ./demo07
a -> 6
ref_a -> 9
car addr -> 0x7ffcab2be08c
Car Drive...
car addr in change_val -> 0x7ffcab2be06c
car.h -> 1.5
car addr in change -> 0x7ffcab2be08c
car.h -> 1.6
car addr in change_ptr -> 0x7ffcab2be08c
car.h -> 1.8
root@ega-VirtualBox:/home/ega/mycpp#
由此可见,mycom::change_ptr(&car) 函数内打印的地址和mycom::change(car)打印的地址是一致的,即 0x7ffcab2be08c 。
- 点赞
- 收藏
- 关注作者
评论(0)