25/05/27(1202)指针

基本概念:

什么是内存

把内存想象成一个很长的大走廊

走廊上有很多房间,每个房间的大小是 1 byte

每个房间都有一个房间编号,编号从 0 开始算,依次累加(看到的房间号一般是比较大的数字),房间号就称为"地址".

指针也是一个变量,变量里存的就是一个整数,这个整数具有特定的含义,就是内存中的一个地址.

内存的特点:

1.内存支持随机访问. CPU在访问内存的时候,访问任何一个地址的数据的代价都非常低.

        int arr[1亿];访问 arr[0]和访问arr[1亿 - 1]效率是一样的

2.内存和外存.

        a)访问速度:访问内存 ns 速度快,访问外存 um 速度慢(慢3 - 4个数量级)

        b)容量:内存的容量小,外存容量大

        c)成本:内存成本高,外存成本低

        d)断电:内存断电后数据就没了,外存断电数据还在

可以创建一个变量 p ,用来保存 num 的地址.此时 p 这个变量就是指针变量.

p 的类型叫做 int* ,指针是一个统称.int* ,char* ,double* 都算指针.

#include <stdio.h>
#include <stdlib.h>

int main(){
    int num = 10;//变量的创建过程就是对内存的申请
    int* p = &num;
    //下面括号里的 * 是间接访问操作符/解引用运算
    printf("%d\n",*p);
    system("pause");
    return 0;
}

内存必须先申请才能使用,没申请不能用.如果强行使用未申请的内存就会出现访问非法内存的情况,这这是一种常见的"未定义行为".

C/C++要着重注意这种情况,Java中如果访问非法内存JVM都能检测出来,通过抛出异常及时通知.

包含一个非法地址的指针,叫做"野指针",对野指针解引用是非常危险的.

指针变量涉及两个要素: int* char*

        1.指针对应的内存是哪个地址                        (指针的值体现)

        2.这个内存地址对应的内存大小是多大        (指针的类型体现)

有一种特殊的指针,只有地址,而没有内存对应的大小.

void* 正因为没有限制内存的大小, void* 对应的内存可以是任意大小.

void* 不能解引用.

void* 用处很大.当某个函数不需要关注类型,或者需要多种指针类型的时候,就可以使用void* (memset是典型的例子)

void* 相当于是把类型完全交给程序员来控制和保证.

空指针 VS void*

空指针:比较特殊的指针,空指针的地址就是 0 .NULL

空指针是一种特殊的野指针.操作系统的内核可以用到,别的时候调用不了

操作系统是一个软件,用来管理硬件设备和各种软件资源的.

一个操作系统 = 内核 + 配套的应用系统

内核是核心所在,软硬件的管理主要都是内核完成的.

平时写的程序都是应用程序,跑在系统之上.还有一些特殊的程序是跑在内核中的(驱动程序(显卡驱动/鼠标驱动)).

32位系统上,一个指针占用4个字节.支持的最大内存就是 4GB

4个字节,能表达的最大数字是多少? 42亿 => 4GB 

64位系统上,指针是占 8 个字节.

64位系统能运行32位程序的.VS生成的程序默认是按照32位来生成.

C语言中煤种类型占几个字节,取决于具体的编译器.

C语言标准中只是规定了 int/long 不能低于4个字节,具体是4 还是8,就和编译器相关了,也和32位/ 64位系统是相关的.

NULL 是一个典型的非法内存,如果解引用一定会出现问题.

#include <stdio.h>
#include <stdlib.h>

int main(){
    int num = 0x11223344;
    int* p = &num;
    char* p2 = (char*)p;
    printf("%x\n", *p2);
    
    system("pause");
    return 0;
}

11 22 33 44 大端字节序

44 33 22 11 小端字节序

0xcc这个数字对应到 int3 指令(CPU的指令),遇到这个指令程序就会直接崩溃.

指针指向的空间释放

有一个出场率很高的笔试题:

#include <stdio.h>
#include <stdlib.h>

int* Func(){
    int num = 10;
    return &num;
}

int main(){
    int* p = Func();
    printf("%d\n",*p);
    system("pause");
    return 0;
}

虽然输出结果为10 但是是有问题的:因为局部变量的生命周期在函数运行结束之后就结束了.申请的num开辟的内存也就释放掉了.之所以能够输出10是恰好这里的内存还没有被其他程序占用.

如何规避野指针:

        1.指针初始化

        2.小心指针越界

        3.指针指向空间释放即置NULL

        4.指针使用之前检查有效性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值