C指针与数组的混合运算(补充指针的内容)_第1页
C指针与数组的混合运算(补充指针的内容)_第2页
C指针与数组的混合运算(补充指针的内容)_第3页
C指针与数组的混合运算(补充指针的内容)_第4页
C指针与数组的混合运算(补充指针的内容)_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、本文不是一篇初学者读者文章,本文不会对基本的指针概念等作介绍,本文是针对本人的关于指针的一篇补充性文章,本文重点在于介绍指针与数组的计算,让读者学会怎样计算指针,让读者不再被指针和数组所困火,希望本文会给你带来一定的帮助。本文内容完全属于个人见解,其中难免有误解之处,望指出更正。指针的计算1、指针与数组(对指针的透彻理解)1、两条基本准则:a、首先要明白,指针运算符的作用,我用一言以概之,你在哪里使用都不会错。指针运算符*的作用是求出*后面所指地址里的值。因此只要*后面的变量表示的是一个地址就可以使用*运算符,来求出这个地址中的值,你不用管这个地址的表示形式是怎样的,只要是地址就可以使用*来求

2、出地址中的值。b、 这个运算符的的运算法则是,把左侧的地址加上 内的偏移量然后再求指针运算,注意有 运算符的地方就有个隐含的指针,比如x2表示的就是将指针x偏移2个单位量后再求指针运算。也就说x2与*(x+2)是相等的。2、对数组的讲解:a、对数组名的理解:大家都知道数组名是一个指针,但是这个指针是一个常量,也就是说不能改变他所指向的地址,比如你不能把另一个变量的地址赋给数组名,比如a=&i; 其中a是数组名,这就是错误的。再比如char a11; a=”hy”;这也是错误的,因为a是数组名是常量,不能把字符串常量”hy”的首地址赋给数组名以此来改变数组名所指向的地址,这是很多人容易范

3、的错误,要把字符串赋给数组应是这样char a11=”hy”; 这是初始化,初始化不会改变数组名所指向的地址。b、一维数组我们基本上都是这样理解一维数组的数组名的,即一维数组的数组名表示的是数组的首地址,比如一维数组a11中的数组名a就表示数组的首地址。首先在这里要明白,这种理解是错误的,因为数组名不是表示的是数组的首地址,他是表示的数组中第一个元素的地址,因此数组名a其实表示的是&a0的地址,而表示数组的首地址的是&a,因为a表示的是一个包含有4个元素的一维数组,因此&a表示的就是一个包含有4个元素的一维数组的地址,也就是说&a的地址中包含了4个元素。注意:a

4、和&a表示的地址是相同的,使用输出语句可以很明显的看到。也就是说数组中第一个元组的地址和数组的首地址是相等的,但是他们的意义却有很大不同,在后面的计算中你将会看到。c、二维数组:比如二维数组b34,我们首先从一维开始分析,众所周知b0,b1分别表示的是二维数组中第一行第一个元素和第二行第一个元素的地址,也就是说b0是与&b00等价的,b1是与&b10等介的。因此数组名b就与&b0等价的,因为b0包含有4个元素,因此数组名b或者&b0表示的是二维数组中第一行所包含的一维数组的地址,说简单一点,就是说二维数组名是二维数组中第一行的行地址。因此二维数组名b所包

5、含的地址中包含有二维数组中第二维中元素的个数的一维数组,也就是b的地址中包含一个含有4个元素的一维数组的地址(也就是所谓的数组的数组了)。d、N维数组:通过上面对一二维数组的语言描术,可以总结一些规律(因为维数大于3的数组就难以用语言来描术,只能通过数学计算来解决地址问题):1:数组名a是与&a0等价的,不管是多少维数组,这条规律都是必定的。2:a(中括号中的下标省掉,只要括号中的下标不超过界限都适合本规律)只要不是表示的最后一维,也就是说他表示的是地址而不是具体的元素,则a都与&a0等价的。e、为什么我们要把a解释为&a0:在计算时你就会看到,a并不是表示的真正的地址

6、,而&a0才是表示的真正的地址,也就是说对于a1+1不等于a2,因为a1并不是表示的具体的地址,因为他所表示的地址是&a10,因此a1+1=&a10+1=&a11,我们看到了,只有把a表示为&a0才能和后面的整数直接相加,这一点非常重要,一定要记住。2、指针和 的混合计算法则(以下假设b为二维数组b34):1、首先要明白,指针运算符的作用,我用一言以概之,你在哪里使用都不会错。指针运算符*的作用是求出*后面所指地址里的值。因此只要*后面的变量表示的是一个地址就可以使用*运算符,来求出这个地址中的值,你不用管这个地址的表示形式是怎样的,只要是地址就可以使用

