再议指针和引用的一些事情吧

关于指针和引用一直是学习C++的同学们争论的焦点,什么时候用指针,什么时候用引用,还有怎么引用数组,这么用指针访问数组,以及初始化的问题。

不过有一些文章我在很早就已经写过,但是由于当时时间不充分,自己也都是随性写的,可以参看以前我的一个文章:http://blog.csdn.net/pbymw8iwm/article/details/8555197

这里就详细说一下:

1.关于引用和指针的初始化

首先没有空引用,一个引用必须代表某个对象,如果你有一个变量,目的用来指向领一个对象,但是它有可能不指向任何对象。

程序为指针分配内存空间,但是引用不需要分配内存空间。

比如这样的例子,

int  a = 0;

int* p = NULL;

int& pref= *p;

p = &a;

上面的这段代码,相信你心里有数了,这个例子告诉我们指针可以被重复赋值,执行另外一个对象,但是引用却总是执行他最初获得的那个对象,所以第三行的代码你将会得到一个无效的引用,即使后来p已经指向了a的地址。

到这里就不得不再说一下指针和引用去访问数组了,并且分别用他们初始化数组的方式了:

int main() {
	int a[10]={1,2,3,4,5,6,7,8,9,0};
	int (*pa)[10] = &a;
	printf("%d",(*pa)[8]);
}

这个是对指针pa的初始化和通过指针对数组的访问,首先pa是一个指针,你看到pa前面的*,就该知道,他的确是个指针,那么它指向的是什么 int  [10] ,也就是说有10个整形元素的数组,怎么初始化呢,我们都知道数组名代表的是数组的首地址,那么我们应该用数组a的首地址去初始化它。

int main() {
	int a[10]={1,2,3,4,5,6,7,8,9,0};
	int (&pa)[10] = a;
	printf("%d",(pa)[8]);
}

这个是对引用pa的初始化以及通过引用对数组访问,首先pa是一个引用,你看到pa前面的&,你就知道他的确是引用,他引用的是一个 int 【10】的数组,引用这个数组的名字就代表对这个数组的引用,也就是说此时pa和a是一样的,那么对于数组的访问,怎么用引用访问,相信你知道了。

2 关于指针和引用的函数传参

接着就要说传参数了,

class A
{
public:
	A(){cout<<"构造函数"<<endl;}
	~A(){cout<<"析构函数"<<endl;}
	A(const A &a){cout<<"拷贝构造函数"<<endl;};

	A& operator=(const A &a)
	{
		cout<<"赋值操作符"<<endl;
		return *this;
	}
};
A show(A a)
{
	return a;
}

A showRef(A& a)
{
	return a;
}
A showPoint(A* a)
{
	return *a;
}
int main() {
     A a;
	 show(a);
	 /*
	 拷贝构造函数
	 拷贝构造函数
	 析构函数
	 析构函数
	 */
	 showRef(a);
	  /*
	 拷贝构造函数
	 析构函数
     */
	 showPoint(&a);
	  /*
	 拷贝构造函数
	 析构函数
     */
}

说明了传参数的时候引用和指针的效果相似。都不需要在这个栈上创建新的对象,而普通的传参则会调用拷贝构造函数,用主调函数的参数对象来初始化北调函数的对象。

3 练习

int main() {
        const int& a = 0;
	const int* p = 0;
	cout << a << *p;
}

这个程序有什么问题么?(a是一个引用,引用的是一个常量,因此a的值是0,p是一个指针,指向的是一个空指针,因此对p的访问是非法的)

再看一个如下程序,看看这个段代码有什么输出?

int main() {
	int a = 0;
        const int& const ref = a;
	const int* const p = &a;
	a =  1;
	cout << a << endl;
	cout << *p;
}

结果显示a和*p都是1,为什么呢,ref是一个常引用,引用的是一个const常量,其实ref本身就是const引用,因为他一旦引用到他初始化的那个变量后就不会再改变了,此时a但是是非const的,所以a的改变也会影响到ref,即使ref指向的是const常量,但由于a本身是非const的,同样的p也是一样的。

时间: 2024-08-06 00:39:19

再议指针和引用的一些事情吧的相关文章

再议指针---------函数回调(qsort函数原理)

