C/C++指针看这一篇文章就够了,千字总结附带案例和源代码块!

56 篇文章 0 订阅
35 篇文章 0 订阅

指针——指针的定义与使用

作用:可以通过指针间接访问内存

  1. 内存编号是从0开始记录的,一般用十六进制的数字表示
  2. 可以利用指针变量保存地址

语法:数据类型*变量名

可以通过指针来保存一个地址

通俗来说指针就是一个地址

#include <iostream>
using namespace std;
int main()
{
    int a = 10;
    int* p = &a;
    cout << p << endl;
    return 0;
}

这样输出的p就是内存编码

可以通过解引用的方式来找到指针所指向的内存(指针前加*代表解引用,找到指针指向的内存中的数据)

输出*p就是p指向的变量a的值

我们还可以通过指针间接找到并且修改内存

#include <iostream>
using namespace std;
int main()
{
    int a = 10;
    int* p = &a;
    *p = 100;
    cout << a << endl;
    return 0;
}

我们通过修改*p发现a的值也变化了,我们可以联想到我们函数值传递的特点(实参不变),那指针能不能传递能不能改变实参呢?后面会提到

指针所占用的内存空间

指针同样前面定义了数据类型,那指针的所占内存和前面定义的数据类型有关嘛?

当然没有关系!

  • 在32位操作系统中,指针占4个字节
  • 在64位操作系统中,指针占8个字节

指针所占内存大小与数据类型没有关系!

#include <iostream>
using namespace std;
int main()
{
    int a = 10;
    int* p = &a;
    *p = 100;
    cout << sizeof(p) << endl;
    return 0;
}

空指针

定义:指针变量指向内存中编号为0的内存空间

用途:初始化指针变量(在我们不确定这个指针指向谁的时候可以先指向0)

空指针指向的内存无法访问

因为0-255时系统占用的内存编号,我们没有权限进行访问

定义方法:

#include <iostream>
using namespace std;
int main()
{
    int* p = NULL;
    return 0;
}

野指针与垂悬指针

野指针:指针变量指向非法的内存空间

空指针和野指针都不是我们申请的内存空间,因此不要访问

垂悬指针是一个正常的指针,但是其指向的对象以及被销毁,指针却没有制空

关于野指针的知识将在栈区相关知识中介绍

const修饰指针

const修饰指针存在有三种情况

  1. const修饰指针——常量指针
  2. const修饰变量——指针常量
  3. const修饰指针和变量

注意: p是地址,*p才是值

//常量指针
//指针的指向可以修改,就是可以指向别的内存,但是解引用的值一定是a的值无法修改
const int *p = &a;
//指针常量
//指针的指向不可以修改,即只能指向a的内存空间,但是指向内存空间的值可以修改
int * const p = &a;
//俩个都修饰那就两个都不能改

小技巧:看const右侧紧跟的是值还是地址!

指针与数组

作用:利用指针去访问数组中的元素

#include <iostream>
using namespace std;
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
    //数组名代表的就是整个数组的首地址
    int* p = arr;
    for (int i = 0; i < 10; i++)
    {
        //+i代表往后i个元素的内存空间进行解引用,从而达到遍历输出数组的作用
        cout << *(p + i) << " ";
    }
    cout << endl;
    return 0;
}

指针与函数

作用:利用指针作为函数参数,可以修改实参的值(地址传递)

(值传递无法修改实参的值)

#include <iostream>
using namespace std;
void swap(int* p1, int* p2)
{
    int temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}
int main()
{
    int a = 10;
    int b = 20;
    swap(&a, &b);
    cout << a << endl;
    cout << b << endl;
    return 0;
}

值传递不改变实参的原因是另外开辟了内存是存放值传递之后的值与变量,原先值所在的内存空间没有受到更改

而地址传递传入的是地址,直接修改地址,间接改变了实参

地址传递和值传递各有优劣,具体需求具体分析

经典案例

需求案例:封装一个函数,利用冒泡排序,实现对整型数组的升序排序

思路:

  1. 循环输入,并且将输入的数保存进一个足够大容量的数组中
  2. 封装冒泡排序函数
  3. 进行地址传递,在主函数中输出排序后的结果
#include <iostream>
using namespace std;
void sort(int* p,int count)
{
    for (int i = 0; i < count - 1; i++)
    {
        for (int j = 0; j < count - i - 1; j++)
        {
            if (*(p + i) > *(p + i + 1))
            {
                int temp = *(p + i + 1);
                *(p + i + 1) = *(p + i);
                *(p + i) = temp;
            }
            else
            {
                continue;
            }
        }
    }
}
int main()
{
    cout << "输入666并回车即可开始对以及输入的数字进行排序" << endl;
    int arr[100];
    int ch;
    cin >> ch;
    //设置一个计数变量方便存放数据进数组
    int count = 0;
    while (ch != 666)
    {
        arr[count] = ch;
        count++;
        cin >> ch;
    }
    //arr就代表首地址
    sort(arr,count);
    //count代表数组中有多少个数字
    for (int i = 0; i < count; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
    return 0;
}

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宴师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值