您的位置:首页 > 编程语言 > C语言/C++

浅谈C语言指针的有趣应用(一)

2010-09-29 02:20 169 查看
      曾经有人这样说过:"如果你不懂指针操作,你就不能说自己学过C语言。"虽然这话有点偏激,不过却是道出指针在C语言的重要地位:C的灵活性在于指针,我们几乎可以通过指针对程序做任何事。闲话不多说,让我们来看一个关于指针操作的简单有趣例子:

部分代码如下:

    #include <stdio.h>

    void process_keys12 (int * key1, int * key2) {

     

        *((int *) (key1 + *key1)) = *key2;

    }

    int main()

    {

        int dummy = 1;

        int start, stride;

        int key1, key2;

        key1 = 3;

        key2 = 777;

        process_keys12(&key1, &key2);

        start = (int)(*((char *) &dummy));

        stride = (int)(*(((char *) &dummy) + 1));

        printf("dummy: %d/nstart: %d/nstride: %d/n", dummy, start, stride);

        return 0;

    }

运行结果如下:

dummy: 777

start: 9

stride: 3

下面我们来简单分析一下:(注:以下分析基于x86结构)

      分析之前我们要了解一下我们的程序在内存中是怎么存放的,所有的代码在内存中都是已二进制的形式存放的,不过操作系统将我们的程序的数据部分和指令部分分开放置在内存中,对于数据部分的全局变量初始化的放在一块,未初始化的放在另一块,对于局部变量无论初始化还是未初始化在内存中都是从高到低依次存放。

       有了这些知识我们开始看一下这个程序:这里我们没有定义全局变量,所以变量dummy, start,stride, key1,key2在内存中是依次连续存放的5个整形变量。下面我们分析一下process_keys12()函数, key1 + *key1就是key1的地址移动key1地址存放的值(也就是3)个单元,此时已经指向变量dummy所在的地址,*((int *) (key1 + *key1)) = *key2就是将key2的指针指向的值覆盖dummy所在地址存放的内容,这样dummy的值就被偷换成key2的值了。接下来便是对start和stride的赋值,分析这个之前我们还要了解一下大端模式存储和小端模式存储,所谓的大端模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;所谓的小端模式,是指数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中。例如:十进制777这个数在十六进制表示为0x00 00 03 09,在大端模式下存储方式为:

内存地址
0x4000
0x4001
0x4002
0x4003
存放内容
0x00
0x00
0x03
0x09
在小端模式下存储方式为:

内存地址
0x4000
0x4001
0x4002
0x4003
存放内容
0x09
0x03
0x00
0x00
在x86结构下通常为小端模式,因此(char *) &dummy便是int型dummy的低位地址第一个字节存放的内容0x09,((char *) &dummy) + 1则是对int型dummy低位地址开始第二字节存放的内容0x03,因此得到了start = 9, stride = 3的结果。

     C语言的指针的灵活性,成就了C语言作为系统级开发的龙头地位,但也正是指针的灵活性使编写程序变得难以把握稍不注意便会出错,对于C语言的这把双刃剑我们在以后的时间继续学习与讨论,使C语言成为我们的修身利器!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  语言 c 存储 x86