一、变量与指针
1.定义
指针(指针变量)
1).一种数据类型
2).用来存放地址的变量
2.指针的声明
数据类型标识符 *指针变量名
例如:
int *p_iPoint; //声明一个整形指针
float *a; //声明一个浮点指针
3.指针的声明
1).初始化时赋值
int i = 100;
int *p_iPoint = &i;
2).后期赋值
int i = 100;
p_iPoint = &i;
ps:通过变量访问变量是直接的,通过指针访问变量是间接的
4.关于指针使用的说明
1).指针变量名是p,不是*p
p=&i:去变量i的地址赋给指针变量p
下面的代码可以获取变量的地址,并将地址输出
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a = 100;
int *p = &a;
printf("%d\n",p);
return 0;
}
ps1:变量是由系统分配空间,所以地址不是固定的
ps2:指针一定要赋值,否则可能会产生隐藏的后果
2).指针不可以直接赋值
int a = 100;
int *p;
p = 100;//编译会出错
如果强行赋值,使用*提取指针所指变量时会出错
int a = 100;
int *p;
p=(int*)100;
printf("%d",p);
printf("%d",*p);//出错语句
3).不能将*p当变量使用
int a = 100;
int *p;
*p = 100;
printf("%d",p);//地址 出错语句
printf("%d",*p)//指向的值 出错语句
二.指针运算符与取地址符
1.简介
*是指针运算符,&是取地址运算符
星号表示的是通过地址取值
&表示的是取地址
举个栗子:
输出指针对应的数值
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a = 100;
int *p = &a;
cout << "a=" << a <<endl;
cout <<"*p=" << *p <<endl;
}
2.说明
声明指针变量时用到了*和&两个运算符
int *p = &a
该语句等同于:
int *(p = &a)
ps:&*p中的p只能是指针变量,如果将星号放在变量名前,会有逻辑错误
举个栗子:
#include <iostream>
#include <cstdio>
int main()
{
int a = 100;
int *p;
printf("%d",&*a);
return 0;
}
以上程序会出现编译错误
三、指针运算
我们知道,指针存的是地址,所以对指针做运算就等于对地址做运算
举个栗子:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a = 100;
int *p = &a;
printf("%d\n",p);
p++;
printf("%d\n",p);
p--;
printf("%d\n",p);
p--;
printf("%d\n",p);
}
程序输出的结果为:
7339540
7339544
7339540
7339536
ps:如果运行结果不同,不代表代码有问题,而是存储地址不同
好,我们发现,指针做一次+1运算,其地址居然增加了4!!这是咋肥事儿?
其实这和指针的声明类型有关,地址虽然是按字节存放数据,但指针+1并不代表地址值增加一个字节,而是+数据类型的字节宽度,想要获取int型的字节宽度,得用sizeof关键字才行。sizeof(int)=4,sizeof(double)=8
**总结:**定义指针时必须指定一个数据类型,其类型指定其所指变量的类型
四、指向空的指针和空类型指针
指针可以接受任何类型的数据,包括空类型
空指针赋值后,才可以转换为对应类型的指针以达到我们所期望的效果。若将其转化为其他类型的指针,得到的结果将不可预知,非空类型指针同样具有这样的特性。NULL表示的是空值,空值无法用输出表示,而且赋空值的指针不能使用,直到被赋予其他的值。
五、指向常量的指针与指针常量
同其他数据类型一样,指针也有常量,如下:
int i = 9;
int *const p = &i;
*p = 3;
将const放在标识符前,表示这个数据本身是常量,而数据类型是int*,即整形指针。与其他常量一样,指针常量必须初始化。我们无法改变它的内存指向,但可以改变其指向的内容