曾经未来) 11:02:42 是2*4+3+1 (曾经未来) 11:03:00 我前面的偏移推导写错了,应该还要加一才对 (天堂没有雪) 11:03:22 不用吧 (曾经未来) 11:03:34 寒,我也有点儿乱了,呵呵 (曾经未来) 11:03:43 不用不用,第一个是零,哈哈哈 (天堂没有雪) 11:03:52 (曾经未来) 11:03:56 加了一再减一,,其实就是不用加 漫.ASH) 11:03:57 我现在感觉,a[2][3]的寻址方式应该是: 先寻找a[2],也就是跳过2个int [3]的位置, 然后再在当前位置跳过3个int 的位置,就找到了 这样数组和指针就和谐统一了 (天堂没有雪) 11:04:03 好热烈呀,刚下课 (曾经未来) 11:04:05 对的 (曾经未来) 11:04:11 ASH的说法是对的 (天堂没有雪) 11:04:26 赞 (学C新手) 11:04:32 又一个牛人到了 (天堂没有雪) 11:05:39 (漫.ASH) 11:05:46 (学C新手) 11:07:06 怎么都暴汗啊? (学C新手) 11:07:37 (2004-12-17 11:03:57) 漫.ASH(26367948) 我现在感觉,a[2][3]的寻址方式应该是: 先寻找a[2],也就是跳过2个int [3]的位置, 然后再在当前位置跳过3个int 的位置,就找到了 这样数组和指针就和谐统一了 --------------------------- 怎么实现? (曾经未来) 11:08:36 实现?实现就是我写的那样 (学C新手) 11:10:21 脑子乱啊~~~~想想回头再来... (漫.ASH) 11:10:26 int a[2][3]也就是 int (*a)[3] 就是定义一个指针a,指针指向的类型是一个长度为3个int的数组 这个时候,如果寻址的话: a[1][2] 就是*(a[1] + 2) *(*(a + 1) + 2) 也就是说从a向前跳1 (学C新手) 11:12:00 从a向前跳1 ---------------- 木能理解 (漫.ASH) 11:12:26 这次跳的距离是a的类型,因为a的类型是一个长度为3的int数组,所以向前跳 1 * 3 * sizeof(int) 但是*(a + 1)的类型也是指针,是一个int型的指针,所以,*(a + 1) + 2的结果是指针向前跳2个int的单位 漫.ASH) 11:14:03 int *a; a += 1; 就是a想前跳一个int宽度的距离 那如果a指向的类型不是int,而是一个int类型的数组,数组的元素个数为3个, a += 1 是不是就往前跳一个数组的距离呢? (学C新手) 11:14:29 解了.... (曾经未来) 11:14:33 首先,你要明白,指针分指针地址和指针数据两部分,对于一个指针p,p的运算是移动它指向的地址位置,*p的运算是对它指向的数据进行操作 (天堂没有雪) 11:15:12 你们讲得比老师讲的好多了, (学C新手) 11:15:25 int (*p)[3] p++; 加的是int[3] (曾经未来) 11:15:28 呵呵,我的老师讲得比我好多了 (漫.ASH) 11:15:43 a[2] == *(a + 2) Ricky昨天给的这个式子真的很经典呀 (曾经未来) 11:15:56 还有那个0[p] (曾经未来) 11:15:59 太强了 (漫.ASH) 11:16:21 点出了指针和数组的内在联系 (学C新手) 11:16:21 0[p]我到现在不能理解 (漫.ASH) 11:17:04 证明,用到加法交换律: a[2] == *(a + 2) == *(2 + a) == 2[a] (曾经未来) 11:17:05 0[p],就是从程序内存的起点,移动至P指针所在的位置 (Ricky) 11:17:42 (漫.ASH) 11:17:04 证明,用到加法交换律: a[2] == *(a + 2) == *(2 + a) == 2[a] ,就是这个道理啊, (学C新手) 11:17:56 这样都行? (Ricky) 11:18:10 同样的道理,2可以换成0,甚至是负数,还可以大于数组大小 (学C新手) 11:18:15 弓虽啊 (天堂没有雪) 11:18:22 靠,强,第一次听说,居然还能这样 (曾经未来) 11:18:23 呵呵,所以C才会长盛不衰 (Ricky) 11:18:24 只要这个大小还在栈中 (天堂没有雪) 11:18:33 (漫.ASH) 11:18:41 c真是太博大精深了 (Ricky) 11:18:41 就不会引起错误。 (天堂没有雪) 11:18:54 学习ing (曾经未来) 11:19:00 理解了这个你就会明白,整个计算机的在C编译器看来就是用指针操作资源 (Ricky) 11:19:10 这就是为什么有时候指针越界只是得到错误结果,有些时候却会引起程序崩溃 (学C新手) 11:20:04 2[a]这个时候是做什么滴? ------------------------ 我不活了...我还是不懂 (天堂没有雪) 11:20:31 a[2]一样吧 (Ricky) 11:20:35 2[a]就等于a[2]啊 (Ricky) 11:21:01 其实是在欺骗编译器,反正得到的汇编代码是一样的 (天堂没有雪) 11:21:14 就是说是同一个内存块的东西 (学C新手) 11:22:52 .......... (曾经未来) 11:23:21 其实我觉得也不能叫欺骗,从数学意义上讲,这样的转换很完美 (曾经未来) 11:23:36 能支持这样的运算,它在数学角度才是完备的 ( 流星雨) 11:23:41 (漫.ASH) 11:23:46 c编译器在处理a[2]的时候,把a和2看成了一样的东西?就是做简单的地址加法而已,谁前谁后都无所谓 不知道这样说好明白吗? (曾经未来) 11:24:16 a[2]是从a偏移2,2[a]是从2偏移a,它们本来就应该是一致的 (曾经未来) 11:24:29 ASH说得没错啊 (学C新手) 11:24:43 a[2]是从a偏移2,2[a]是从2偏移a,它们本来就应该是一致的 -------------------- 这个说法好 (Ricky) 11:24:45 都很有道理 (走尽天涯路②) 00:51:39 ( 流星雨) 11:24:55 a[2]是从a偏移2,2[a]是从2偏移a
没见过 (天堂没有雪) 11:25:25 反正是同一个地方 (走尽天涯路②) 00:52:24 早知道应该去看看,对应的汇编码 ( 流星雨) 11:25:38 哦,
您刚才发送的消息:"早知道应该去看看,对应的汇编码 "没有发送成功(服务器超时).
(学C新手) 11:25:58 说的现在,我觉得解释的最好的是未来,虽然提出这个概念是的ricky发扬光大的是ASH ( 流星雨) 11:26:40 哈哈, (曾经未来) 11:26:42 (Ricky) 11:17:42 (漫.ASH) 11:17:04 证明,用到加法交换律: a[2] == *(a + 2) == *(2 + a) == 2[a] ,就是这个道理啊,
ASH的这个证明,是最严谨的 (学C新手) 11:26:59 但是不能理解 (Guderian★) 11:27:40 报个到 还有事 (漫.ASH) 11:27:45 偶就说是降龙十八掌 舞的好看吧 (曾经未来) 11:28:02 学上一年的泛函分析,你就学悟了 (学C新手) 11:28:33 泛函分析? 木有学过啊~~~ (尤利卡) 11:29:53 那位会嵌入式系统的? (学C新手) 11:30:24 int a[10] a这个字符是不是一个变量捏? a==a[-1]???? ( 流星雨) 11:30:42 A是常量地址吧
(漫.ASH) 11:31:02 a是地址 (漫.ASH) 11:31:18 是指针那 ( 流星雨) 11:31:19 就是 (学C新手) 11:31:20 a[0]?
( 流星雨) 11:31:47 A[0]代表是一个元素吧 (学C新手) 11:31:57 &A[0]? ( 流星雨) 11:32:10 呵呵 , (漫.ASH) 11:32:16 int a[10] 等价与 int *a = new[10]; a等价与&a[0] (漫.ASH) 11:32:42 当然一个在栈上一个在堆上
( 流星雨) 11:32:42 高手 (学C新手) 11:33:18 栈和堆?要求ASH讲讲...我还没明白捏? (漫.ASH) 11:34:02 除了new出来的东西,其他东西全是在栈上建立的 (学C新手) 11:34:37 栈我记得是先进先出的吧? (尤利卡) 11:34:48 fifo的啊, (Ricky) 11:35:05 那是堆栈数据结构,和这个不是一个概念 (曾经未来) 11:35:19 这里的堆和栈不是数据结构里的堆栈 (曾经未来) 11:35:24 是内存的管理方式 (学C新手) 11:35:25 所以说我不懂嘛~~~~ (学C新手) 11:35:35 讲讲.... (漫.ASH) 11:35:39 fifo?队列吧? (尤利卡) 11:35:41 队列是先进现出 堆栈是后进先出啊 (尤利卡) 11:35:49 恩, (学C新手) 11:35:59 我记错了 (学C新手) 11:36:15 不过还是先讲系统的堆和栈吧? (学C新手) 11:36:23 不懂啊~~~~ (学C新手) 11:36:52 操作系统的书里有没有?有的话回头好好翻下 ( 流星雨) 11:37:09 数据结构看一下, (漫.ASH) 11:37:14 我只知道大概的运行方式,不太清楚具体组织方式,那位达人深刻的讲一讲 操作系统的书里没有,至少我见过的课本都没有 (学C新手) 11:37:29 我觉得也是没有... (漫.ASH) 11:37:32 其实跟编译原理有关 (Ricky) 11:37:34 编译原理
(曾经未来
简单来讲,堆上的资源是由程序员自己维护的 栈上的资源是编译来管理的 (数据结构的堆与栈就是另一个问题了 )
(曾经未来) 11:39:45 再细的我也讲不出来了 ( CD-ROM) 11:39:47 队和栈有没区别? (尤利卡) 11:39:57 有点啊, (漫.ASH) 11:39:58 { int a; { int b; } int c; } 入栈方式: c b ---------中间括号的作用域 a (曾经未来) 11:40:09 堆上申请的资源需要程序员自己释放,栈上不用 ( CD-ROM) 11:40:32 明白 (天堂没有雪) 11:42:06 数据结构中的是按照你自己定义的方式得来的吧 (学C新手) 11:42:10 现在不谈数据结构中的堆栈(回去啃书好了)就谈运行程序时候的堆栈 (漫.ASH) 11:42:18 栈上填加或者删除都很简单,比如刚刚的程序,如果我想再填一个int d; 那么,只要把栈顶向上移动一格,空间就出来了 而如果要删除的话更容易,比如说,要是出了外层括号的作用域,只要把指针向下移动到a以下,所有东西就清空了 这就是为什么int a[10]; 比int *a = new[10]; 的速度快的原因 (天堂没有雪) 11:42:19 应该跟系统中的不是一样的 (漫.ASH) 11:43:30 栈的原理比较简单,堆的基本概念我知道,但具体在操作的时候如何实现,我就不清楚了,我们教的编译原理没有涉及过动态分配内存

|