C++指针小结
指针是一个变量,其存储的是值的地址,而不是值本身。对于常规变量的地址,只需要对变量应用地址运算符(&),就可以获得它的位置;如:home是一个变量,则&home是它的地址。使用常规变量时,值是指定的量,而地址是派生量。
面向对象编程与传统的过程性编程的区别在于,OOP强调的是在运行阶段(而不是编译阶段)进行决策。运行阶段指的是程序在运行时,编译阶段指的是编译器将程序组合起来时。总之,使用OOP时,可能在运行阶段确定数组的长度。
声明指针
要声明指向特定类型的指针,请用以下格式:
typeName * pointerName;
如下:
double * pn; //pn是指向double类型的指针
char * pc; //pc是指向char类型的指针
其中 * 两边有无空格均可。
给指针赋值
应将内存地址赋值给指针。可以对变量名应用&运算符,来获得被命名的内存的地址,new运算符返回未命名的内存地址。
下面是一些实例:
double * pn
double * pa
char * pc
double bubble =3.2
pn = &bubble
pc = new char
pa = new double[30]
对指针解除引用
对指针解除引用意味着获得指针指向的值。对指针应用解除引用或间接值运算符()来解除引用。因此,像上面的例子那样,pn是指向bubble的指针,则pn是指向的值,即3.2
如下:
cout<< *pc;
pc = ‘s’;
另一种对指针解除引用的方法是使用数组表示法,例如pn[0]与pn是一样的。绝不要对未被初始化为适当地址的指针解除引用。
区分指针和指针所指向的值
如果pt是指向int的指针,则*pt不是指向int的指针,而是完全等同于一个int类型的变量。pt才是指针。
如下:
int * pt = new int;
*pt = 5;
数组名
在大多数情况下,C++将数组名视为数组的第一元素的地址。
如下:
int tacos[10];
则tacos=&tacos[0],一种例外情况是将sizeof运算符用于数组名时,此时返回整个数组的长度(单位为字节)
如:
#include <iostream>
using namespace std;
int main() {
double wages[3] = {10.0, 10.0, 10.0};
double * pn = wages;
cout<< sizeof(wages)<<endl;
cout<< sizeof(pn)<<endl;
}
24
4
此时C++不会将数组名解释为地址。
指针算术
C++允许将指针和整数相加。加1结果为原来的地址值加上指向的对象占用的总字节数。还可以将一个指针减去另一个指针,获得两个指针的差。后一种运算将得到一个整数,仅当两个指针指向同一个数组(也可以指向超出结尾的一个位置)时,这种运算才有意义;这将得到俩个元素的间隔。
如下:
#include <iostream>
using namespace std;
int main() {
int tacos[10] = {1,2,34,4,5,7,6,1,3,5};
int *pt = tacos;
pt = pt + 1;
int *pe = &tacos[9];
pe = pe-1;
int diff = pe - pt;
cout<<"pt is "<<pt<<endl;
cout<<"pe is "<<pe<<endl;
cout<<"diff is "<<diff<<endl;
}
pt is 0x61fef0
pe is 0x61ff0c
diff is 7
数组的动态联编和静态联编
使用数组声明来创建数组时,将采用静态联编,即数组的长度在编译时设置:
int tacos[10];
使用new运算符创建数组时,将采用动态联编,即将在运行时为数组分配空间,其长度也将在运行时设置。使用完这种数组后应使用delete[]释放内存。
int size;
cin >> size;
int * pz = new int [size];
…
delete [] pz;
数组表示法和指针表示法
使用方括号数组表示法等同于对指针解除引用:
tacos[0]=tacos
tacos[3]=(tacos+3)
数组名和指针变量都是如此,因此对于指针和数组名,既可以用指针表示法,也可以用数组表示法。
int *pt = new int [10];
*pt=5;
pt[0]=6;
pt[9]=44;
int coats[10];
*(coats+4) = 12;
上一篇: c++指针小结
下一篇: django中的bug(持续更新)