请看此例,使用vc6.0
#include "stdafx.h"
#include<iostream>
using namespace std;

void swap2(int& a,int& b);//声明;引用
void swap3(int* a,int* b);

void swap2(int& a,int& b)//定义;引用

...{
int temp=a;
a=b;
b=temp;
};

void swap3(int* a,int* b)

...{
int p=*a;
*a=*b;
*b=p;
}

int main(int argc, char* argv[])

...{

/**/////////////////////////////////////////////////
int a=2,b=10;
cout<<a<<","<<b<<endl;
//swap2(&a,&b);//不可以
swap2(a,b);//引用
//swap2(a+1,b);//不可以
cout<<a<<","<<b<<endl;

int *pa,*pb;
pa = &a;//地址
pb = &b;
cout<<*pa<<","<<*pb<<endl;
//swap2(pa,pb);//不可以(a)
swap2(*pa,*pb);//引用
cout<<*pa<<","<<*pb<<endl;

/**//////////////////////////////////////////////////

int c=6,d=3;
cout<<c<<","<<d<<endl;
swap3(&c,&d);//地址
cout<<c<<","<<d<<endl;


int *pc,*pd;
pc = &c;//地址
pd = &d;
cout<<*pc<<","<<*pd<<endl;
swap3(pc,pd);
//swap3(pc+1,pd);//(b)可以编译通过,但显然错误而危险,可以和(a)对比
cout<<*pc<<","<<*pd<<endl;


/**///////////////////////////////////////////////////////

c =23;d=67;
//int &e,&f;//不可以,引用变量必需初始化
int &e=c,&f=d;//引用;可以理解为e是c的别名

cout<<e<<","<<f<<endl;
swap2(e,f);
cout<<e<<","<<f<<endl;

cout<<e<<","<<f<<endl;
swap3(&e,&f);//地址
cout<<e<<","<<f<<endl;

return 0;
}

由上,我的个人经验:
//在声明和定义中使用“&”时,是引用;在执行代码中使用“&”时,是地址。
//不过对于如下语句:
//int *pc = &c;
//依然是地址。因为这个初始化动作也是执行代码。
//其实引用、地址以及指针关系很紧密的。像int & a,const int *p, int *const p, const int * const p以及
//HANDLE句柄等,都可以理解为限制对指针的操作,以避免指针的弊端。
//由(a),(b)处可以看出引用要安全些。
//请指正。