void指针和NULL指针

你猜下边代码会打印多少?

#include <stdio.h>

int main()
{
        void a;

        printf("%d\n", sizeof(a));

        return 0;
}

答:会报错!那 void 既然是无类型,我们就不应该用它来定义一个变量,如果你一定要这么做,那么程序就会给你报错(我只是换个提问方式,看看多少童鞋会上当)。

那 sizeof(void *) 呢?答:如果你回答是 4 个字节或 8 个字节,那么本题不能算你答对。因为指针的尺寸是与编译器的目标平台相关的。比如目标平台是 32 位的,那么 sizeof(void*) 就是 4,如果是 64 位的,那么 sizeof(void *) 就是 8,如果是 16 位的,那么就是 2 啦。

 如何有效地避免出现悬空指针?注:悬空指针就是指向了不确定的内存区域的指针,通常对这种指针进行操作会使程序发生不可预知的错误。

答:当你的指针不知道指向哪儿的时候,那么将它指向 NULL,以后就不会有太多的麻烦。比如定义一个指针变量的时候,你可以把它初始化为 NULL,这样至少可以确保它不是一个垂悬指针

对 NULL 指针进行解引用,结果是什么?答:报错。无论什么操作系统,对空指针进行解引用都是非法的。

请问下边定义有没有问题?

……
int *p = void *0;
……

答:报错

NULL 的宏定义是:#define NULL ((void *)0)

这里是将 0 强制转换成 void 指针,所以要这么写才能通过编译:int *p = (void *)0;

请问下边代码会打印什么?

#include <stdio.h>

int main()
{
        int array[5] = {1, 2, 3, 4, 5};
        int *pi = &array[2];
        void *pv;

        pv = pi;
        pv++;
        pi = pv;

        printf("%d\n", *pi);

        return 0;
}

答:建议回答“4”的童鞋自己打一次代码……

先晒下结果:

为何如此邪乎?我们把代码修改如下,你或许就会知道答案:

#include <stdio.h>

int main()
{
        int array[5] = {1, 2, 3, 4, 5};
        int *pi = &array[2];
        void *pv;

        pv = pi;
        printf("%p, %p\n", pv, pi);

        pv++;
        pi = pv;
        printf("%p, %p\n", pv, pi);

        printf("%d\n", *pi);

        return 0;
}

程序实现如下:

猜到了吧?由于 pv 是 void 类型指针,所以编译器并不知道其“跨度”是多少,因此 pv++ 只是简单的将地址加 1。那么地址不正确,打印出来的值肯定就是错误的!

那打印出来的是“乱码”吗?不是!如果没有猜错,你在电脑上得到的结果应该跟小甲鱼是一样的。

下边解释需要你懂得小端和大端的原理,不懂请先戳右边学习 -> 传送门

pi 指向的是数组的第三个元素(即 array[2],其值为 3)

那么 array[2] 和 array[3] 在内存中的存放形式(小端)应该如下:

pv = pi 使得 pv 也是指向 0xbf93b10c 地址。

pv++ 刚才我们解释了,编译器只知道机械将其地址加 1,即 pv 现在指向的是 0xbf93b10d 地址。

pi = pv 使得 pi 被 pv 带上了歪路…… 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

倦504

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

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

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

打赏作者

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

抵扣说明:

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

余额充值