数组,指针经验交流(堆,栈讨论初步……)

类别:编程语言 点击:0 评论:0 推荐:


曾经未来) 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
栈的原理比较简单,堆的基本概念我知道,但具体在操作的时候如何实现,我就不清楚了,我们教的编译原理没有涉及过动态分配内存

本文地址:http://com.8s8s.com/it/it24258.htm