内存->字节数组->字节->位
内存中的每个位置都由一个独一无二的地址表示
内存中的每个位置都包含一个值
我们可以通过一个地址,找到内存中的某个具体位置,然后访问到该位置的值(允许的话)
指针是一个其值为地址的变量(存储地址的变量)
&取址运算符 :当它后面跟一个变量名的时候,给出这个变量名的地址
int a=1;cout<<"Address of a:"<<&a<<endl;
*间接访问运算符/解引用指针:当它后面跟一个指针的时候,得到指针指向的内存中的内容
int a =1;cout<<"a:"<<*(&a)<<endl;
ANSI专门为指针提供了%p输出格式
声明指针的模板:
指向地址的数据类型 * 指针变量名;(int a;)
号表明现在创建的是一个指针类型的变量。
指针可以赋值给同类型指针
指针赋值
int a =1;
int *p = NULL;
p = &a;
cout<<*p;
NULL(整型0),表示不指向任何东西的指针
尝试对NULL指针取值(解引用)会导致程序崩溃,所以最好在取值之前加一个NULL指针判断
尽量定义了对象之后再定义指向这个对象的指针,对于不清楚的指向哪里的指针,先初始化为nullptr(C++11)或NULL(0),之后再判断是否指向对象再进行相应的操作
void *是一种特殊类型的指针,能够用来存放任何类型对象的地址,通俗的说,就是我不知道这个指针指向的是什么类型的对象
void *p_void=NULL;
int *p=NULL;
p_void = p ;
指针的指针
int a =10;//变量
int *p_a=&a;//指针,存的是变量的地址
int **pp_a=&p_a;//指针的指针,存的是指针的地址
指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用只不过是变量的一个别名而已。
指针的值可以为空,也可能指向一个不确定的内存空间,但是引用的值不能为空,并且引用在定义的时候必须初始化为特定对象;
指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不可以改变引用对象了;
指针可以有多级,但是引用只能是一级;
sizeof引用得到的是所指向的变量(对象)的大小,而sizeof指针得到的是指针本身的大小;
数组
数组是一坨类型相同的数据排列在一起组成的,因为每个元素占用的字节数相同,所以根据一个元素的序号就可以计算出它在内存中的位置,所以数组元素可以用序号来访问。
int i,*pa,a[]={3,4,5,6,7,3,7,4,4,6};
pa =a ;//请注意数组名a(数组名a就是数组a的首地址,数组名是一指针常量)直接赋值给指针 pa
for (i=0;i<=9;i++)
{
printf ( “%d”, *(pa+i) );//指针pa存储的地址并未发生改变
}
for (i=0;i<=9;i++)
{
printf ( “%d”, *pa);
pa++;//改变指针存储的地址
}
指针常量(指向的地址不会改变)
int * const p=a;