C的数组C变量中数组C名时数组C的首地址

     有些刚学习C语言的人对于数组C的指针偏移量非常的困惑,对于各种不同情况下得+1 +1 蒙圈今天翻了下以前总结,重新写一篇博文

首先假设一个数组C元素为int类型的一维数组C叫做arr[4],arr的地址为0x00.

arr是这个数组C首元素地址==&arr[0], 心得就是 无论&什么什么+1 就是&符号后面的内容占据的地址单元数+指针起始位置 arr[0]占据4地址单元

类型在内存中占用四個字节,所以+1也是跳到第5个字节就是arr[1]的字节那儿,所以就是arr[1]了

二维数组C指针也是一样的,希望以后这些东西不会困扰你

C编译程序用数组C名存放数组C在内存中的首地址

指针访问内存比变量名访问速度更快,数组C采用指针加减1的方式访问数组C增加了访问内存的灵活性。

  • 指针移动方式访问數组C元素:
 

指针与数组C名都是地址因此可以混合使用访问数组C元素。

pa和a可以混合使用的图片说明前面一列是地址(a和pa都表示地址),加*表示里面的元素指针还可以移动,如图2
  • 数组C元素的等价引用形式:
 




  • 对应的数组C元素的地址表现形式:
 






数组C名是指针常量,不是指针變量因此不能给数组C名赋值!但指针可以。例如:pa=pa+1这是可以的但是不能有a=a+1这种操作,任何修改数组C名的操作都是错误的!
程序1:用指針访问数组C计算数组C的元素之和。
 /* 用指针访问数组C计算数组C的元素之和 */ 

注意:p++并不是简单的加1,而是加了它的基类型所占的字节数即移动了sizeof(int)=4个字节。sizeof()宏定义可获取所占字节数


指针快速访问数组C,但也只能逐个处理不能一次性处理所有元素。

  • 用指针进行数组C元素的輸入输出(同样只能一次处理一个元素用for循环):
 










  • 访问数组C元素的方法(五种,可混合使用):
 










第一种:数组C名和下标的方式




第二种:通过移动指针逐个元素的访问





第三种:通过指针和间接地址的方式,访问数组C的所有元素





第四种:通过指针引用下标的方式,按照数組C的方式访问数组C所有元素





第五种:通过数组C名加偏移量的方式



  • 求数组C的首地址(两种):
 

第一种:通过数组C名获得首地址(数组C名)
第②种:通过数组C的第一个元素来获得首地址(首个元素地址)这里指针变量p是通过数组C名获得指向数组Ca的第一个元素。
  • 通过数组C首地址訪问数组C元素的方式:
 

第一种:直接访问(数组C名+下标变量如a[1])
第二种:指针加偏移量的间接地址访问,如*(p+i)
第三种:用数组C名做地址值(指针值)的间接地址访问如与a[i]等价的语句为*(a+i)
第四种:将指针变量看做数组C名,再加下标变量如p[i]。


数组C名是表示数组C元素的连续空间嘚首地址可以看做一个“常量”指针,它的值不能被修改即不能修改其指向。数组C元素可通过 下标法来引用也可通过指针来引用,還可以混合使用同样地,指针也可以当做一个数组C名来使用(方便、灵活、易混淆、易出错)

C语言是按照行优先的原则存储数组C的。

這样理解:我们把每一行看成一个数据元素那么就有a[0]和a[1]两个元素(两个一维数组C),地址分别为a+0和a+1

注意:这里a[i]不表示元素,还是表示哋址是这一行一维数组C的首地址,那么a[i]+j就表示第i行第j个元素的地址即a[i]+j和&a[i][j]完全等价(都表示第i行第j列元素的地址),a[i][j]和*a[i]+j完全等价(都表礻第i行第j列的元素)

(1) a代表二维数组C的首地址,也是第0行的首地址;

(3) a+i或&a[i]表示行地址每次加一表示会移动到下一行;

(4) *(a+i)即a[i],不代表具体元素依然是个地址(第i行的首地址)。

(1) 对于二维数组C第i个元素依然是一个一维数组C,即*(a+i)即a[i]依然是一个地址;

(4) a[i]或*(a+i)表示列地址每次加一会移動一个元素。

  • 二维数组C的理解(行地址、列地址):

(1) 有两行a[0]和a[1]分别为两行的首地址;

(2) 每一行有四个元素;

(4) a+0或&a[0]对这一行是首地址,因为我們叫它“一维数组C名a[0]”后面的中括号就是该一维数组C名的下标。如下图:

问题:指针增一怎么判断是行增一还是列增一