我们能否写一个这样的函数: 可以对任何类型数据排序 任何人在使用该函数不需要修改该函数代码(即:用户可以不必看到函数源 码,只会调用就行) 思考: 用户需要排序的数据的类型千变万化,可能是int型,也有可能是自定义的结构体类型,各种类型的大小比较规则是不一样的,这样看来实现一个这样全能的排序函数似乎不可能. 但具体需要排序的类型应按照什么规则确定大小只有使用该函数的用户最清楚,那我们可不可以把实现比较大小的功能交给用户来完成了,到时候用户只需告诉该函数比较规则(函数)在什么位置,这样排序函数不就

C++ 指针与引用 知识点 小结

[摘要] 指针可以指向变量.数组.字符串.函数.甚至结构体.即指针可以指向不同数据对象.指针问题 包括 常量指针.数组指针.函数指针.this指针.指针传值.指向指针的指针 等.主要知识点包括:1.指针与引用在概念上的三个区别及其在const.sizeof.自增运算上的差异:2.熟记经典swap函数的指针实现与引用实现,并能反映输出错误的两个函数的思想弊端:3.熟记GetMem函数的错误形式以及错误产生的原因:4.比较数组.指针与静态变量作为函数返回值的差异:5.str.*str以及&str三者

无效的指针、引用和迭代器

首先以示例代码为例: vector<int> v; //添加一些元素 fir(int i=0; i<10; ++i) v.push_back(i); int* my_favorite_element_ptr = &v[3]; cout<<"My favorite element = "<<(*my_favorite_element_ptr)<<endl; cout<<"Its address = &qu

C++指针和引用

 ★ 相同点: 1. 都是地址的概念: 指针指向一块内存,它的内容是所指内存的地址:引用是某块内存的别名.  ★ 区别: 1. 指针是一个实体,而引用仅是个别名: 2. 引用使用时无需解引用(*),指针需要解引用: 3. 引用只能在定义时被初始化一次,之后不可变:指针可变: 引用“从一而终” ^_^ 4. 引用没有 const,指针有 const,const 的指针不可变: 5. 引用不能为空,指针可以为空: 6. “sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针

More Effective C++----(1)指针与引用的区别 &amp; (2)尽量使用C++风格的类型转换 &amp; (3)不要对数组使用多态

Item M1:指针与引用的区别 指针与引用看上去完全不同(指针用操作符"*"和"->",引用使用操作符". "),但是它们似乎有相同的功能.指针与引用都是让你间接引用其他对象.你如何决定在什么时候使用指针,在什么时候使用引用呢? 首先,要认识到在任何情况下都不能使用指向空值的引用.一个引用必须总是指向某些对象.因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空

由指针和引用的区别引发的思考

指针和引用一直在用,但是却从来没有仔细思考过他们真正的区别在哪里,一直都是照本宣科的理解,引用就是变量的别名,引用确定后就不能修改,原因是什么呢? 现在就来弄清楚事情的真相, 区别究竟在哪里? 下面这段话应该可以从本质上来解释指针和引用的区别 程序在编译的时候分别将指针和引用添加到符号表上, 符号表上记录的是变量,以及变量所对应的地址, 指针变量在符号表上对应的地址为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值, 符号表生成后就不会再改,因此指针可以改变其指向的变量地址. 而

c++中通过指针或引用实现多态的本质!!

引言:  在c++中司空见惯的事情就是:可以通过指针和引用可以实现多态,而对象不可以.  那为什么?让我们来解开这神秘的暗纱! 1. 类对象的存储方式: 在一个类的实例中,只会存放非静态的成员变量. 如果该类中存在虚函数的话,再多加一个指向虚函数列表指针—vptr. 例如声明如下两个类,并分别实例化两个对象,它们的内存分配大致如下:(vptr具体在什么位置,与编译器有关,大多数都在开始处) class base { public: virtual ~base() {}; virtual stri

c++指针与引用问题

本来是回答问题的,到这里做个笔记 *&L是指针的引用,实参是个指针.所以L是实参指针的别名,对别名L的修改,等于对实参的修改.*L是传值,你无法改变传过来的实参指针变量的值程序代码: #include<iostream>using namespace std;void foo(int*p);int main(){    int a=5;    int *b=&a;    printf("%d %d\n",b,*b);    foo(b);    printf

(C/C++)区别:数组与指针,指针与引用

1.数组跟指针的区别 数组要么在静态存储区被创建(如全局数组),要么在栈上被创建.数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变. 指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存.指针远比数组灵活,但也更危险. 数组和指针特点的简单比较: 数组 指针 保存数据 保存地址 直接访问数据 间接访问数据,先取得指针的内容,然后以它为地址取得数据 用于存储数目固定且类型相同的数据 通常用于动态数据结构 编译器自动分配和删除