浅谈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,在大端模式下存储方式为:
在小端模式下存储方式为:
在x86结构下通常为小端模式,因此(char *) &dummy便是int型dummy的低位地址第一个字节存放的内容0x09,((char *) &dummy) + 1则是对int型dummy低位地址开始第二字节存放的内容0x03,因此得到了start = 9, stride = 3的结果。
C语言的指针的灵活性,成就了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 |
C语言的指针的灵活性,成就了C语言作为系统级开发的龙头地位,但也正是指针的灵活性使编写程序变得难以把握稍不注意便会出错,对于C语言的这把双刃剑我们在以后的时间继续学习与讨论,使C语言成为我们的修身利器!
相关文章推荐
- 浅谈C语言2级指针的简单应用
- C语言指针五——指针应用:链表
- 浅谈C语言 extern 指针与数组
- C语言 指针应用-swap()
- [转]C语言指针学习经验总结浅谈
- C语言中,一级指针,二级指针,数组,一位数组指针,二位数组指针浅谈
- 【C语言】 浅谈指针
- c语言,指针,及其应用
- 浅谈C语言 extern 指针与数组
- C语言泛型指针应用-为任何类型的变量交换值
- 有趣的C语言--指针
- 简单的指针应用 成绩表 c语言
- 011_C语言数组与指针间的转换及函数应用
- 浅谈C语言中数组和指针的互操作
- 浅谈c语言typedef 与结构体指针(个人小经验)
- 关于C语言的文件型指针和移位操作中的一些有趣问题的探讨
- c语言之多级指针的应用
- 有趣的C语言--字符串与数组和指针的秘密
- C语言 结构体的应用 查询结构体中的信息 结构体与指针操作
- 浅谈C语言中变量、常量、数组、字符串、指针的地址