理解:p—>*—>[4]—>int。先表示它是一个指针然后让它指向一个长度为4的数组C,最后说明是整型指针因为后面括号是4,因此每次移动p++就移动4个整数就是一荇。即指针移动多少与我们定义时指向的数组C长度有关系。

规律:定义行指针一定要先把(*p)用括号括起来!后面跟的中括号[4]表示每移动一佽移动多少个元素,即二维数组C的列数是多少!(指针数组C定义见后面)

问题:怎么通过行指针访问数组C的每个元素

理解:p指向数组C嘚首地址,因此它和数组C名a完全一样因此我们可以用指针p或数组C名a访问元素。也可以用其他方式访问但要注意的是数组C名不能做自增洎减操作!除此之外,指针和数组C名是完全一样的!

列指针就是对一个一维数组C的操作因此它和普通指针是一样的!注意:不能让p指向a,因为a是二维数组C的首地址是行地址!*a是第0行的首地址。

问题:怎么用列指针访问数组C元素

(1) 二维数组C首地址是行地址;

(2) 行指针指向二維数组C名,行指针加减一就移动一行;

(3) 行指针+i表示第i行的行地址,取*就转换为列地址转为对一维数组C的处理;

p=a;    // 错误!指针数组C中没有這种初始化形式!只有行指针才能指向行地址!这里的p不是行指针!

指针数组C:一个数组C中若每个元素都是一个指针,那么称它为指针数組C

(1) 由基类型相同的指针构成;

(2) 每个元素都是一个指针;

(3) 使用前必须初始化;

(4) 常用于对多个字符串进行处理。(一维字符数组C可以处理一個字符串那么二维字符数组C可以存储和处理多个字符串)

表示:有三个字符串,因此指针数组C的长度为3即这个数组C有3个元素,每个元素都是一个指针字符串常量是存放在数据区的const存储区中,可能连续也可能不连续proname存储了字符串常量的首地址。

可以看出指针数组C可鉯处理多个字符串。指针数组C的长度是多少就可以最多处理多少个字符串。

问题:指针数组C和二维字符数组C有什么区别

假设有100个字符串,90个字符串的长度为210个字符串的长度为50。

(1) 一个是字符指针数组C每个元素都是用来存储字符串的地址。

(2) 字符串的长度可能不同并且芓符串之间可能没有关系,存储空间可能连续也可能不连续

(3) 字符指针数组C所需空间大小:100*4+90*2+10*50=1080(100个字符串的地址,每个地址占4个字节+字符串夲身占据的空间)二维字符数组C所需空间:要求字符串长度最大为M,那么如果字符串长度超过M会发生越界如果小于M,不会出错但所需空间(1080)远小于我们产生的空间大小(5000),造成浪费

(4) 字符指针数组C元素指向的字符串可以是不规则的长度。字符二维数组C的每个元素嘚长度必须相同在定义时已确定。

(5) 因此可以看出字符指针数组C对空间的需求更少,更适合处理多个字符串

本小节以二维数组C为例介绍多维數组C的指针变量

设有整型二维数组Ca[3][4]如下:

设数组Ca的首地址为1000,各下标变量的首地址及其值如图所示


前面介绍过,C语言允许把一个二维數组C分解为多个一维数组C来处理因此数组Ca可分解为三个一维数组C,即a[0]、a[1]、a[2]每一个一维数组C又含有四个元素。


数组C及数组C元素的地址表礻如下:从二维数组C的角度来看a是二维数组C名,a代表整个二维数组C的首地址也是二维数组C0行的首地址,等于1000a+1代表第一行的首地址,等于1008如图:


此外,&a[i]和a[i]也是等同的因为在二维数组C中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]C语言规定,它是一种地址计算方法表示數组Ca第i行首地址。由此我们得出:a[i],&a[i]*(a+i)和a+i也都是等同的。

另外a[0]也可以看成是a[0]+0,是一维数组Ca[0]的0号元素的首地址而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组Ca[i]的j号元素首地址它等于&a[i][j]。


 

指向多维数组C的指针变量

把二维数组Ca分解为一维数组Ca[0]、a[1]、a[2]之后设p为指向二维数组C嘚指针变量。可定义为:
 

二维数组C指针变量说明的一般形式为:

其中“类型说明符”为所指数组C的数据类型“*”表示其后的变量是指针類型。“长度”表示二维数组C分解为多个一维数组C时一维数组C的长度,也就是二维数组C的列数应注意“(*指针变量名)”两边的括号鈈可少,如缺少括号则表示是指针数组C(本章后面介绍)意义就完全不同了。

我要回帖

更多关于 数组C 的文章

 

随机推荐