阅读耗时大概 4 分钟

指针是干什么的

我们可以通过指针间接访问内存
可以用指针变量保存地址

指针是如何定义和使用的

指针变量定义的语法: 数据类型 * 变量名
我们来看下下面这张图:
指针.png
首先我们声明了a = 10,它在内存中的地址是0x0001, 值是10,如果我们想要获取内存地址,可以用 &a,但是如果我们想要操作这块内存,如何办。我们可以声明一个p变量,指向这块地址 0x0001。
这个p就是指针变量。定义方式 为 int p = a
那你有可能会问,怎么用指针,记住一点,**加
就代表解引用,代表指针指向的内存,p指向内存地址,p指针指向的内存地址 解开就是值*
解引用.PNG
示例

  1. #include<iostream>
  2. using namespace std;
  3. int main(){
  4. int a = 10;
  5. int *p = &a;
  6. int *b ;
  7. b = &a;
  8. cout <<"a == " << a << endl;
  9. cout << "&a == " << &a << endl;
  10. cout << "p == " << p << endl;
  11. cout << "*p == " << *p << endl;
  12. cout << "b == " << b << endl;
  13. cout << "*b == " << *b << endl;
  14. *p = 20;
  15. cout << "a == " << a << endl;
  16. return 0;
  17. }
  18. 结果
  19. a == 10
  20. &a == 0x61fe0c
  21. p == 0x61fe0c
  22. *p == 10
  23. b == 0x61fe0c
  24. *b == 10
  25. a == 20

指针占用空间大小

猜猜指针这种数据类型占用多少内存空间呢?

#include<iostream>
using namespace std;
class Person{
    int a;
};
int main(){
    int a = 10;
    int *p = &a;
    cout << sizeof(p) << endl;
    cout << sizeof(int *) << endl;
    cout << sizeof(char *) << endl;
    cout << sizeof(float *) << endl;
    cout << sizeof(double *) << endl;
    Person *pp ;
    cout << sizeof(pp) << endl;
}
结果是
8
8
8
8
8
8

我电脑是 64 位操作系统 ,所以是8个字节,如果是 32 位操作系统,是 4 个字节

空指针

空空如也的指针,指针是空的?
空指针是指 指向内存中编号为0的空间,用来初始化指针变量,但是空指针指向的内存是不可以访问的。你就想想java 对象是null的情景吧

#include<iostream>
using namespace std;

int main(){
    int *p = NULL;
    cout << p << endl;  //这一行输出 0 ,内存编号是 0 
    cout << *p << endl;  //我用vscode 运行 并没有报错 只是终端上一直卡着 ,说明不允许访问
    *p = 100;  //内存编号 0 到 255 为系统占用内存,不允许用户访问
    return 0;
}

野指针

这孩子真野
指针变量指向非法的内存空间

#include<iostream>
using namespace std;

int main(){
    int *p = (int *)0x1100;//指针变量p指向内存地址0x1100空间 

    cout << *p << endl;  //vscode 运行卡了一会终止了,什么也没有输出,一些编辑器会报错哟,读写访问冲突
    return 0;
}

为什么说 p 是野指针,p指向的地址是自己申请的吗?不是,p有权利操作吗?我并不知道,没有人说它有权利操作这块空间。

Const修饰指针

直接看例子

  1. 常量指针

const 修饰指针
指针的指向可以修改,但是指针指向的值不能修改

int a = 10;
const int *p = &a;  //const 放在指针前面,修饰指针,叫指针常量

*p = 20;
执行结果 报错

int b = 20;
p = &b;
执行正确
  1. 指针常量

const修饰常量
指针的指向不可以修改,但是值可以修改

int a = 10;
int * const p = &a;  //const 放在常量前面

*p = 20;
执行结果
正确

int b = 20;
p = &b;
执行报错
  1. const修饰常量和指针

指针的指向和指针指向的值都不可以修改

int a = 10;
const int * const p = &a;

总结
const放在 指针(int )前面叫 常量指针,说明指针是常量,常量就不能改咯,就是指针指向不能改咯。
const放在指针(int
)后面, 变量(p)前面,叫指针常量,const修饰的是变量(p), 说明这个变量值不能改变。
const修饰什么,什么就不能改。

指针和数据

来一个指针访问数组元素例子

#include<iostream>
using namespace std;

int main(){
    int arr[] = {1,2,3,4,5,6,0,1,5,8};
    int *p = arr;//指向数组的指针
    cout << "第一个元素 " << arr[0] << endl;
    cout << "第一个元素 " << (*p) << endl;
    for(int i = 0; i< sizeof(arr) / sizeof(int);i++){
        cout << *p << "\t" ;
        p++;
    }
    cout << endl;
    return 0;
}

输出结果:
第一个元素 1
第一个元素 1
1       2       3       4       5       6       0       1       5       8

所以说指针指向的是 数组第一个地址,不信自己打印去

指针和函数

最大的好处,就是利用指针作函数参数,可以修改实参的值,也就是引用传递,之前普通函数那一章描述过值传递
把值传递代码copy 改一下 运行下示例

#include<iostream>
using namespace std;

void swap(int * a, int * b){
    cout << "a = " << *a << endl;
    cout << "b = " << *b << endl;
    int  temp = *a;  //只是交换值,可千万别定义 int * temp = a;来修改指向
    *a = *b;
    *b = temp;
    cout << "swap doned a = " << *a << endl;
    cout << "swap doned b = " << *b << endl;
}

int main(){
    int a = 10;
    int b = 20;
    swap(&a,&b); //传入引用
    cout << "global a = " << a << endl;
    cout << "global b = " << b << endl; 
    return 0;
}

输出结果:
a = 10
b = 20
swap doned a = 20
swap doned b = 10
global a = 10
global b = 20

来一个指针法冒泡

#include<iostream>
using namespace std;

void sort(int * arr, int len){
    for(int i = 0;i < len - 1;i++){
        bool isSorted = true;
        for(int j = 0;j < len - 1 - i; j++){
            if(arr[j] > arr[j+1]){
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                isSorted = false;
            }
        }
        if(isSorted){
            break;
        }
    }
}
int main(){
    int arr[] = {8 , 5, 3, 2, 4, 0, 9,1,4,6};
    int len = sizeof(arr) / sizeof(int);
    sort(arr, len);
    for(int i = 0;i < len; i++){
        cout << arr[i] << "\t";
    }
    cout << endl;
    return 0;
}

结果输出:
0       1       2       3       4       4       5       6       8       9