指针的含义其实是好理解的,容易混淆的地方主要来自于(*)星号的使用和实参形参的作用域。这的确引起了一些不好理解(极易混淆)的地方。
最好的办法就是动手写:
(来自)
1
int andy = 25;
int fred = andy;
int * ted = &andy;
cout << andy << endl;
cout << fred << endl;
cout << ted << endl;
cout << * ted << endl;
结果:
25
25
0x7fff560d99e8(对应图中的地址1776)
25
上图其实已经一目了然了,唯一容易引起混淆的地方,就是指针的声明处,int * ted = &andy。这里的星号其实可以将其看成(int *)作为类型声明的一部分,它与ted无关。声明处的星号,仅仅代表ted这个变量是个指针类型。而后面在使用ted这个变量的时候,就必须记住ted代表的是ted,而*ted代表的是“取出ted的值然后根据这个值去获取另一个变量的值”。
2
void pointer(int *p) {
int a = 11;
*p = a;
p = &a;
}
int main() {
int b = 22;
int *p = &b;
cout << p << endl;
cout << *p << endl;
pointer(p);
cout << p << endl;
cout << *p << endl;
return 0;
}
结果:
0x7fff5caa79e8
22
0x7fff5caa79e8
11
可以看出,函数内的作用域依然是有效,函数内对参数的修改不会影响函数外,因为传递的只是一个拷贝,但此处该拷贝是一个指针,并没有拷贝指针的指向地址上的值,因此如果在函数内对指针本身作修改,函数外无效;但在函数内对指针指向地址的值作修改,函数内外都会有效。
3
引用和指针很类似,容易混淆的地方也相同,都在于声明和参数传递。而实际上引用就是一种特殊的指针,特殊之处就在于引用是作为一种别名的存在,在使用上也会有很大不同。
简要来说,就是(&)与符号在定义时(它只有定义不允许只声明)是作为一种符号类型标识代表引用类型,而其他地方使用就是作为取地址的操作。
需要注意的地方就是,在参数传递的时候
void pointer(int &p) {
int a = 11;
p = a;
}
int main() {
int b = 22;
int &p = b;
cout << p << endl;
cout << &p << endl;
cout << &b << endl;
pointer(p);
cout << p << endl;
return 0;
}
结果:
22
0x7fff523989e8
0x7fff523989e8
11
可以看出,引用取的地址和其值的地址是相同的,如果它在函数内被修改,那么其对应的值也会被修改。但这种方式不会产生副本,因为引用传递的还是地址。