原帖及讨论:http://bbs.bccn.net/thread-180443-1-1.html */ -------------------------------------------------------------------------------------- */ 出自: 编程中国 http://www.bccn.net */ 作者: neverTheSame E-mail:zhaoxufeng9997@126.com QQ:475818502 */ 时间: 2007-10-24 编程论坛首发 */ 声明: 尊重作者劳动,转载请保留本段文字 */ --------------------------------------------------------------------------------------
大家都知道,每一个变量都有自己的存储空间。而地址就是用来唯一地标识存储空间。 这样就很容易让我们联想到:可以直接通过地址来代替变量,来参加程序的运算。 也就是说,我们在程序运算中可以不用变量,而直接对地址进行操作。 说了这么多,大家可能还不明白,我到底是什么意思。下面就举几个例子来说明。 例一: #include<stdio.h> int main(void) { scanf("%d",(int*)0x0100); printf("%d",*((int*)0x0100)); } 由上例可知,0x0100一个存储空间地址.我们通过int*强制类型转换, 将0x0100的类型转换成int*型.在scanf()函数执行时,将从标准输入设备中输入的 整型值放在以0x0100为首址的空间中.而在printf()函数执行时,*((int*)0x0100)的作用 就是在0x0100为首址的空间中取出一个整型数,然后打印在标准输出设备上. 以上这个例子模拟有变量例子: #include<stdio.h> int main(void) { int var;/*假设变量的存储空间的首址为0x0100*/ scanf("%d",&var);/*&var就是取var的首址,相当于scanf("%d",0x0100);*/ printf("%d",var);/* *((int*)0x0100)就是var的值.*/ } 例二: 实现一个动态申请一个三维数组(像array[5][5][5). #include<stdio.h> #include<malloc.h> int main(void) { *(int****)0x0120=(int***)malloc(sizeof(int**)*5); for((*(int*)0x0116)=0;(*(int*)0x0116)<5;(*(int*)0x0116)++) { *(*(int****)0x0120+(*(int*)0x116))=(int**)malloc(sizeof(int*)*5); for((*(int*)0x0112)=0;(*(int*)0x0112)<5;(*(int*)0x0112)++) { *(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))=(int*)malloc(sizeof(int)*5); for((*(int*)0x0108)=0;(*(int*)0x0108)<5;(*(int*)0x0108)++) *(*(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))+(*(int*)0x0108))=1; } } for((*(int*)0x0116)=0;(*(int*)0x0116)<5;(*(int*)0x0116)++) for((*(int*)0x0112)=0;(*(int*)0x0112)<5;(*(int*)0x0112)++) { for((*(int*)0x0108)=0;(*(int*)0x0108)<5;(*(int*)0x0108)++) printf("%d ",*(*(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))+(*(int*)0x0108))); printf("/n"); } } 相关的解释如下: #include<stdio.h> #include<malloc.h> int main(void) { /*申请一个可以存放5个二级指针的空间, 并把申请到的空间的首址的存放到0x0120为首址的空间中。 相当于:char ***array=NULL; array=(int***)malloc(sizeof(int**)*5);*/ *(int****)0x0120=(int***)malloc(sizeof(int**)*5); /*用一个循环,循环的次数为5,空间0x0116存储控制循环的次数值。 相当于for(i=0;i<5;i++)*/ for((*(int*)0x0116)=0;(*(int*)0x0116)<5;(*(int*)0x0116)++) { /*申请一个可以存放5个一级指针的空间, 并把申请到的空间的首址的存放到*(int****)0x0120+(*(int*)0x116)为首址的空间中。 相当于:array[i]=(int**)malloc(sizeof(int*)*5);*/ *(*(int****)0x0120+(*(int*)0x116))=(int**)malloc(sizeof(int*)*5); /*用一个循环,循环的次数为5,空间0x0112存储控制循环的次数值。 相当于for(j=0;j<5;j++)*/ for((*(int*)0x0112)=0;(*(int*)0x0112)<5;(*(int*)0x0112)++) { /*申请一个可以存放5个整型数据的空间, 并把申请到的空间的首址的存放到*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112) 为首址的空间中。相当于:array[i][j]=(int*)malloc(sizeof(int)*5)*/ *(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))=(int*)malloc(sizeof(int)*5); /*用一个循环,循环的次数为5,空间0x0108存储控制循环的次数值。 相当于for(k=0;k<5;k++)*/ for((*(int*)0x0108)=0;(*(int*)0x0108)<5;(*(int*)0x0108)++) /*将首址为*(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))+(*(int*)0x0108)的 空间赋值为1。相当于array[i][j][k]=1;*/ *(*(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))+(*(int*)0x0108))=1; } } /*用一个循环,循环的次数为5,空间0x0116存储控制循环的次数值。 相当于for(i=0;i<5;i++)*/ for((*(int*)0x0116)=0;(*(int*)0x0116)<5;(*(int*)0x0116)++) /*用一个循环,循环的次数为5,空间0x0112存储控制循环的次数值。 相当于for(j=0;j<5;j++)*/ for((*(int*)0x0112)=0;(*(int*)0x0112)<5;(*(int*)0x0112)++) { /*用一个循环,循环的次数为5,空间0x0108存储控制循环的次数值。 相当于for(k=0;k<5;k++)*/ for((*(int*)0x0108)=0;(*(int*)0x0108)<5;(*(int*)0x0108)++) /*将首址为*(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))+(*(int*)0x0108)的 空间的数据打印。相当于printf("%d ",array[i][j][k]);*/ printf("%d ",*(*(*(*(int****)0x0120+(*(int*)0x0116))+(*(int*)0x0112))+(*(int*)0x0108))); printf("/n"); } } 优点: 访问速度快。(由于,CPU直接用地址查找数据) 程序的效率高。(由于,减少了其它用于对变量操作的指令,从而对运算操作的指令比例大) 生成的可执行文件小。(由于,变量直接用地址存取,减少了指令数量。)
缺点: 程序可读性差。 直接使用地址很容易混淆。(如,动态申请的空间是否被用作变量空间去使用。) 对程序员要求很高。(如程序员需要知道,每种类型所占用的字节空间大小。) |