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的字节给写了,越界访问呐。

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

posted @ 2012-11-28 10:03  南树  阅读(377)  评论(3编辑  收藏  举报