当前位置:编程文档 >> C/C++ >> 深入理解C语言指针奥秘系列文章之一
首页

深入理解C语言指针奥秘系列文章之一

所属类别:C/C++
文章作者:jodie
推荐指数:★★☆
文档人气:95
本周人气:10
发布日期:2008-8-7
深入理解C语言指针奥秘系列文章之一

    Java堆是一个运行时数据区,类的实例(对象)从中分配空间。Java虚拟机(Jvm)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new、newarray、anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式的释放。一般来说,堆是由垃圾回收来负责的,尽管Jvm规范并不要求特殊的垃圾回收技术,甚至根本就不需要垃圾回收,但是由于内存的有限性,Jvm在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术,它自动地释放不再被程序引用的对象,按照特定的垃圾收集算法来实现资源自动回收的功能。/P>

    垃圾收集的意义

    在c中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象;而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾。Jvm的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是无用信息,这些信息将被丢弃。当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用。事实上,除了释放没用的对象,垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间,内存会出现碎片。碎片是分配;

    (1)int*ptr;//指针的类型是int*    (2)char*ptr;//指针的类型是char*

    (3)int**ptr;//指针的类型是int**

    (4)int(*ptr)[3];//指针的类型是int(*)[3]

    (5)int*(*ptr)[4];//指针的类型是int*(*)[4]

    指针所指向的类型

    当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。

    从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如:

    (1)int*ptr;//指针所指向的类型是int

    (2)char*ptr;//指针所指向的的类型是char

    (3)int**ptr;//指针所指向的的类型是int*

    (4)int(*ptr)[3];//指针所指向的的类型是int()[3]

    (5)int*(*ptr)[4];//指针所指向的的类型是int*()[4]

    在指针的算术运算中,指针所指向的类型有很大的作用。

    指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。

    指针的值,或者叫指针所指向的内存区或地址,指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。

    指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。

    指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。

    以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?

    指针本身所占据的内存区

    指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。

    指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。

    指针的算术运算

    指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如:

    例二:

    1、chara[20];
    2、int*ptr=a;
        ...
        ...
    3、ptr++;

    在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整形变量a。接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。

    由于char类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。我们可以用一个指针和一个循环来遍历一个数组,看例子:

    例三:

    intarray[20];
    int*ptr=array;
    ...
    //此处略去为整型数组赋值的代码。
    ...
    for(i=0;i<20;i++)
    {
    (*ptr)++;
    ptr++;
    }

    这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1,所以每次循环都能访问数组的下一个单元。

文档说明:

     

相关文档


读取评论列表……