指针
什么时候要用到指针?
这里是引用
1:当你要获取地址的时候,你必须要用指针.
2:当在传递参数时多数要使用指针.
3:当在动态分配地址时要使用指针.
4:在链表时需要使用指针.
5:指针可以指向计算机的任何一个位置.
6:指针有一个最大的特点,就速度快.
指针可以间接访问内存
可以理解为指针就是地址
1.指针的定义和使用
(1).定义一个指针:
int a=10; //定义数据类型int
//指针定义的语法: 数据类型 + * 指针变量名
int *p;//记录变量a的地址
p=&a; //&为取址符号
cout << p<< endl;
(2).使用指针:
通过解引用的方式
指针前加*找到指针指向的内存中的数据
int a=10; //定义数据类型int
//指针定义的语法: 数据类型 + * 指针变量名
int *p;//记录变量a的地址
p=&a; //&为取址符号
cout << p<< endl;
cout<<*p<<endl;
结果如下:
2.指针所占内存空间
32位操作系统中 指针占4个字节
64位操作系统中 指针占8个字节
3.空指针和野指针
(1)空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可访问的
内存编号0~255是系统所占用的,不允许用户访问
int *p=NULL;
cout<<p<<endl;
cout<<*p<<endl;
return 0;
数据无法显示。
int *p=NULL;
*p=100;
cout<<p<<endl;
cout<<"p指针指向空间的数据"<<*p<<endl;
return 0;
编译成功但是无法运行。
(2)野指针:指针变量指向非法的内存空间
int *p=(int *)0x1111;//0x1111强制转换为指针类型
cout<<p<<endl;//指向的空间
cout<<"p指针指向空间的数据"<<*p<<endl;
return 0;
结果*p是无法访问的 因为没有权限访问
在程序中尽量避免野指针的出现
3.const修饰指针
(1)const修饰指针——常量指针
(2)const修饰常量——指针常量
(3)const即修饰指针又修饰常量
(1)常量指针:
这个时候没有使用const 接下来使用const修饰:
出现报错
如果我们修改一下指针的方向 不指向a 指向b
p=&b;
可以正常进行;
常量指针的特点就是 指针指向可以修改 但是指针指向的值不可以修改
(2)指针常量
指针常量的特点是指针方向不能修改,指针的内容可以修改
(可以修改a的值)
(不可以修改指针的方向)
(3)即修饰指针又修饰常量
特点:指向和指向的值都不能改变
这个类型就是前两种的结合 指针的指向和指向的值都不能改变。
4.指针和数组
利用指针来访问数组中的元素
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int len=sizeof(arr)/sizeof(arr[0]);//求一个数组的长度
int *p=arr;//arr数组名就是数组的首地址
for(int i=0;i<len;i++)
{
cout<<*p<<endl;
p++;
}
}
运行结果如下:
5.指针和函数
以前学习的值交换是值传递:
void swap1(int a,int b)
{
int num=a;
a=b;
b=num;
cout<<"swap1中的a"<<a<<endl;
cout<<"swap1中的b"<<b<<endl;
}
int main()
{
int a=100;
int b=200;
swap1(a,b);
cout<<a<<endl;
cout<<b<<endl;
}
结果中swap1函数中的ab值交换 形参改变但是实参没有改变。
void swap2(int *p1,int *p2)
{
int num=*p1;
*p1=*p2;
*p2=num;
}
int main()
{
int a=100;
int b=200;
swap2(&a,&b);
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
}
此时是地址传递,运行后结果为:
可以看出来实参也被修改