7、*来求出地址中的值。2、 这个运算符的的运算法则是,把左侧的地址加上 内的偏移量然后再求指针运算,注意有 运算符的地方就有个隐含的指针,比如x2表示的就是将指针x偏移2个单位量后再求指针运算。也就说x2与*(x+2)是相等的。3、对于b1这样的地址,一定要表示为&b10再进行偏移计算,比如对于b1+1,这不是直接在对b1加1,也就是b1+1不等于b2,因为b1表示的是第二行行1个元素的地址,对其加1,应该表示的是第二行第二个元素的地址,也就是&b11,而b2则表示的是第二行第一个元素的地址,因此错误,所以在计算时应把b1转换为&b10之后,才能直接进行地址的偏移,也就是

8、说b1+1=&b10+1=&b11,这样才能得到正确的结果,并且不会出错。4、对于有小括号的地方,一定不要省略小括号。比如(&b1)1与&b11将表示的是不同的结果,第二个是显然的,对于第一个(&b1)1=*(&b1)+1)=*(&b1+1)=*(&b2)=b2,可以看到,表示的是第3行第1个元素的地址,因此这两个的结果是显然不一样的。因此对于(b+1)1这样的运算,不能省略小括号,即(b+1)1=(&b1)1=*(&b1)+1)=*(&b1+1)=*(&b2)=b2,如果省略了小括号,则是(b+1

9、)1=&b11,这将是不易发现的错误。因此这是两个完完全全不同的符案。5、对于指针,只要指针指向了数组,不管他是多少重指针,都可以使用这些计算法则。注意:对于有指针运算符*和下标运算符的混合运算时,最好使用计算表达式的方式采用数学的方法来得出正确的结论,因为用语言来描术这类的综合运算,弯过来弯过去的很容易出错,如果用数学方式,结合C中的运算符优先级来运算,只要弄懂指针的首地址,然后从优先级高的运算符开始运算,这样得到的结果是不会出错的。比如,对于(*(b+1)1其中b是二维数组b34。如果用语言去描术很容易出错,如果掌握好下面的数学计算方法,然后逐步计算,就很容易得出正确答案,而且简单

10、易懂,只要把数组b表示的地址弄懂,也就是b=&b0,然后再计算,就很容易得到答案了。下面先用语言描术一些基本理论,然后再讲解具体的计算方法。下面讲解一些示例(假设b为二维数组b34):例1:*(b+1)=*(&b0+1)=*(&b1)=b1例2:*(*(b+1)+1)=*(*(&b0+1)+1)=*(*(&b1)+1)=*(b1+1)=*(&b10+1)=*(&b11)=b11例3:(*(b+1)1=(*(&b0+1)1=(*(&b1)1=(b1)1=*(b1)+1) /把b1拆分为*(b+1);=*(&b10+1

11、)=*(&b11)=b11例4:(b+1)1=(&b0+1)1=(&b1)1=*(&b1+1)=*(&b2)=b2例5:*(b+1)1=*(&b0+1)1=*(&b1)1=*(*(&b1+1) /注意 运算符优先级比*指针运算符高,把以应先计算(&b1)1=*(&b1+1)=*(*(&b2)=*(b2)=*(&b20)=b20方法2:*(b+1)1=*(b+1)+1)=*(b+2)=*(*(b+2)=*(*(&b0+2)=*b2=b20例6:(*(b+1)5=(*(&b1)5=(b1

12、)5=*(b1+5)=*(&b10+5)=*(&b15)=b153、对于多重指针的计算。比如int a11=0; int *p1=a; int *p=&p1; 注意,因为int *p=&p1与int *p; p=&p1相同,可以看到p=&p1因此在计算的时候,只有出现p的地方,都可以把其替换为&p1,同理p1=a;因此可以把p1替换为a,最后可以把p替换为&a来计算,这样的话,在对多重指针的计算时就比较简单了。比如*p+1=*(&a)+1=a+1=&a0+1=&a1,同理p+1=&a+1;当然&am

13、p;a+1将是一个不明确的地址,这样看实际情况来处理。如果a不是数组,而是一个整型常量,比如int a;则不存在指针的相加减运算,因为对整型变量的地址偏移,必定会得到一个不明确的地址。指针指向整数变量(其他非数组变量也是类似的)只能有p+0这样的运算,只要p+1就会偏移到不确定地址。4、对于指针数组的计算int *p4对于指针数组的计算可以采用二维数组的计算法则:比如int *p4,则*p+1=*(&p0)+1=p0+1=&p00+1=&p01;因此*p+1表示的是指针p0所指向的第2个元素的地址,但要注意,如果p0不是指向的数组,则这是错误的表达式,比如p0=&

14、;i; 其中变量i是int型的,则*p+1将会是一个不可预测值的地址,使用*(*p+1)将得到一个不可预测的值,如果p0指向的是一个一维数组,比如p0=a; 其中a是一个一维数组,则*p+1表示的就是数组a中的第2个元素(下标为1),使用*(*p+1)将会输出这个值。因此&p01应把p0整体理解为一个指针,你也可以把p0使用不是数组类型的指针来代替,比如q,则p01就是q1,然后再来看q是指向的什么。因此对于指针数组同样可以使用上面的法则进行计算,但要把计算之后的结果p进行相应的简单理解,即,应把p理解为是一个指针。5、数组指针与二维数组讲解:下面我们将以y4=1,2,3,4这个一维数

15、组为例来层层讲解,指针和数组的关系。1、数组指针:定义形式为:int (*p)4;表示定义了一个指向多维数组的指针,即指针p指向的是一个数组,这个数组有4个元素,对这个指针p的赋值必须是有4个int元素的数组的地址,即只要包含有四个元素的数组的地址都能赋给指针p,不管这个数组的行数是多少,但列数必须为4。即int y4,x224;都可以赋给指针p。赋值方式为p=&y或p=x,对于&y和二维数组数组名前面已讲过,&y中的地址是一个包含有4个元素的一维数组的地址,二维数组名x也是一个含有4个元素的一维数组的地址,因此可以这样赋值。而这样赋值将是错误的p=y,或者p=x0;

16、因为y和x0的地址只包含一个元素,他们不包含一个数组,因此出错。2注意()必须有,如果没有的话则,int *p4;则是定义了一个指针数组,表示每个数组元素都是一个指针,即p2=&i;指向一个int型的地址,而*p2则表示p2所指向的元素的值。3初始化数组指针p:a、当把int y4赋给指针p时p=y将是错误的,正确的方式为p=&y因为这时编译器会检查赋给指针p的元素是否是含有四个元素的数组,如果是就能正确的赋值,但语句p=y中的y代表的是数组y4第一行第一列的元素的地址也就是&y0的地址,因此y指向的地址只有一个元素,而指针p要求的是有4个元素的数组的地址,因此语句p=

17、y将出错。而&y也表示的是一个地址,但&y包含了数组y4的第一行的所有元素,在这里&y包含有4个元素,因此p=&y才是正确的赋值方法,在这里要注意,数组的某行的行地址是第本行的第一个元素的地址是相同的。b、把x224赋给指针p有几种方法,方法一:p=x;我们这样来理解该条语句,首先x0表示的是二维数组x224的第1行第一列元素的地址,这个地址包含一个元素,这是显而易见的,而数组名x也表示一个地址,但这个地址包含的是一个数组(即数组的数组),这个数组是包含4个元素的数组,这4个元素就是数组x第一行的4个元素,也就是说x表示的是数组x224的第1行的行地址,即数组名

18、x就包含了数组x224第1行的4个元素,因此这种赋值方式是正确的。这时指针p就相当于是数组名一样,比如p21访问的就是数组x的第3行的第2个元素。c、方法二:p=x+1或者p=&x1;注意必须要有地址运算符&,同理语句&x1表示的是数组x224第2行的行地址,因为x1表示的是数组x224第的第2行第1列的元素的地址,因此&x1表示的就是数组x的第2行的行地址,因为&x1这个地址包含了一个数组,这个数组的起始地址是从x1这个地址开始的,这,即数组x224中x1这一行的4个元素。在这一行中包含了4个元素。这时指针p的起始地址是&x1,所以p01不再是访问的x的第一行第二个元素,而是访问的x的第二行第二个元素。d、注意,再次提示,数组的某行的行地址是与本行的第一个元素的地址是相同的。4、数组指针的计算数组指针的计算与上面介绍的指针与数组的计算法则相同,但计算之后表示成的二维数组形式p12要注意看指针p的起始地址是哪一行,然后才能确定输出哪个元素,比如p起始地址是二维数组的第1行,则p12表示的是第2行第3个元素,但若p指向的是二维数组的第二行(也就是起始地址在二维数组第2行),则这时p12就表示的是第3行第3个元素了。6、int (&p)4引用int (&a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论