本文章对C++指针的使用做一个全面的阐述与解释
1.1指针的定义使用
指针: 通过指针间接访问内存
指针就是地址
看下面代码:
#include<iostream>
using namespace std;
int main(){
//1、定义指针
int * p;
int a = 10;
//2、使用指针
p = &a;
cout<<"a的地址为: "<<&a<<endl;
cout<<"p的值为: "<<p<<endl;
cout<<"*p的值为: "<<*p<<endl;
return 0;
}
~
上述代码利用取地址运算符得到a的地址;并打印p的值,二者结果相等;因此p=&a;p就代表了a的地址;再通过解引用的方式来找到指针指向的内存:*p
因此之后可以通过操作 *p而间接操作a,也就是说改变 *p的值,a的值也会随之改变。
1.2指针所占内存空间
虽然指针指向的是内存地址,但指针本身需要地址去存储,但类型特殊,用多大内存去存储呢?
公认下,在32位操作系统下,占用4个字节空间;64位下占8个字节空间。大部分都是32位,因此该情况位默认。
C++中利用sizeof()函数查询数据类型占多大空间,如下:
cout<<"---------------------------"<<endl;
cout<<"sizeof(p) = "<<sizeof(p)<<endl;
cout<<"sizeof(int *) = "<<sizeof(int*)<<endl;
cout<<"sizeof(*p) = "<<sizeof(*p)<<endl;
cout<<"sizeof(int) = "<<sizeof(int)<<endl;
cout<<"sizeof(float) = "<<sizeof(float)<<endl;
p是int类型的数据,结果得,目前是64位操作系统,指针占8个字节空间。
顺便看了看p,此时与int类型相同,证明了第一节中说的 * p 代表a的说法。对于64位操作系统,无论什么类型指针,都占8个字节内存(char* ;double*;float*;int*)
1.3 空指针和野指针
空指针: 指针变量指向内存中编号为0的空间
用于指针的初始化;空指针指向的内存是不能访问的
0-255是系统内存,不允许访问
**野指针: ** 指针变量指向非法的内存空间
指针指向了一片没有开辟的内存。语法没有错误,但无法运行。
所以空指针和野指针都不是我们申请的内存,因此不要访问
1.4 const修饰指针
1.常量指针 ------ const int *p = &a
指针的指向可以修改,但指针指向的值不可以修改;
即p现在指向a的地址,现在可以将p指向另一个变量地址,这个操作允许;但p指向a的地址,a的值不允许更改!
2.指针常量 -----int *const p = &a
指针的指向不可以修改,但指针指向的值可以修改;
即p现在指向a的地址,现在可以修改a的值,这个操作允许;但不可以将p的指向修改,即指向别的指针!
3.const即修饰指针,又修饰常量 ----const int* const p = &a;
指针的指向不可以修改,指针指向的值也不可以修改
1.5 指针和数组
这里说的是,数组名代表得就是数组首地址,而指针p指向的也是地址,因此可以将指针直接指向数组,表示数组的第一个值
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
cout<<*p<<endl;
//结果是1
p++;
//表示指针向后移动四个字节
cout<<*p<<endl;
//结果是2
1.6 指针和函数
函数参数传递,如果是值传递,函数内部修改不会影响主函数的参数值;如果想要在函数内部修改影响到外面主函数中的参数值,就要给函数传递参数的地址(&),之后函数参数类型为指针,表示用指针去接受传入的地址,然后指针解引用访问参数值,因为直接访问的是地址,因此主函数值也会改变