关于二维数组和指针的理解
本帖最后由 竹逸 于 2022-9-30 13:31 编辑要彻底理解二维数组和指针,首先得先要理解什么是内存,内存是一种存储器,它的作用是用来存储数据的,这个存储器的内部是一个个存储单元,这一个个存储单元是互相独立存在的,而且这一个个存储单元是按照一条直线的顺序排列在一起的,也就是线性排列的。为了方便区分各个相互独立的存储单元,也就是区分谁是谁,我们用记标号的方式来定位每一个存储单元,第一个存储单元从0开始标号,以此类推,这些标号就是每一个存储单元在当前位置的地址值,存储单元都是实实在在物理层面上存在的,所以我们把为这些存储单元分配的地址值称为物理地址,也就是内存地址。
然后什么是变量,变量本质其实就是一块存储单元,因为变量一旦被声明,CPU就会立刻在内存中为其申请一块闲置的存储单元,用来存储该变量的值,变量名就是该存储单元的别称(取外号),变量的地址就是该存储单元的地址值,即内存地址,变量的值就是该存储单元里存放的数据,给变量赋值就是给对应的存储单元写入数据。
可能有人会有疑问,既然有地址值就可以定位各个存储单元,那我们为什么还需要给存储单元取名,即变量名,那是因为地址值是一串无意义的数字,计算机虽然可以通过地址值定位到各个存储单元,但人类却难以识别和记忆各个存储单元的地址值,尤其是申请的存储单元太多,谁知道某一个具体的数据是存放在哪个存储单元里?这就好比二进制一样使人难以阅读、理解和记忆。而变量名的存在就是给存储单元取名,即标记一个符号(标识符),这个符号就代表了这块存储单元,我们只需要通过名字就可以定位具体的存储单元,而不需要通过一串无意义的数字,但注意的是变量名并不是地址值的替换,而是给地址值上对应的存储单元标记的符号。我们要给某个变量(存储单元)赋值,除了可以直接引用变量名外(存储单元的别称),还可以间接的通过地址值来定位。
我们知道数组的元素也是一个个变量,在内存中也是由一个个存储单元以线性的形式排列的,各个元素的值就是各个存储单元里存放的数据,各个元素的地址就是各个存储单元的地址值(元素有自己的地址值)。而二维数组是一种特殊的一维数组,只不过数组中的各个元素的值不是简简单单的数值,而是内存地址,这个内存地址是另一个一维数组的首地址,那么也就是说,这个特殊的一维数组中的各个元素( a、a、a……)这些元素名是另一个一维数组的数组名,指向了另一个一维数组的首地址。即二维数组中各个元素的值是内存地址,指向了另一个一维数组的首地址。
以上理解了,那么我们再假设一个二维数组a:
a:二维数组名,数组名是该数组的首地址,也是第一个元素的内存地址。即 a 的值是一个地址值,这个地址值上存放的数据是数组中第一个元素的值,即a的值,这个值指向是另一个一维数组的首地址(地址值上存储的是地址值)
*a:" * " 是取值运算符,*a表示取a的值,也就是取第一个元素a的值,取出的是另一个一维数组的首地址。
a:同 *a 。
&a:" & " 是取址运算符,&a表示取a的地址,也就是取第一个元素的地址(保存另一个一维数组首地址的地址)。
&a:a是另一个一维数组名,其值是另一个一维数组的首地址,a是另一个一维数组的第一个元素,&a取的是另一个一维数组的第一个元素的地址。
a+1:a是数组名,是首地址,也是第一个元素的地址,对应的下标索引值是0,a是地址,1是数值,类型不同的相加运算,+1的操作是下标索引值+1,即 0+1 = 1,得到的结果是指向下标为1的元素的地址,即a的地址 (a的地址值加了1个元素的长度(字节数)。
*(a+1):取元素a的地址的值,相当于*&a,也就是取a的值,a里存储的是另一个一维数组的首地址。
a+1:a是二维数组a中下标为1的元素,也是另一个一维数组的第一个元素的地址,a+1指向的是另一个一维数组中,下标为1的元素的地址,即&a。
*(a+1)+1:同a+1,结果是&a。
*(a+1):取的是一维数组a中,下标为1的那个元素的地址的值,即a的值
*(*(a+1)+1):同*(a+1) 。
有个小小的疑问?在汇编语言中,标识符是一个指针,记录了当前位置的地址值,通过loop或goto指令跳转到所标识的内存地址。在c语言中,变量名也是一种标识符,在cpu内部,它是不是也是以地址的形式来索引这个变量,只不过我们输出变量的值不是地址而是数据? 在CPU内部就是 有非常非常多的电线,有的电线上面有电流流过,有的电线上面没有电流流过
在这里,我又要推荐书了
《穿越计算机的迷雾》,百度能找到pdf版本
去看一看吧,看一看计算机底层是什么样子的
补充一句,数组的下标索引是相对于首地址的偏移量,首地址就是起始地址,也可以叫基地址(基础地址),偏移量是相对于这个基地址偏移了多少个单位,第一个元素的下标是0,表示相对于基地址偏移了0个单位,也就是没有偏移,也就解释了首地址也是第一个元素的地址 人造人 发表于 2022-9-30 14:02
在CPU内部就是 有非常非常多的电线,有的电线上面有电流流过,有的电线上面没有电流流过
在这里,我又要推 ...
算了{:10_266:}等以后再深入研究吧,现在我都是假期和下班时间来学习c的,都感觉时间不够用{:10_266:} 人造人 发表于 2022-9-30 14:02
在CPU内部就是 有非常非常多的电线,有的电线上面有电流流过,有的电线上面没有电流流过
在这里,我又要推 ...
其实我的学习进度超级慢的,我是属于那种一旦进入学习了就会沉醉其中,可一旦哪天没有学习,再继续学习很抵触,拖延症晚期,懒癌患者{:10_247:} 竹逸 发表于 2022-9-30 14:34
其实我的学习进度超级慢的,我是属于那种一旦进入学习了就会沉醉其中,可一旦哪天没有学习,再继续学习很 ...
^_^
页:
[1]