C指针本质探究

  • 指针是什么

我的解释是,把内存看成能容纳东西的房间。这个房间的大小是一个字节(8位)。房间可以容纳东西(内容),房间有自己的门牌号(地址)。

例如:

int a = 5;

我们申请了一个名为a的房间,这个房间一共由四个基本房间组成(32位),这个房间里存放的内容为5,那它的门牌号呢?c语言不需要我们直接接触地址,如果学过汇编就很清楚这个问题了,c中我们可以用 &a 取得a的地址,即这个房间的门牌号。

指针

上面是示意图,能类比内存的模样。如果我们认为第六个房间里放的是门牌号,那么它指向的是一号房间。

我们定义  

int *p = &a;

这时候p这个房间里面就存放了a的门牌号,注意p自己也是房间,也有门牌号。

因为不论何种类型的指针存放的都是地址,所以其所需的房间大小都是一样的。

  • 指针类型的作用

定义一个指针变量,我们需要这样做:

int *p;

前面提到所有类型的指针所需的空间都是一样大的,为什么指针需要分类型?

我们这样访问指针:

int b = *p;

访问的时候出了需要知道目标房间的门牌号,还要知道由多少间基本房间(字节)组成。char类型占一个基本房间,int类型占4个基本房间(32位),自定义的类型也许更多。所以访问的时候仅仅知道房间的门牌号还是不够的,还需要知道其大小。我们用*p的时候,编译器需要知道我们要从其地址开始读几个字节的数据,所以我们需要定义指针的类型。

例:

#include <stdio.h>

#include <stdlib.h> 



struct TY

{

    char s[100];

}; 



int main()

{

    int *pa = 0x0;

    char *pb = 0x0;

    TY *pc = 0x0; 



    ++pa;

    ++pb;

    ++pc; 



    printf("%d   %d\n",pa,sizeof(int));

    printf("%d   %d\n",pb,sizeof(char));

    printf("%d   %d\n",pc,sizeof(TY));

    return 0;

}

void *类型指针加大了c指针的灵活性。我的上一篇博文《void*指针实现支持所有数据类型的容器》,就是用void*实现的,在计算偏移地址的时候,我把void*强制转换成char*,这样每次++就会移动一个字节。

  • 指针的作用

指针很灵活,不仅能够访问数据,还能访问函数。

如果有汇编基础,就知道在内存里数据和代码是没有区别的。所以指针能够指向数据,也就能够指向函数代码入口。

用指针访问数组,传递参数,访问某个特定地址,有用的地方很多

  • 指针的潜在风险

c中的指针是允许强制转换类型的。如

int *a;



char c;



a = (int*)&c;

这样是允许的,但是有什么风险?

结合上面说的,指针类型制定了其访问的长度。如果按上面那样做,再有这样的句子:

*a = ‘c’;

它修改的就不仅是c的哪一个字节了,而是四个字节。虽然执行

printf(“%c\n”,c)

输出的是c。那是因为小端机的原因,结果没错,但是把后面三个不属于c的字节给写了,越界访问呐。

还有指针悬空,内存泄露等问题。所以用指针时候需要注意。

你可能感兴趣的:(指针)