现在的位置: 首页 > 综合 > 正文

c语言 指针–这是怎么分配的,我要疯了!!!

2018年04月22日 ⁄ 综合 ⁄ 共 2565字 ⁄ 字号 评论关闭

c语言很难,C语言的指针更是难点,当初学的一头雾水,现在才有了一点感悟,想研究下c语言的指针。 说到指针就不得不提指针地址的分配,了解c语言指针地址的分配逻辑非常有助于我们理解程序。 先看下面的程序#include int main(){int *p;int *q;int *i;int m = 3;int *x[3];/////////////////////////////////////////////------1输出指针本身所在地址printf("1-输出指针本身所在地址:\n");printf("%x\n",&p);printf("%x\n",&q);printf("%x\n",&i);printf("%x\n",&m);printf("%x,%x,%x\n",x,x+1,x+2);/////////////////////////////////////////////////////----2输出指针指向的地址printf("\n2-输出指针指向的地址:\n");i
= &m;printf("%x\n",p);printf("%x\n",q);printf("%x\n",i);/////////////////////////////////////////////////////----3输出指针指向的地址所存储的值printf("\n3-输出指针指向的地址所存储的值:\n");printf("%x\n",*i);return 0;} 去掉第三部分error标记的两行,在vc6.0中运行的结果是http://img.blog.csdn.net/20141124231806859?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzkzNTIzOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
我们来分段分析,一开始我想做的只是输出指针本身的地址,然后,我实验了下,如第一部分的显示。 为什么先定义的会是从高地址开始,而后定义的却地址更小? 让我们回到一开始的内存地址分配说起,在c语言还有单片机中变量地址管理是通过栈实现的,就是个桶,先来的放到桶底,而规定的桶底就是高地址。这样就出现了去p,q,i的地址顺序。但是注意,数组的地址分配是顺序的如x[],这个符合大家的思维习惯。(具体的地址分配方式请百度c语言如何为变量分配地址,会有详细解释)但是,我就有个问题了,如果不给地址分配指向的地址,则指针指向不确定,那指向的就是随机地址吗?运行下,结果如部分二,怎么所有未初始化的指针都指向0xcccccccc?
百度一下: VC 会把未初始化的栈内存上的指针全部填成 0xcccccccc ,当字符串看就是 “烫烫烫烫……”;会把未初始化的堆内存上的指针全部填成 0xcdcdcdcd,当字符串看就是 “屯屯屯屯……”。 所以当大家出现这种乱码字符串了,我是出现过多次,那你就该好好看看你的指针了。 原来是这样,就此结束?NONONO!!!我继续想,所有的地址都是以数字表现出来 如果我另 p= (int *)0xcccccccc,会如何,然后为指针指向的地址赋值呢? 结果是这样为指针赋值是正确的,但是因为0xcccccccc相当于NULL,不能赋值,所以实验失败。但是如果是0xcccccccf或者0xccccccc3呢,是不是就可以了。
结果是,实验失败,可是为什么?0xccccccc3并不是NULL呀,这个地址和变量存储的地址有什么区别呢?基于这条思路,我重新写了个测试小程序:#include int main(){int *p;int m = 3;int x = 5;printf("%x\n",&m);//打印m的地址并记录下来printf("m = %d\n",m);//打印m的值用来对比p = (int *)0x18ff40; //这里0x18ff40是m的十六进制地址表示(*p)++;printf("m = %d\n",m);//重新打印mreturn
0;} 这个程序的思路是,我申请个变量,得到它的地址,赋给p,观察是否可行运行结果:18ff40m = 3m = 4 竟然成功了,我总结了一下,因为地址分配是从高地址往下开始的,所以第一个分配的地址为0x18ff44,也就是指针p,其他变量的地址只能比这个地址小,所以我原来为指针复制到地址0xcccccccf只能报错了。 变量的地址分配是从0x00000000开始吗?p = (int *)0x10ff40;发现也是运行错误,那到底从何处开始,我怎么知道?测试呗程序#include int main(){int
*p;p = (int *)0x18ff40; while(1){ *p=3;printf("p = %x\n",p--);}return 0;} 程序让p指向的地址从0x18ff40自减,观察何时报错程序运行结果是一直循环到0x93000报错另 p = (int *)0x93000; p = (int *)0x180000;#include int main(){int *p;p = (int *)0x93000; //p = (int *)0x180000;*p=3; printf("p = %x\n",p);return
0;} 郁闷的是依然报错,郁闷的要疯了呀!!!怎么办,到底是到哪里才不报错??怎么办 ,人工折半查找法,从0x93000 到 0x18ff40结果是 0x18d000程序运行正确,0x18cffc错误#include int main(){int *p;p = (int *)0x18d000; *p=3; printf("p = %x\n",p);printf("p = %x\n",*p);return 0;} 运行结果p = 0x18d000p = 30x18ff40 - 0x18d000 = 0x2f40
= 12096(10)我去网上查了关于这方面的资料,没有关于这些的介绍我认为,这是编译器的不同导致的结果,每种编译器分配的最高地址不同,为变量分配的存储变量的地址大小也不同。本人的虚拟机暂时出问题暂时不能验证,见谅。如果有人知道这个问题的清晰介绍请留言哦^_^运行结果想贴图的,但不知道为什么传不上来,见谅。 ph ph 我在努力哦,我是可爱的小尾巴

抱歉!评论已关闭.