- 1 NULL
#define NULL ((void *)0)
When
NULLis assgined to a pointer, it means the pointer does not point to anything.
- 2 void*
void *pv;
A pointer to void is a general-purpose pointer used to hold references to any data type.
Constants and Pointers
1 pointers to a constant
初始代碼:
int a = 2;
const int b = 4;
const int* pci;
pci = &b;
調(diào)試分析:
- pci可以改變自身的值,即指向另一個(gè)變量
pci = &a;
- *pci不允許改變指向的變量的值
*pci = 8; //error: assignment of read-only location ‘* pci’
pci可以指向一個(gè)int或一個(gè)const int
pci的下述定義是等價(jià)的
const int *pci;
int const *pci;
簡(jiǎn)單圖
- 灰色表示不可通過(guò)指針的反引用改變變量的值

2 constant pointers to nonconstant
初始代碼
int a = 2;
const int b = 4;
int c = 6;
int* const cpi = &a;
調(diào)試分析
- cpi必須在聲明時(shí)就被初始化,否則會(huì)有如下報(bào)錯(cuò)
int* const cpi; //error: error: uninitialized const ‘cpi’
cpi = &a; //error: assignment of read-only variable ‘cpi’
- cpi不能指向constant int
int* const cpi = &b; //error: invalid conversion from ‘const int*’ to ‘int*’
- cpi不能改變自身的值,即在初始化后,不能指向另一個(gè)變量
cpi = &c; //error: assignment of read-only variable ‘cpi’
- *cpi可以改變所指向的變量的值
*cpi = 8;
簡(jiǎn)單圖

3 constant pointers to constants
初始代碼:
int a = 2;
const int b = 4;
const int* const cpci = &b;
調(diào)試分析:
cpci必須在聲明時(shí)被初始化,否則會(huì)報(bào)錯(cuò)
cpci自身的值不允許被修改,即在初始化后不能指向另一個(gè)變量
*cpci不允許修改所指向變量的值
cpci可以指向一個(gè)int或是const int
簡(jiǎn)單圖

4 pointer to constant pointer to constant
初始代碼:
const int b = 4;
const int* const cpci = &b;
const int* const* pcpci = &cpci;
調(diào)試分析:
cout<<**pcpci<<endl; // 4
簡(jiǎn)單圖

& v.s. *(引用 v.s. 指針)
引用:就是某一變量(目標(biāo))的一個(gè)別名,對(duì)引用的操作與對(duì)變量直接操作完全一樣。
1 傳參
- 引用傳參
#include <iostream>
void add(int& sum, int a, int b)
{
sum = a + b;
}
int main()
{
int a=3;
int b=4;
int c;
add(c, a, b);
std::cout<<c<<std::endl;
return 0;
}
output:
7
- 指針傳參
#include <iostream>
void add(int* sum, int a, int b)
{
*sum = a + b;
}
int main()
{
int a=3;
int b=4;
int c;
add(&c, a, b);
std::cout<<c<<std::endl;
return 0;
}
- 兩種傳參方式區(qū)別
- 使用引用傳遞函數(shù)的參數(shù),在內(nèi)存中并沒(méi)有產(chǎn)生實(shí)參的副本,它是直接對(duì)實(shí)參操作;
- 使用指針作為函數(shù)的參數(shù)雖然也能達(dá)到與使用引用的效果,但是,在被調(diào)函數(shù)中同樣要給形參分配存儲(chǔ)單元
2 常引用
初始代碼:
int a=3;
const int& rci = a;
調(diào)試分析:
- rci在初始化后就不能再被賦值了,但a仍可以被賦值
rci = 1; //error: assignment of read-only reference ‘rci’
a = 1; //that's okay.
傳參常引用:
#include <iostream>
int add(int& a, int& b)
{
return a+b;
}
int main()
{
int a=3;
int b=4;
int c=add(a, b);
return 0;
}
- 上述代碼是正確的,只是沒(méi)什么意義,純屬為了測(cè)試。若在main函數(shù)加入
int d=add(3, 4); //error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
則將報(bào)錯(cuò)。那是因?yàn)?code>int&的引用應(yīng)該是變量,而不能是常數(shù)。
- 為了能處理常數(shù)的情況,可以改下add函數(shù)
int add(const int& a, const int& b)
{
return a+b;
}
這樣,就可以了。除了能處理常數(shù)外,還有一個(gè)好處是,由于是常引用,故在該add函數(shù)內(nèi)部不能改變a, b的原始值,更安全了。
3 引用作為返回值
#include <iostream>
const int& max(const int& a, const int& b)
{
return a>b ? a:b;
}
int main()
{
int a=3;
int b=4;
int c=max(a, b);
std::cout<<c<<std::endl;
return 0;
}
- output:
4
- 用引用返回一個(gè)函數(shù)值的最大好處是,在內(nèi)存中不產(chǎn)生被返回值的副本。
不能返回局部變量的引用。主要原因是局部變量會(huì)在函數(shù)返回后被銷毀,因此被返回的引用就成為了"無(wú)所指"的引用,程序會(huì)進(jìn)入未知狀態(tài)
再看下另一個(gè)例子:
#include<iostream>
int ga;
int double_1(int a)
{
ga = 2*a;
return ga;
}
int& double_2(int a)
{
ga = 2*a;
return ga;
}
int main()
{
int a=2;
int& b=double_2(a);
b = 8;
std::cout<<ga<<std::endl;
return 0;
}
Output:
8
若在main中加上
int& b = double_1(a); //error: invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’
將報(bào)錯(cuò)。因?yàn)?strong>double_1()函數(shù)返回的只是一個(gè)常數(shù)值,在C++中,任何臨時(shí)變量都是常數(shù)值const,而int&引用的不能是常數(shù)值;但在double_2()函數(shù)中,函數(shù)返回的是ga,使得b引用它.
4 引用的其他特性
- 傳遞性
#include <iostream>
int main()
{
int a=3;
int& b=a;
int& c=b;
c = 5;
std::cout<<a<<std::endl;
return 0;
}
Output:
5
- int* &(指針引用) int* const&(指針常引用)
#include <iostream>
int main()
{
int a=3;
int* pi=&a;
int*& rpi = pi;
int* const& rcpi=&a;
*rcpi = 6;
std::cout<<a<<std::endl;
return 0;
}
Output:
6
int*& rpi=&a; //error:因?yàn)?amp;a為常量
- read more
**覓思.澈**同學(xué)的[C++引用詳解](http://www.cnblogs.com/gw811/archive/2012/10/20/2732687.html)