学习指针万用表要求掌握的技能(最终版)

时间:2019-05-15 05:19:48下载本文作者:会员上传
简介:写写帮文库小编为你整理了多篇相关的《学习指针万用表要求掌握的技能(最终版)》,但愿对你工作学习有帮助,当然你在写写帮文库还可以找到更多《学习指针万用表要求掌握的技能(最终版)》。

第一篇:学习指针万用表要求掌握的技能(最终版)

学习指针万用表要求掌握的技能

1、掌握万用表使用原则

2、知道一些指针万用表和数字万用表的区别

3、掌握指针式万用表的测量计算原理

4、熟练掌握单手操作

5、会保护维修万用表的表笔

6、万用损坏后,能根据先前操作和现象,判断万用表损坏原因,7、区分在什么情况下进行欧姆调零和机械调零,并掌握其用法

8、会选择合适的档位测量电阻,会欧姆调零,会读数,会计算。

9、熟练掌握在不同档位(1000v、500v、250v)测量插座电压,会读数,会计算

10、熟练判断零线和火线,掌握握笔方法,知道其安全原理

11、熟练测量直流电压和直流电流,知道直流和交流的不同之处,知道测量电压和电流的不同之处,且要会读数,会计算

12、会使用万用表的标准电阻箱

13、知道9v电池和1.5v电池对万用表测量的影响,知道10k档位的作用。

14、知道交流电压档10v档位使用的是独立的刻度线

15、知道如何测量三极管的放大倍数

16、知道如何测量1000v以上的交流电压和直流电压,并会选择档位,会选择插孔,会计算。

17、知道如何测量500mA以上的直流电流,并会选择档位,会选择插孔,会计算。

18、会测量电池电量是否充足,并会选择档位,会看表盘。

19、知道表盘上标号的意思

第二篇:磁电式指针万用表原理与维修总结

磁电式指针万用表维修总结

MF-47型指针万用表原理与维修经验总结

指针系仪表分为磁电式和电磁式两种,现在的指针万用表都是以磁电式仪表为主,由于电磁式仪表灵敏度较低,所以电磁式仪表一般应用在工业用电的电压表和电流表中,磁电式仪表根据磁路不同分为,内磁,外磁,内外磁,三种,其中外磁表头的指针万用表很容易受到外磁场的干扰而引起测量不准现象,所以外磁表头的指针万用表一般会在万用表后盖板上设计一块金属屏蔽板,金属屏蔽板的作用就是屏蔽外界电磁场干扰让表头测量的更佳精准,因为外磁表头很容易引入外界电磁场干扰,而引起测量不准现象,所以通过在万用表后盖板上加装金属屏蔽板来进行外磁屏蔽,从而让外磁表头测量的更佳精准,而内磁表头一般是不会设计的,因为内磁表头不易引入外磁场干扰,内磁表头抗干扰能力强。

下面介绍下磁电式仪表的内部构成:

磁电式仪表内部有两部分组成一部分是可动部分一部分是固定部分,固定部分:磁钢,可动部分:弹簧游丝,指针,阻尼器,这两部分组成,其中磁钢的作用主要是通入电流产生磁场力,弹簧游丝的作用主要是产生反作用力矩带动表针偏转,阻尼器的作用是,当指针受到磁场力的作用而偏转时会产生一定的惯性而阻尼器的作用就是吸收这部分惯性让指针可以尽快的停止在某一点上以达到快速读数的目的。

下面讲解一下:磁电式仪表的工作原理:

现在所有机械式万用表(即指针万用表)都是磁电式仪表,磁电式仪表根据磁路不同,分为内磁,外磁,内外磁三种,其工作原理是:当电流通入表头内部的磁钢时,电流切割磁感线,会产生一个磁场力也就是我们所谓的(转动力矩),这个磁场力(转动力矩)会带动表头内部的弹簧游丝,弹簧游丝会带动指针偏转,根据通入表头内部磁钢电流大小不同,产生的磁场力强弱也不同,从而游丝带动指针偏转的幅度也不同,也就是说,通入磁钢电流越大,产生的磁场力越强,所以弹簧游丝带动指针偏转的幅度也就越大说明被测信号很大,反之,通入磁钢电流越小产生的磁场力越弱,所以游丝带动指针偏转的幅度也就越小说明被测信号很小,通过这个原理实现测量信号的大小。而弹簧游丝的作用主要是产生反作用力矩的装置,我们知道指针偏转是受到磁场力(转动力矩)的作用而偏转,而游丝主要是产生一个反作用力矩,简单的来讲,游丝主要是产生一个与磁场力相反的力矩,我们称它为反作用力矩,当磁场力(转动力矩)与游丝产生的反作用力矩相等时指针停止,磁场力(转动力矩)带动指针向右偏转,游丝自身产生一个反作用力矩向左拉抻指针,当磁场力(转动力矩)与游丝产生的反作用力矩相等时,指针停止从而读数。如果只有磁场力(转动力矩)没有游丝产生的反作用力矩的话不管测量的信号有多大指针都会偏转到头。

下面以国产MF-47为例讲解指针表原理与维修:

MF-47型指针表的表头是一个微安(μA)级的直流电流表,它的满偏转度为46.2微安,也就是说表头满篇电流为46.2微安,其工作原理:当有电流信号流过表头,表针会受到磁场力的作用而偏转,(因为有电流的地方就会产生磁场)根据磁场力大小不同,表针偏转的幅度也不同,也就是说,流过表头电流越大产生的磁场力越强,所以游丝带动表针偏转的幅度也就越大,流过表头电流越小,产生的磁场力越弱所以游丝带动表针偏转的幅度也就越小,它们成正比关系。即电流越大磁场力越强,游丝带动指针偏转幅度也就越大,电流越小,磁场力越弱,游丝带动指针偏转的幅度也就越小。

指针万用表调零方法与调零原理:

机械调零:指针没有指向0位使用螺丝刀拧动机械调零旋钮将指针归0,机械调零原理:机械调零旋钮内部接着一个机械调零螺丝,通过拧动机械调零旋钮相当于拧动机械调零螺丝,从而将指针归0 欧姆调零:将万用表打到电阻挡,因为在万用表里只有电阻挡才用内部电池工作,短接表笔相当于短接内部电池有电流流过表头,表针偏转,表针没有指向0位,拧动电阻调零电位器将指针归0,欧姆调零原理:电阻调零电位器控制一个可调电阻,通过拧动电阻调零电位器相当于改变可调电阻的电阻值从而改变流过表头电流大小来进行调零。

测量原理: DC:直流 AC:交流

DCV直流电压挡测量原理:通过与表头串联电阻分压来扩大电压挡测量量程,因为测量的是直流信号,所以不用走半波直接可以走表头来测量,通过改变直流电压挡中串联分压电阻的阻值就可以改变测量量程的范围,每个档位的分压电阻都要与保险管相连接。

DCmA直流电流挡测量原理:通过与表头并联电阻分流来扩大电流挡测量量程,改变直流电流挡中并联分流电阻的阻值就可以改变测量量程的范围,每个档位的分流电阻都要与保险管相连接。

ACV交流电压挡测量原理:通过与表头串联电阻分压来扩大交流电压挡测量量程,在走半波整流电路将交流信号整流变为直流信号流过表头来测量,因为指针表的表头是一个直流电流表,表头无法流过交流信号所以必须要在交流电压挡中加上一个半波整流电路做整流器将被测量的交流信号整流变为直流信号流过表头来测量,所以说测量一次交流电就要经过整流二极管整流一次,交流电压挡必须走整流器要将被测量的交流信号整流变为直流信号流过表头来测量。交流电压挡相当于是在直流电压挡的电阻串联分压来扩大电压挡量程基础上加装了一个整流器,构成了交流电压挡。

当交流电正半周时经过D1整流将交流信号整流变为直流信号流过表头来测量,交流电负半周时经过D2整流,这里的D2是为了保护D1整流二极管,为了防止 交流电正负半周时都经D1整流,由于交流电压信号过大很容易将D1击穿,所以加了一个D2整流二极管,这样的话正半周时经过D1整流将交流信号变为直流信号流过表头来测量,负半周时经过D2整流将交流信号整流变为直流信号流过表头来测量。

Ω电阻挡测量原理:电阻挡是在万用表里唯一使用电池工作的档位,MF-47指针表内部有两块电池一块1.5V一块9V,电阻挡共分为五个量程,其中RX10K独立使用内部9V电池供电 RX1K RX100 RX10 RX1四个档位共用内部1.5V,如果被测电阻阻值很大,则流过被测电阻的电流就很小,这时候表针偏转的幅度就很小说明被测电阻阻值很大,反之如果被测电阻阻值很小,则流过被测电阻的电流就很大,这时候表针偏转的幅度也就很大,说明被测电阻的阻值很小,通过这个原理实现测量电阻的大小。

MF-47万用表保护电路讲解:

1:表头保护:表头钳位保护,利用两只IN4001硅整流二极管并联构成双向限幅二极管接入表头目的是防止勿用电流挡去测量电压而烧表头这样的话输入电压信号会被双向限幅二极管牵制在0.7V即硅二极管导通电压,从而来保护表头。

表头跨接电容C1作用是给表头滤波,防止流过表头的直流信号有杂波影响测量误差,R1是限流保护电阻,防止流过表头电流过大而烧表头。

2:所有档位使用闭路式分流器:直流电压挡。交流电压挡,直流电流挡所有分压电阻和分流电阻都是串联起来的这样的话一只分压电阻或分流电阻损坏该档位所有量程都是无法使用的。

3:输入保险管:FUSE 250V/0.5A输入电流值大于(AC/DC)0.5A该保险管会自动熔断,以达到保护后级电路目的。

新型天宇MF-47,电阻挡设计一个压敏电阻,做过压保护元件,为了防止用电阻挡去测量220V交流电压而烧电阻挡电阻,以及其它元件,所以在电阻中设计一个压敏电阻,即使使用万用表电阻挡去测量220V电压也不比害怕烧表。

指针万用表故障维修讲解:

指针万用表表头故障讲解:现在的所有指针万用表都是磁电式表头,磁电式表头构成:磁钢,动圈,阻尼器,弹簧游丝,以及指针几部分组成,其中磁钢的作用是通入电流产生磁场力,弹簧游丝的作用主要是产生反作用力矩带动指针偏转,阻尼器的作用是当指针受到磁场力的作用而偏转时会产生一定惯性而阻尼器的作用就是吸收这部分惯性让指针可以尽快的停止在某一点上以达到快速读数的目的。

表头故障维修:表头维修讲解: 故障1:指针无法偏转,首先要检查万用表保险管,防止内部输入保险管被烧断引起没有电流输入,从而导致表针无法偏转,第二步,如果保险管正常,则要试试所有档位,即直流电压挡,交流电压挡,直流电流挡,看看所有档位测量的时候指针是否都无法偏转,如果所有档位在测量时指针都无法偏转则说明故障在表头,因为保险管是好的,但是所有档位都无法用,这么说的话,万用表内部直流电压挡串联分压电阻,和交流电压挡串联分压电阻和整流器,以及电流挡的分流电阻不可能全部损坏,所以说,指针不动的原因就是由于表头有问题引起的,检查方法如下,可以通过测量表头满篇电流,当然如果觉得麻烦的话可以采取更换一个同样大小的表头。

表头维修讲解: 故障2:指针偏转幅度较大,如果测试中发现,所有档位测量信号的时候,指针偏转幅度都很大,超过测量中的实际值,排除,保险管有问题,在排除内部分压分流电阻有短路或开路现象,则要检查表头,检查:表头内部的平衡锤,弹簧游丝,弹簧游丝是重点检查的对象,因为我们知道游丝的作用是产生反作用力矩带动指针偏转,而让指针偏转的是磁场力,磁场(转动力矩),光有磁场力(转动力矩)没有游丝产生的反作用力矩的话,不管测量的信号有多大指针都会偏转到头,所以如果游丝损坏就会出现测量的时候指针偏转幅度较大,或者是测量信号不准,就是由于游丝损坏,或游丝变形引起的故障。可以采取更换游丝,或换掉表头排除故障。(换游丝比较麻烦所以最好更换表头)

表头维修讲解: 故障3:指针偏转幅度很小,如果出现测量信号的时候指针几乎不偏转,排除保险管被烧断的故障,排除万用表内部电池没电,以及万用表内部电路中分压分流电阻损坏,(内部的分压电阻和分流电阻不可能全部损坏),则故障肯定出现在表头,重点检查表头,指针偏转的幅度比较小的故障,一般在与表头内部磁钢失磁引起的该故障发生,由于将指针万用表长时间放在离磁场干扰能力强的地方,磁电式仪表的表头内部磁钢失磁,引起该故障发生,可用充磁机给表头充磁,当然也可以采用更换表头,淘宝网上我记得MF-47表头是5块钱。表头故障维修: 故障4:指针偏转的时候左右乱晃,这个故障其实很简单,故障出现在表头,是由于磁电式仪表内部的指针阻尼器损坏,就是阻尼器损坏或阻尼器性能不良引起的该故障发生,可以采用更换新表头来维修。表头维修很简单就这么几个东西.指针偏转幅度大或者测量不准的话,多数就是游丝损坏,指针偏转幅度小的话,多数就出现在磁钢失磁或线圈烧断引起的,而指针偏转左右乱晃多数就是阻尼器损坏引起。

电路故障维修:

指针万用表电路维修:故障1:输入保险管250V/0.5A被烧断引起没有电流输入,所有档位无法使用(所有档位测量时指针不动)的故障,这个故障算是在修万用表中最简单的了,由于使用失误,用电流挡去测量电压,或用电阻挡去测量电压,引起的将输入保险管被烧断导致的没有电流输入故障,维修方法很简单将万用表拆开测下输入保险管发现已经被烧断换掉一个同型号同规格保险管故障修复。47型指针万用表 保险管规格为250V/0.5A 换掉一个新保险管故障修复。

指针万用表电路维修:故障2:交流电压挡中整流器中半波整流电路中的两只整流二极管击穿或开路引起交流电压挡无法正常使用或测量不准的故障,我们知道指针万用表交流电压挡测量原理:通过与表头串联电阻分压来扩大交流电压挡量程,在走半波整流电路将交流信号整流变为直流信号流过表头来测量,因为指针万用表的表头是一个直流电流表表头无法流过交流信号所以必须要在交流电压挡中加上一个半波整流电路做整流器将交流信号整流变为直流信号流过表头来测量,所以说测量一次交流电就要经过整流二极管整流一次,如果长时间测量交流电的话,整流二极管由于经常会被交流信号冲击,一般会遇到开路或短路的情况这点是很常见的故障,所以说如果遇到指针万用表交流电压挡无法使用的故障,上来先检查保险管,因为保险管被烧断会引起没有电流输入表针肯定不会动的,如果万用表保险管正常交流电压挡还是无法使用,则要先检查电刷与电路板转换开关触点是否接触松动或接触不良,排除接触不良交流电压挡还是无法正常使用,则要重点检查交流电压挡中的几只分压电阻,检查分压电阻有无阻值变化现象或开路现象,如果有就先换掉分压电阻,排除分压电阻有损坏,交流电压挡还是无法正常使用,则应该重点检查交流电压挡中的整流器中半波整流电路中的两只整流二极管的正反向电阻值,可能是由于整流二极管击穿或开路引起的交流电压挡无法使用或测量不准的故障,如果检查中发现整流二极管有击穿或开路的现象,更换同型号的管子来修复该故障。

指针万用表电路维修: 故障3:电阻挡测量不准以及电阻挡无法使用的故障,由于9V电池和1.5V电池电压偏低引起该故障发生换新电池排除故障,电阻挡无法测量由于9V电池和1.5V电池接线有断线或虚焊现象,检查修复故障,电阻挡等效电阻有开路,转换开关的电刷与电路板触电接触松动,引起电阻挡无法使用的故障。

指针万用表电路维修: 故障4:电刷与电路板接触松动,引起万用表所有档位无法使用,指针无法偏转,维修方法很简单,将万用表拆掉,从新安装电刷,安装电刷之前清理电路板。这个故障很简单,由于电刷与电路板接触不良引起。

指针万用表电路维修:故障5:直流电流挡中分流电阻烧掉,引起电流挡无法使用,我们知道电流挡中分流电阻阻值都是比较小的,一般都是几欧姆或几十欧的分流电阻,如果使用失误用电流挡去测量电压,相当于短路电源,产生短路电流直接将分流电阻烧掉,所以要检查分流电阻好坏,这点应该注意。

指针万用表电路维修: 故障6:电阻挡所有档位调零不准,检查电池电压是否偏低,检查电池接线接线,排除这些电阻挡还是调零不准,检查电阻挡等效电阻有无损坏,等效电阻如果正常,调零还不准的话,通过测量表头偏转电流调节电位器,如果还是无法将指针归0则就是欧姆调零电路的故障,首先检查电阻调零电位器是否有虚焊或阻值变大的故障,如果电位器正常的话,则要检查与电位器相连接的可调电阻,如果检查可调电阻的时候,测出来可调电阻阻值明显变大则说明故障就在这个地方,换掉可调电阻故障修复,我们知道欧姆调零电路工作原理:电阻调零电位器接一个可调电阻,通过拧动电阻调零电位器相当于改变可调电阻的电阻值从而改变流过表头电流大小来进行调零,如果说,可调电阻阻值变大或阻值变小则可调电阻不受电位器控制,也就无法调节流过表头电流大小,从而出现的欧姆调零不准的故障。

指针万用表电路维修: 故障7:交直流电压挡分压电阻烧掉,我们知道电压挡分压电阻阻值都是比较大的,比如直流1000V接 10M分压电阻 500V接5M 250V接4M 50V接800K 10V接150K 交流电压挡1000V接2M 500V接1M 250V接800K 阻值都是比较大的不容易坏,容易坏的在10V量程以下的分压电阻,如果使用失误用10V量程以下的档位去测量高电压,一:输入保险管肯定被烧断,2:就是分压电阻容易烧坏,这点应该重点检查。

第三篇:C++“指针”学习建议

一.对于众多人提出的c/c++中指针难学的问题做个总结:

指针学习不好关键是概念不清造成的,说的简单点就是书没有认真看,指针的学习犹如人在学习饶口令不多看多学多练是不行的,下面是两个很经典的例子,很多书上都有,对于学习的重点在于理解*x和x的理解,他们并不相同,*x所表示的其实就是变量a本身,x表示的是变量a在内存中的地址,如果想明白可以输出观察cout<<*x“|”x;,当定义了int *x;后对x=&a的理解的问题。仔细阅读和联系下面的两个例子我想指针问题就不是难点了!

#include main(){ int a,b;/* 定义a,b两个整形变量用于输入两个整数 */ int *point_1,*point_2,*temp_point;/* 定义三个指针变量 */ scanf(“%d,%d”,&a,&b);/* 格式化输入a,b的值 */

point_1=&a;/* 把指针变量point_1的值指向变量a的地址 */ point_2=&b;/* 把指针变量point_2的值指向变量b的地址 */ if(a main(){ int a,b;/* 定义a,b两个整形变量用于输入两个整数 */ int *point_1,*point_2;/* 定义三个指针变量 */ scanf(“%d,%d”,&a,&b);/* 格式化输入a,b的值 */

point_1 = &a;/* 把指针变量point_1的值指向变量a的地址 */ point_2 = &b;/* 把指针变量point_2的值指向变量b的地址 */

compositor(point_1,point_2);/* 调用自定义的排序涵数,把a,b的地址传递给point_1和point_2 */ printf(“%d,%d”,a,b);/* 打印出a,b的值 */ } static compositor(p1,p2)int *p1,*p2;/* 定义形式参数p1,p2为指针变量 */ { int temp;/* 建立临时存储变量 */

if(*p1<*p2)/* 如果*p1

*p1 = *p2;/* 将*p1的值也就是a的值换成*p2的值也就是b的值,等价于a=b */ *p2 = temp;/* 将*p2的值也就是temp的值等价于b=temp */ } } /* 注意:此题与上题不同的是,直接改变了a于b的值达到真实改变的目的 */

二.C++指针使用方法解惑

“void ClearList(LNode * & HL)”

仔细看一下这种声明方式,确实有点让人迷惑。

下面以void func1(MYCLASS *&pBuildingElement); 为例来说明这个问题。在某种意义上,“*”和“&”是意思相对的两个东西,把它们放在一起有什么意义呢?。为了理解指针的这种做法,我们先复习一下C/C++编程中无所不在的指针概念。我们都知道MYCLASS*的意思:指向某个对象的指针,此对象的类型为MYCLASS。Void func1(MYCLASS *pMyClass);

// 例如: MYCLASS* p = new MYCLASS; func1(p);

上面这段代码的这种处理方法想必谁都用过,创建一个MYCLASS对象,然后将它传入func1函数。现在假设此函数要修改pMyClass: void func1(MYCLASS *pMyClass){ DoSomething(pMyClass); pMyClass = // 其它对象的指针 }

第二条语句在函数过程中只修改了pMyClass的值。并没有修改调用者的变量p的值。如果p指向某个位于地址0x008a00的对象,当func1返回时,它仍然指向这个特定的对象。(除非func1有bug将堆弄乱了,完全有这种可能。)

现在假设你想要在func1中修改p的值。这是你的权利。调用者传入一个指针,然后函数给这个指针赋值。以往一般都是传双指针,即指针的指针,例如,CMyClass**。MYCLASS* p = NULL; func1(&p);

void func1(MYCLASS** pMyClass); { *pMyClass = new MYCLASS; „„ }

调用func1之后,p指向新的对象。在COM编程中,你到处都会碰到这样的用法--例如在查询对象接口的QueryInterface函数中: interface ISomeInterface { HRESULT QueryInterface(IID &iid, void** ppvObj); „„ };

LPSOMEINTERFACE p=NULL;

pOb->QueryInterface(IID_SOMEINTERFACE, &p);

此处,p是SOMEINTERFACE类型的指针,所以&p便是指针的指针,在QueryInterface返回的时候,如果调用成功,则变量p包含一个指向新的接口的指针。

如果你理解指针的指针,那么你肯定就理解指针引用,因为它们完全是一回事。如果你象下面这样声明函数: void func1(MYCLASS *&pMyClass); { pMyClass = new MYCLASS; „„ } 其实,它和前面所讲得指针的指针例子是一码事,只是语法有所不同。传递的时候不用传p的地址&p,而是直接传p本身:

MYCLASS* p = NULL;

func1(p);

在调用之后,p指向一个新的对象。一般来讲,引用的原理或多或少就象一个指针,从语法上看它就是一个普通变量。所以只要你碰到*&,就应该想到**。也就是说这个函数修改或可能修改调用者的指针,而调用者象普通变量一样传递这个指针,不使用地址操作符&。

至于说什么场合要使用这种方法,我会说,极少。MFC在其集合类中用到了它--例如,CObList,它是一个Cobjects指针列表。

Class CObList : public Cobject { „„

// 获取/修改指定位置的元素

Cobject*& GetAt(POSITION position); Cobject* GetAt(POSITION position)const; };

这里有两个GetAt函数,功能都是获取给定位置的元素。区别何在呢?

区别在于一个让你修改列表中的对象,另一个则不行。所以如果你写成下面这样: Cobject* pObj = mylist.GetAt(pos);

则pObj是列表中某个对象的指针,如果接着改变pObj的值: pObj = pSomeOtherObj;

这并改变不了在位置pos处的对象地址,而仅仅是改变了变量pObj。但是,如果你写成下面这样: Cobject*& rpObj = mylist.GetAt(pos);

现在,rpObj是引用一个列表中的对象的指针,所以当改变rpObj时,也会改变列表中位置pos处的对象地址--换句话说,替代了这个对象。这就是为什么CObList会有两个GetAt函数的缘故。一个可以修改指针的值,另一个则不能。注意我在此说的是指针,不是对象本身。这两个函数都可以修改对象,但只有*&版本可以替代对象。

在C/C++中引用是很重要的,同时也是高效的处理手段。所以要想成为C/C++高手,对引用的概念没有透彻的理解和熟练的应用是不行的。

三.数据指针

在C/C++语言中一直是很受宠的;几乎找不到一个不使用指针的C/C++应用。用于存储数据和程序的地址,这是指针的基本功能。用于指向整型数,用整数指针(int*);指向浮点数用浮点数指针(float*);指向结构,用对应的结构指针(struct xxx *);指向任意地址,用无类型指针(void*)。

有时候,我们需要一些通用的指针。在C语言当中,(void*)可以代表一切;但是在C++中,我们还有一些比较特殊的指针,无法用(void*)来表示。事实上,在C++中,想找到一个通用的指针,特别是通用的函数指针简直是一个“不可能任务”。

C++是一种静态类型的语言,类型安全在C++中举足轻重。在C语言中,你可以用void*来指向一切;但在C++中,void*并不能指向一切,就算能,也失去了类型安全的意义了。类型安全往往能帮我们找出程序中潜在的一些BUG。

下面我们来探讨一下,C++中如何存储各种类型数据的指针。

C++指针探讨

(一)数据指针 沐枫网志

1.数据指针

数据指针分为两种:常规数据指针和成员数据指针

1.1 常规数据指针

这个不用说明了,和C语言一样,定义、赋值是很简单明了的。常见的有:int*, double* 等等。

如:

int value = 123;int * pn = &value;

1.2 成员数据指针

有如下的结构: struct MyStruct { int key;int value;};

现在有一个结构对象: MyStruct me;MyStruct* pMe = &me;

我们需要 value 成员的地址,我们可以: int * pValue = &me.value;//或

int * pValue = &pMe->value;

当然了,这个指针仍然是属于第一种范筹----常规数据指针。

好了,我们现在需要一种指针,它指向MyStruct中的任一数据成员,那么它应该是这样的子: int MyStruct::* pMV = &MyStruct::value;//或

int MyStruct::* pMK = &MyStruct::key;

这种指针的用途是用于取得结构成员在结构内的地址。我们可以通过该指针来访问成员数据: int value = pMe->*pMV;// 取得pMe的value成员数据。

int key = me.*pMK;// 取得me的key成员数据。

那么,在什么场合下会使用到成员数据指针呢?

确实,成员指针本来就不是一种很常用的指针。不过,在某些时候还是很有用处的。我们先来看看下面的一个函数: int sum(MyStruct* objs, int MyStruct::* pm, int count){ int result = 0;for(int i = 0;i < count;++i)result += objs[i].*pm;return result;}

这个函数的功能是什么,你能看明白吗?它的功能就是,给定count个MyStruct结构的指针,计算出给定成员数据的总和。有点拗口对吧?看看下面的程序,你也许就明白了:

MyStruct me[10] = { {1,2},{3,4},{5,6},{7,8},{9,10},{11,12},{13,14},{15,16},{17,18},{19,20} };int sum_value = sum(me, &MyStruct::value, 10);//计算10个MyStruct结构的value成员的总和: sum_value 值 为 110(2+4+6+8+ int sum_key = sum(me, &MyStruct::key, 10);//计算10个MyStruct结构的key成员的总和: sum_key 值 为 100(1+3+5+7+

+19)+20)也许,你觉得用常规指针也可以做到,而且更易懂。Ok,没问题: int sum(MyStruct* objs, int count){ int result = 0;for(int i = 0;i < count;++i)result += objs[i].value;return result;}

你是想这么做吗?但这么做,你只能计算value,如果要算key的话,你要多写一个函数。有多少个成员需要计算的话,你就要写多少个函数,多麻烦啊。指针

四.C++指针使用

在下列函数声明中,为什么要同时使用*和&符号?以及什么场合使用这种声明方式?

void func1(MYCLASS *&pBuildingElement);论坛中经常有人问到这样的问题。

本文试图通过一些实际的指针使用经验来解释这个问题。

仔细看一下这种声明方式,确实有点让人迷惑。在某种意义上,“*”和“&”是意思相对的两个东西,把它们放在一起有什么意义呢?。为了理解指针的这种做法,我们先复习一下C/C++编程中无所不在的指针概念。我们都知道MYCLASS*的意思:指向某个对象的指针,此对象的类型为MYCLASS。void func1(MYCLASS *pMyClass);

// 例如: MYCLASS* p = new MYCLASS;

func1(p);

上面这段代码的这种处理方法想必谁都用过,创建一个MYCLASS对象,然后将它传入func1函数。现在假设此函数要修改pMyClass: void func1(MYCLASS *pMyClass){ DoSomething(pMyClass);pMyClass = // 其它对象的指针 }

第二条语句在函数过程中只修改了pMyClass的值。并没有修改调用者的变量p的值。如果p指向某个位于地址0x008a00的对象,当func1返回时,它仍然指向这个特定的对象。(除非func1有bug将堆弄乱了,完全有这种可能。)

现在假设你想要在func1中修改p的值。这是你的权利。调用者传入一个指针,然后函数给这个指针赋值。以往一般都是传双指针,即指针的指针,例如,CMyClass**。MYCLASS* p = NULL;func1(&p);void func1(MYCLASS** pMyClass);{ *pMyClass = new MYCLASS;„„ }

调用func1之后,p指向新的对象。在COM编程中,你到处都会碰到这样的用法--例如在查询对象接口的QueryInterface函数中:

interface ISomeInterface { HRESULT QueryInterface(IID &iid, void** ppvObj);„„ };

LPSOMEINTERFACE p=NULL;pOb->QueryInterface(IID_SOMEINTERFACE, &p);

此处,p是SOMEINTERFACE类型的指针,所以&p便是指针的指针,在QueryInterface返回的时候,如果调用成功,则变量p包含一个指向新的接口的指针。

如果你理解指针的指针,那么你肯定就理解指针引用,因为它们完全是一回事。如果你象下面这样声明函数: void func1(MYCLASS *&pMyClass);{ pMyClass = new MYCLASS;„„ } 其实,它和前面所讲得指针的指针例子是一码事,只是语法有所不同。传递的时候不用传p的地址&p,而是直接传p本身:

MYCLASS* p = NULL;func1(p);在调用之后,p指向一个新的对象。一般来讲,引用的原理或多或少就象一个指针,从语法上看它就是一个普通变量。所以只要你碰到*&,就应该想到**。也就是说这个函数修改或可能修改调用者的指针,而调用者象普通变量一样传递这个指针,不使用地址操作符&。

至于说什么场合要使用这种方法,我会说,极少。MFC在其集合类中用到了它--例如,CObList,它是一个CObjects指针列表。

class CObList : public CObject { „„

// 获取/修改指定位置的元素

CObject*& GetAt(POSITION position);CObject* GetAt(POSITION position)const;};这里有两个GetAt函数,功能都是获取给定位置的元素。区别何在呢?

区别在于一个让你修改列表中的对象,另一个则不行。所以如果你写成下面这样: CObject* pObj = mylist.GetAt(pos);

则pObj是列表中某个对象的指针,如果接着改变pObj的值: pObj = pSomeOtherObj;

这并改变不了在位置pos处的对象地址,而仅仅是改变了变量pObj。但是,如果你写成下面这样: CObject*& rpObj = mylist.GetAt(pos);

现在,rpObj是引用一个列表中的对象的指针,所以当改变rpObj时,也会改变列表中位置pos处的对象地址--换句话说,替代了这个对象。这就是为什么CObList会有两个GetAt函数的缘故。一个可以修改指针的值,另一个则不能。注意我在此说的是指针,不是对象本身。这两个函数都可以修改对象,但只有*&版本可以替代对象。

在C/C++中引用是很重要的,同时也是高效的处理手段。所以要想成为C/C++高手,对引用的概念没有透彻的理解和熟练的应用是不行的。

五.新手学习之浅析c/c++中的指针

在学习c/c+过程中,指针是一个比较让人头痛的问题,稍微不注意将会是程序编译无法通过,甚至造成死机。在程序设计过程中,指针也往往是产生隐含bug的原因。下面就来谈谈指针的应用以及需要注意的一些问题,里面也许就有你平时没有注意到的问题,希望能帮助各位读者理解好指针。

一、我们先来回忆一下指针的概念吧,方便下面的介绍

指针是存放地址值的变量或者常量。例如:int a=1;&a就表示指针常量(“&”表示取地址运算符,也即引用)。int *b,b表示的是指针变量(注意,是b表示指针变量而不是*b),*表示要说明的是指针变量。大家注意int *b[2]和int(*b)[2]是不同的,int *b表示一个指针数组,而int(*b)[2]表示含有两个元素的int指针,这里要注意运算优先级问题,有助于理解指针问题。在这里大概介绍基本概念就够了,至于具体使用方法,如赋值等,很多书都有介绍,我就不多说了。

二、应用以及注意的问题

1、理解指针的关键所在——对指针类型和指针所指向的类型的理解

①、指针类型:可以把指针名字去掉,剩下的就是这个指针

例如: int *a;//指针类型为int *

int **a;//指针类型为int **

int *(*a)[8];//指针类型为 int *(*)[8]

②、指针所指向的类型:是指编译器将把那一片内存所看待成的类型。这里只要把指针声明语句中的指针名字和名字右边的“*”号去掉就可以了,剩下的就是指针所指向的类型。

我之所以把他们放在第一位,是因为弄清楚他们是学c/c++指针的重点,正确理解他们才能使你打好c/c++的编程基础。

2、指针的应用——传递参数。

其实它可以相当于隐式的返回值,这就比return的方法更加灵活了,可以返回更多的值,看看下面的例子自然就明白了:

#include “iostream.h”

void example(int *a1,int &b1,int c1)

{

*a1*=3;

++b1;

++c1;

}

void main()

{

int *a;

int b,c;

*a=6;

b=7;c=10;

example(a,b,c);

cout <<“*a=”<<*a<

cout <<“b=”<

cout <<“c=”<

}

输出:*a=18

b=8

c=10

注意到没有,*a和b的值都改变了,而c没有变。这是由于a1是指向*a(=6)的指针,也即与a是指向同一个地址,所以当a1指向的值改变了,*a的值也就改变了。在函数中的参数使用了引用(int &b1),b1是b的别名,也可以把它当作特殊的指针来理解,所以b的值会改变。函数中的参数int c1只是在函数中起作用,当函数结束时候便消失了,所以在main()中不起作用。

3、关于全局变量和局部变量的一个问题先不废话了,先看看程序:

#include “iostream.h”

int a=5;

int *example1(int b)

{

a+=b;

return &a;

}

int *example2(int b)

{

int c=5;

b+=c;

return &b;

}

void main()

{

int *a1=example1(10);

int *b1=example2(10);

cout <<”a1=”<<*a1<

cout <<”b1=”<<*b1<

}

输出结果:

a1=15

b1=4135

*b1怎么会是4135,而不是15呢?是程序的问题?没错吧?

由于a是全局变量,存放在全局变量的内存区,它一直是存在的;而局部变量则是存在于函数的栈区,当函数example2()调用结束后便消失,是b指向了一个不确定的区域,产生指针悬挂。

下面是对example1()和example2()的反汇编(用TC++ 3.0编译):

example1():

push bp;入栈

mov bp,sp mov ax,[bp+04];传递参数

add [00AA],ax;相加

mov ax,00AA;返回了结果所在的地址

..pop bp;恢复栈,出栈

ret;退出函数

example2():

push bp;入栈

mov bp,sp

sub sp,02

mov word ptr [bp-02],0005

mov ax,[bp-02];传递参数

add [bp+04],ax;相加

lea ax,[bp+04];问题就出在这里

..mov sp,bp

pop bp;恢复栈,出栈

ret;退出函数

对比之后看出来了吧?ax应该是存储的是结果的地址。而在example2()中,返回的却是[bp+04]的内容,因此指针指向了一个不确定的地方,由此产生的指针悬挂。example1()中,ax返回了正确的结果的地址。

4、内存问题:使用指针注意内存的分配和边界。使用指针过程中应该给变量一个适当的空间,以免产生不可见的错误。请看以下代码:

#include “iostream.h”

void main()

{

char *a1;

char *a2;

cin >>a1;

cin >>a2;

cout <<”a1=”<

cout <<”a2=”<

}

输入:abc

123

输出:

a1=123

a2=

Null pointer assignment

指针指向了“空”。解决办法就是分配适当的内存给这两个字符串。修正后的代码

如下:

#include “iostream.h”

void main()

{

char *a1;

char *a2;

a1=new char [10];

a2=new char [10];

cin >>a1;

cin >>a2;

cout <<”a1=”<

cout <<”a2=”<

delete(a1);注意,别忘了要释放内存空间

delete(a2);

}

到此就能输出正确的结果了。分配了适当的内存之后要注意释放内参空间,同时还应该注意不要超出所分配的内存的大小,否则会有溢出现象产生,导致不可预料的结果。

5、关于特殊的指针——引用

引用有时候应用起来要比指针要灵活,用它做返回的时候是不产生任何变量的副本的这样减小了内存的占用,提高执行的速度。引用使用起来要比指针好理解,比较直观。当引用作为参数时,不会改变参数的地址,因此可以作为左值。

下面请看一个例子:

#include “iostream.h”

char ch[5]=”ABCD”;

char &example(int b)

{

return ch;

}

void main()

{

cout <<”ch=”<

example(2)=”c”;

cout<<”ch=”<

}

输出结果:

ch=ABCD

ch=ABcD

在实际编程过程中,可以灵活地引用或指针,尽量提高程序的可读性和执行效率。

三、小结:

指针是学习c/c++的重点难点,主要原因是指针较为抽象,不容易理解。使用指针千万要明白让指针指向什么地方,如何让指针指向正确的地方。在深入系统底层之中需要应用到大量的指针,因此需要理解好指针的基本概念,例如:指针类型和指针所指向的类型。平时应该对留心观察,了解程序的工作过程,必要时候可以对程序进行反汇编,加深对指针的理解,这种方法同样适合学别的编程方面的知识。

四、结束:

指针的应用是很广泛的,利用指针可以做很多事情,要成为一个好的程序员,必须对指针有比较深刻的了解。写本文的目的在于让大家对指针有更深一层的了解,提高指针的应用能力,内容大都是我在实际编程中遇到的问题。相信能给大家一定的帮助。

六.C++中关于指针入门的最好的文章

什么是指针?

其实指针就像是其它变量一样,所不同的是一般的变量包含的是实际的真实的数据,而指针是一个指示器,它告诉程序在内存的哪块区域可以找到数据。这是一个非常重要的概念,有很多程序和算法都是围绕指针而设计的,如链表。

开始学习

如何定义一个指针呢?就像你定义一个其它变量一样,只不过你要在指针名字前加上一个星号。我们来看一个例子:下面这个程序定义了两个指针,它们都是指向整型数据。

int* pNumberOne;

int* pNumberTwo;

你注意到在两个变量名前的“p”前缀了吗?这是程序员通常在定义指针时的一个习惯,以提高便程序的阅读性,表示这是个指针。现在让我们来初始化这两个指针:

pNumberOne = &some_number;

pNumberTwo = &some_other_number;

&号读作“什么的地址”,它表示返回的是变量在内存中的地址而不是变量本身的值。在这个例子中,pNumberOne 等于some_number的地址,所以现在pNumberOne指向some_number。如果现在我们在程序中要用到some_number,我们就可以使用pNumberOne。

我们来学习一个例子:

在这个例子中你将学到很多,如果你对指针的概念一点都不了解,我建议你多看几遍这个例子,指针是个很复杂的东西,但你会很快掌握它的。

这个例子用以增强你对上面所介绍内容的了解。它是用C编写的(注:原英文版是用C写的代码,译者重新用C++改写写了所有代码,并在DEV C++ 和VC++中编译通过!)

#include

void main()

{ // 声明变量:

int nNumber;

int *pPointer;

// 现在给它们赋值:

nNumber = 15;

pPointer = &nNumber;

//打印出变量nNumber的值:

cout<<“nNumber is equal to :”<< nNumber<

// 现在通过指针改变nNumber的值:

*pPointer = 25;

//证明nNumber已经被上面的程序改变

//重新打印出nNumber的值:

cout<<“nNumber is equal to :”<

}

通读一下这个程序,编译并运行它,务必明白它是怎样工作的。如果你完成了,准备好,开始下一小节。

陷井!

试一下,你能找出下面这段程序的错误吗?

#include

int *pPointer;

void SomeFunction();

{

int nNumber;

nNumber = 25;

//让指针指向nNumber:

pPointer = &nNumber;

}

void main()

{

SomeFunction();//为pPointer赋值

//为什么这里失败了?为什么没有得到25

cout<<“Value of *pPointer: ”<<*pPointer<

}

这段程序先调用了SomeFunction函数,创建了个叫nNumber的变量,接着让指针pPointer指向了它。可是问题出在哪儿呢?当函数结束后,nNumber被删掉了,因为这一个局部变量。局部变量在定义它的函数执行完后都会被系统自动删掉。也就是说当SomeFunction 函数返回主函数main()时,这个变量已经被删掉,但pPointer还指着变量曾经用过的但现在已不属于这个程序的区域。如果你还不明白,你可以再读读这个程序,注意它的局部变量和全局变量,这些概念都非常重要。

但这个问题怎么解决呢?答案是动态分配技术。注意这在C和C++中是不同的。由于大多数程序员都是用C++,所以我用到的是C++中常用的称谓。

动态分配

动态分配是指针的关键技术。它是用来在不必定义变量的情况下分配内存和让指针去指向它们。尽管这么说可能会让你迷惑,其实它真的很简单。下面的代码就是一个为一个整型数据分配内存的例子:

int *pNumber;

pNumber = new int;

第一行声明一个指针pNumber。第二行为一个整型数据分配一个内存空间,并让pNumber指向这个新内存空间。下面是一个新例,这一次是用double双精型:

double *pDouble;

pDouble = new double;

这种格式是一个规则,这样写你是不会错的。

但动态分配又和前面的例子有什么不同呢?就是在函数返回或执行完毕时,你分配的这块内存区域是不会被删除的所以我们现在可以用动态分配重写上面的程序:

#include

int *pPointer;

void SomeFunction()

{ // 让指针指向一个新的整型

pPointer = new int;

*pPointer = 25;

}

void main()

{

SomeFunction();// 为pPointer赋值

cout<<“Value of *pPointer: ”<<*pPointer<

}

通读这个程序,编译并运行它,务必理解它是怎样工作的。当SomeFunction调用时,它分配了一个内存,并让pPointer指向它。这一次,当函数返回时,新的内存区域被保留下来,所以pPointer始终指着有用的信息,这是因为了动态分配。但是你再仔细读读上面这个程序,虽然它得到了正确结果,可仍有一个严重的错误。

分配了内存,别忘了回收

太复杂了,怎么会还有严重的错误!其实要改正并不难。问题是:你动态地分配了一个内存空间,可它绝不会被自动删除。也就是说,这块内存空间会一直存在,直到你告诉电脑你已经使用完了。可结果是,你并没有告诉电脑你已不再需要这块内存空间了,所以它会继续占据着内存空间造成浪费,甚至你的程序运行完毕,其它程序运行时它还存在。当这样的问题积累到一定程度,最终将导致系统崩溃。所以这是很重要的,在你用完它以后,请释放它的空间,如:

delete pPointer;

这样就差不多了,你不得不小心。在这你终止了一个有效的指针(一个确实指向某个内存的指针)。下面的程序,它不会浪费任何的内存:

#include

int *pPointer;

void SomeFunction()

{ // 让指针指向一个新的整型

pPointer = new int;

*pPointer = 25;

}

void main()

{

SomeFunction();//为pPointer赋值

cout<<“Value of *pPointer: ”<<*pPointer<

delete pPointer;

}

只有一行与前一个程序不同,但就是这最后一行十分地重要。如果你不删除它,你就会制造一起“内存漏洞”,而让内存逐渐地泄漏。(译者:假如在程序中调用了两次SomeFunction,你又该如何修改这个程序呢?请读者自己思考)

传递指针到函数

传递指针到函数是非常有用的,也很容易掌握。如果我们写一个程序,让一个数加上5,看一看这个程序完整吗?:

#include

void AddFive(int Number)

{

Number = Number + 5;

}

void main()

{

int nMyNumber = 18;

cout<<“My original number is ”<

AddFive(nMyNumber);

cout<<“My new number is ”<

}

问题出在函数AddFive里用到的Number是变量nMyNumber的一个副本而传递给函数,而不是变量本身。因此,“ Number = Number + 5” 这一行是把变量的副本加了5,而原始的变量在主函数main()里依然没变。试着运行这个程序,自己去体会一下。要解决这个问题,我们就要传递一个指针到函数,所以我们要修改一下函数让它能接受指针:把'void AddFive(int Number)' 改成 'void AddFive(int*Number)'。下面就是改过的程序,注意函数调用时要用&号,以表示传递的是指针:

#include

void AddFive(int* Number)

{

*Number = *Number + 5;

}

void main()

{

int nMyNumber = 18;

cout 七.我眼中的指针--学习指针不可少的好文章

我眼中的指针--学习指针不可少的好文章

为初学者服务。这是我的帖子的宗旨。我也是个初学者(强调了无数遍了),我以我的理解把初学者觉得难懂的东西用浅显的语言写出来。由于小学时语文没学好,所以竭尽全力也未必能达到这个目的。尽力而为吧。

指针是c和c++中的难点和重点。我只精通dos下的basic。c语言的其它各种特性,在basic中都有类似的东西。只有指针,是baisc所不具备的。指针是c的灵魂。

我不想重复大多数书上说得很清楚的东西,我只是把我看过的书中说得不清楚或没有说,而我又觉得我理解得有点道理的东西写出来。我的目的是:

1。通过写这些东西,把我脑袋中关于c的模糊的知识清晰化。2。给初学者们一点提示。

3。赚几个经验值。(因为贴这些东西没有灌水之嫌啊)

第一章。指针的概念

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让我们分别说明。先声明几个指针放着做例子: 例一:(1)int *ptr;(2)char *ptr;(3)int **ptr;(4)int(*ptr)[3];(5)int *(*ptr)[4];如果看不懂后几个例子的话,请参阅我前段时间贴出的文?lt;<如何理解c和c++的复杂类型声明>>。

1。指针的类型。

从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:(1)int *ptr;//指针的类型是int *(2)char *ptr;//指针的类型是char *(3)int **ptr;//指针的类型是 int **(4)int(*ptr)[3];//指针的类型是 int(*)[3](5)int *(*ptr)[4];//指针的类型是 int *(*)[4] 怎么样?找出指针的类型的方法是不是很简单?

2。指针所指向的类型。

当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符 * 去掉,剩下的就是指针所指向的类型。例如:

(1)int *ptr;//指针所指向的类型是int(2)char *ptr;//指针所指向的的类型是char(3)int **ptr;//指针所指向的的类型是 int *(4)int(*ptr)[3];//指针所指向的的类型是 int()[3](5)int *(*ptr)[4];//指针所指向的的类型是 int *()[4] 在指针的算术运算中,指针所指向的类型有很大的作用。指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的“类型”这个概念分成“指针的类型”和“指针所指向的类型”两个概念,是精通指针的关键点之一。我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,所以看起书来前后矛盾,越看越糊涂。

3。指针的值,或者叫指针所指向的内存区或地址。

指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相 当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。

指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。

以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指向的类型是什么?该指针指向了哪里? 4。指针本身所占据的内存区。

指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。

第二章。指针的算术运算

指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如: 例二:

1。char a[20];2。int *ptr=a;......3。ptr++;在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整形变量a。接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。

由于char类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。我们可以用一个指针和一个循环来遍历一个数组,看例子: 例三: 例三: int array[20];int *ptr=array;...//此处略去为整型数组赋值的代码。...for(i=0;i<20;i++){(*ptr)++;ptr++; } 这个例子将整型数组中各个单元的值加1。由于每次循环都将

八.指针详解

第一章。指针的概念

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让 我们分别说明。先声明几个指针放着做例子: 例一:(1)int*ptr;(2)char*ptr;(3)int**ptr;(4)int(*ptr)[3];(5)int*(*ptr)[4];

1。指针的类型。

从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:(1)int*ptr;//指针的类型是int*(2)char*ptr;//指针的类型是char*(3)int**ptr;//指针的类型是int**(4)int(*ptr)[3];//指针的类型是int(*)[3](5)int*(*ptr)[4];//指针的类型是int*(*)[4] 怎么样?找出指针的类型的方法是不是很简单?

2。指针所指向的类型。

当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符 *去掉,剩下的就是指针所指向的类型。例如:

(1)int*ptr;//指针所指向的类型是int(2)char*ptr;//指针所指向的的类型是char(3)int**ptr;//指针所指向的的类型是int*(4)int(*ptr)[3];//指针所指向的的类型是int()[3](5)int*(*ptr)[4];//指针所指向的的类型是int*()[4] 在指针的算术运算中,指针所指向的类型有很大的作用。

指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的“类型”这个概念分成“指针的类型”和“指针所指向的类型”两个概念,是精通指针的关键点之一。我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,所以看起书来前后矛盾,越看越糊涂。

3。指针的值,或者叫指针所指向的内存区或地址。

指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区 是不存在的,或者说是无意义的。以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指向的类型是什么?该指针指向了哪里?

4。指针本身所占据的内存区。

指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。第二章。指针的算术运算

指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如: 例二: 1。char a[20];2。int *ptr=a;......3。ptr++;在上例中,指针ptr的类型是int*,它指向的类型是int,它被初始化为指向整形变量a。接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针 ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。

由于char类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。我们可以用一个指针和一个循环来遍历一个数组,看例子: 例三: int array[20];int *ptr=array;...//此处略去为整型数组赋值的代码。...for(i=0;i<20;i++){(*ptr)++;ptr++; } 这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1,所以每次循环都能访问数组的下一个单元。再看例子: 例四: 1。char a[20];2。int *ptr=a;......3。ptr+=5;在这个例子中,ptr被加上了5,编译器是这样处理的:将指针ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。由于地址的单位是字节,故现在的ptr所指向的地址比起加5后的ptr所指向的地址来说,向高地址方向移动了20个字节。在这个例子中,没加5前的ptr指向数组a的第0号单元开始的四个字节,加5后,ptr已经指向了数组a的合法范围之外了。虽然这种情况在应用上会出问题,但在语法上却是可以的。这也体现出了指针的灵活性。如果上例中,ptr是被减去5,那么处理过程大同小异,只不过ptr的值是被减去5乘sizeof(int),新的ptr指向的地址将比原来的ptr所指向的地址向低地址方向移动了20个字节。

总结一下,一个指针ptrold加上一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值增加了n乘sizeof(ptrold所指向的类型)个字节。就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向高地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。一个指针ptrold减去一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值减少了n乘sizeof(ptrold所指向的类型)个字节,就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向低地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。

第三章。运算符&和* 这里&是取地址运算符,*是...书上叫做“间接运算符”。&a的运算结果是一个指针,指针的类型是a的类型加个*,指针所指向的类型是a的类型,指针所指向的地址嘛,那就是a的地址。*p的运算结果就五花八门了。总之*p的结果是p所指向的东西,这个东西有这些特点:它的类型是p指向的类型,它所占用的地址是p所指向的地址。例五: int a=12;int b;int *p;int **ptr;p=&a;//&a的结果是一个指针,类型是int*,指向的类型是int,指向的地址是a的地址。

*p=24;//*p的结果,在这里它的类型是int,它所占用的地址是p所指向的地址,显然,*p就是变量a。

ptr=&p;//&p的结果是个指针,该指针的类型是p的类型加个*,在这里是int **。该指针所指向的类型是p的类型,这里是int*。该指针所指向的地址就是指针p自己的地址。

*ptr=&b;//*ptr是个指针,&b的结果也是个指针,且这两个指针的类型和所指向的类型是一样的,所以用&b来给*ptr赋值就是毫无问题的了。

**ptr=34;//*ptr的结果是ptr所指向的东西,在这里是一个指针,对这个指针再做一次*运算,结果就是一个int类型的变量。

第四章。指针表达式。

一个表达式的最后结果如果是一个指针,那么这个表达式就叫指针表达式。下面是一些指针表达式的例子: 例六: int a,b;int array[10];int *pa;pa=&a;//&a是一个指针表达式。

int**ptr=&pa;//&pa也是一个指针表达式。

*ptr=&b;//*ptr和&b都是指针表达式。

pa=array;pa++;//这也是指针表达式。例七: char*arr[20];char**parr=arr;//如果把arr看作指针的话,arr也是指针表达式 char*str;str=*parr;//*parr是指针表达式

str=*(parr+1);//*(parr+1)是指针表达式 str=*(parr+2);//*(parr+2)是指针表达式

由于指针表达式的结果是一个指针,所以指针表达式也具有指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存。

好了,当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话,这个指针表达式就是一个左值,否则就不是一个左值。在例七中,&a不是一个左值,因为它还没有占据明确的内存。*ptr是一个左值,因为*ptr这个指针已经占据了内存,其实*ptr就是指针pa,既然pa已经在内存中有了自己的位置,那么*ptr当然也有了自己的位置。

第五章。数组和指针的关系

数组的数组名其实可以看作一个指针。看下例: 例八:

int array[10]={0,1,2,3,4,5,6,7,8,9},value;......value=array[0];//也可写成:value=*array;value=array[3];//也可写成:value=*(array+3);value=array[4];//也可写成:value=*(array+4);

上例中,一般而言数组名array代表数组本身,类型是int [10],但如果把array看做指针的话,它指向数组的第0个单元,类型是int*,所指向的类型是数组单元的类型即int。因此*array等于0就一点也不奇怪了。同理,array+3是一个指向数组第3个单元的指针,所以*(array+3)等于3。其它依此类推。例九: char*str[3]={ “Hello,thisisasample!”, “Hi,goodmorning.”, “Helloworld” };chars[80];

strcpy(s,str[0]);//也可写成strcpy(s,*str);strcpy(s,str[1]);//也可写成strcpy(s,*(str+1));strcpy(s,str[2]);//也可写成strcpy(s,*(str+2));上例中,str是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。把指针数组名str当作一个指针的话,它指向数组的第0号单元,它的类型是char**,它指向的类型是char*。*str也是一个指针,它的类型是char*,它所指向的类型是char,它指向的地址是字符串“Hello,thisisasample!”的第一个字符的地址,即''H''的地址。str+1也是一个指针,它指向数组的第1号单元,它的类型是char**,它指向的类型是char*。*(str+1)也是一个指针,它的类型是char*,它所指向的类型是char,它指向“Hi,goodmorning.”的第一个字符''H'',等等。下面总结一下数组的数组名的问题。声明了一个数组TYPEarray[n],则数组名称array就有了两重含义:第一,它代表整个数组,它的类型是TYPE[n];第二,它是一个指针,该指针的类型是TYPE*,该指针指向的类型是TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似array++的表达式是错误的。在不同的表达式中数组名array可以扮演不同的角色。在表达式sizeof(array)中,数组名array代表数组本身,故这时sizeof函数 测出的是整个数组的大小。在表达式*array中,array扮演的是指针,因此这个表达式的结果就是数组第0号单元的值。sizeof(*array)测出的是数组单元的大小。表达式array+n(其中n=0,1,2,....。)中,array扮演的是指针,故array+n的结果是一个指针,它的类型是TYPE*,它指向的类型是TYPE,它指向数组第n号单元。故sizeof(array+n)测出的是指针类型的大小。例十: int array[10];int(*ptr)[10];ptr=&array;上例中ptr是一个指针,它的类型是int(*)[10],他指向的类型是int[10],我们用整个数组的首地址来初始化它。在语句ptr=&array中,array代表数组本身。

本节中提到了函数sizeof(),那么我来问一问,sizeof(指针名称)测出的究竟是指针自身类型的大小呢还是指针所指向的类型的大小?答案是前者。例如: int(*ptr)[10];则在32位程序中,有: sizeof(int(*)[10])==4 sizeof(int[10])==40 sizeof(ptr)==4 实际上,sizeof(对象)测出的都是对象自身的类型的大小,而不是别的什么类型的大小。

第六章。指针和结构类型的关系 可以声明一个指向结构类型对象的指针。例十一: struct MyStruct { int a;int b;int c;}MyStruct ss={20,30,40};//声明了结构对象ss,并把ss的三个成员初始化为20,30和40。MyStruct*ptr=&ss;//声明了一个指向结构对象ss的指针。它的类型是MyStruct*, //它指向的类型是MyStruct。

int *pstr=(int*)&ss;//声明了一个指向结构对象ss的指针。但是它的 //类型和它指向的类型和ptr是不同的。

请问怎样通过指针ptr来访问ss的三个成员变量? 答案: ptr->a;ptr->b;ptr->c;又请问怎样通过指针pstr来访问ss的三个成员变量? 答案:

*pstr;//访问了ss的成员a。*(pstr+1);//访问了ss的成员b。

*(pstr+2)//访问了ss的成员c。

呵呵,虽然我在我的MSVC++6.0上调式过上述代码,但是要知道,这样使用pstr来访问结构成员是不正规的,为了说明为什么不正规,让我们看看怎样通过指针来访问数组的各个单元: 例十二:

int array[3]={35,56,37};int*pa=array;通过指针pa访问数组array的三个单元的方法是: *pa;//访问了第0号单元 *(pa+1);//访问了第1号单元

*(pa+2);//访问了第2号单元

从格式上看倒是与通过指针访问结构成员的不正规方法的格式一样。所有的C编译器在排列数组的单元时,总是把各个数组单元存放在连续的存储区里,单元和单元之间没有空隙。但在存放结构对象的各个成员时,在某种编译环境下,可能会需要字对齐或双字对齐或者是别的什么对齐,需要在相邻两个成员之间加若干个“填充字节”,这就导致各个成员之间可能会有若干个字节的空隙。所以,在例十二中,即使*pstr访问到了结构对象ss的第一个成员变量a,也不能保证*(pstr+1)就一定能访问到结构成员b。因为成员a和成员b之间可能会有若干填充字节,说不定*(pstr+1)就正好访问到了这些填充字节呢。这也证明了指针的灵活性。要是你的目的就是想看看各个结构成员之间到底有没有填充字节,嘿,这倒是个不错的方法。通过指针访问结构成员的正确方法应该是象例十二中使用指针ptr的方法。

第七章。指针和函数的关系

可以把一个指针声明成为一个指向函数的指针。int fun1(char*,int);int(*pfun1)(char*,int);pfun1=fun1;........inta=(*pfun1)(“abcdefg”,7);//通过函数指针调用函数。

可以把指针作为函数的形参。在函数调用语句中,可以用指针表达式来作为实参。例十三: int fun(char*);int a;char str[]=“abcdefghijklmn”;a=fun(str);......int fun(char*s){ int num=0;while(*s!= ''''){ num+=*s;s++;} retur nnum;} 这个例子中的函数fun统计一个字符串中各个字符的ASCII码值之和。前面说了,数组的名字也是一个指针。在函数调用中,当把str作为实参传递给形参s后,实际是把str的值传递给了s,s所指向的地址就和str所指向的地址一致,但是str和s各自占用各自的存储空间。在函数体内对s进行自加1运算,并不意味着同时对str进行了自加1运算。

第八章。指针类型转换

当我们初始化一个指针或给一个指针赋值时,赋值号的左边是一个指针,赋值号的右边是一个指针表达式。在我们前面所举的例子中,绝大多数情况下,指针的类型和指针表达式的类型是一样的,指针所指向的类型和指针表达式所指向 的类型是一样的。例十四: 1。float f=12.3;2。float *fptr=&f;3。int*p;在上面的例子中,假如我们想让指针p指向实数f,应该怎么搞?是用下面的语句吗? p=&f;不对。因为指针p的类型是int*,它指向的类型是int。

表达式&f的结果是一

个指针,指针的类型是float*,它指向的类型是float。两者不一致,直接赋值的方法是不行的。为了实现我们的目的,需要进行“强制类型转换”: p=(int*)&f;如果有一个指针p,我们需要把它的类型和所指向的类型改为TYEP*和TYPE,那么语法格式是:(TYPE*)p;

这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE*,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。而原来的指针p的一切属性都没有被修改。

一个函数如果使用了指针作为形参,那么在函数调用语句的实参和形参的结合过程中,也会发生指针类型的转换。例十五: void fun(char*);int a=125,b;fun((char*)&a);......void fun(char*s){ char c;c=*(s+3);*(s+3)=*(s+0);*(s+0)=c;c=*(s+2);*(s+2)=*(s+1);*(s+1)=c;}

注意这是一个32位程序,故int类型占了四个字节,char类型占一个字节。函数fun的作用是把一个整数的四个字节的顺序来个颠倒。注意到了吗?在函数调用语句中,实参&a的结果是一个指针,它的类型是int*,它指向的类型是int。形参这个指针的类型是char*,它指向的类型是char。这样,在实参和形参的结合过程中,我们必须进行一次从int*类型到char*类型的转换。结合这个例子,我们可以这样来想象编译器进行转换的过程:编译器先构造一个临时指针char*temp,然后执行temp=(char*)&a,最后再把temp的值传递给s。所以最后的结果是:s的类型是char*,它指向的类型是char,它指向的地址就是a的首地址。

我们已经知道,指针的值就是指针指向的地址,在32位程序中,指针的值其实是一个32位整数。那可不可以把一个整数当作指针的值直接赋给指针呢?就象下面的语句: unsigned int a;TYPE*ptr;//TYPE是int,char或结构类型等等类型。

......a=20345686;ptr=20345686;//我们的目的是要使指针ptr指向地址20345686(十进制)

ptr=a;//我们的目的是要使指针ptr指向地址20345686(十进制)

编译一下吧。结果发现后面两条语句全是错的。那么我们的目的就不能达到了吗?不,还有办法: unsignedinta;TYPE*ptr;//TYPE是int,char或结构类型等等类型。

......a=某个数,这个数必须代表一个合法的地址; ptr=(TYPE*)a;//呵呵,这就可以了。

严格说来这里的(TYPE*)和指针类型转换中的(TYPE*)还不一样。这里的(TYPE*)的意思是把无符号整数a的值当作一个地址来看待。上面强调了a的值必须代表一个合法的地址,否则的话,在你使用ptr的时候,就会出现非法操作错误。

想想能不能反过来,把指针指向的地址即指针的值当作一个整数取出来。完全可以。下面的例子演示了把一个指针的值当作一个整数取出来,然后再把这个整数当作一个地址赋给一个指针: 例十六: inta=123,b;int*ptr=&a;char*str;b=(int)ptr;//把指针ptr的值当作一个整数取出来。

str=(char*)b;//把这个整数的值当作一个地址赋给指针str。

好了,现在我们已经知道了,可以把指针的值当作一个整数取出来,也可以把一个整数值当作地址赋给一个指针。

第九章。指针的安全问题 看下面的例子: 例十七: char s=''a'';int*ptr;ptr=(int*)&s;*ptr=1298;

指针ptr是一个int*类型的指针,它指向的类型是int。它指向的地址就是s的首地址。在32位程序中,s占一个字节,int类型占四个字节。最后一条语句不但改变了s所占的一个字节,还把和s相临的高地址方向的三个字节也改变了。这三个字节是干什么的?只有编译程序知道,而写程序的人是不太可能知道的。也许这三个字节里存储了非常重要的数据,也许这三个字节里正好是程序的一条代码,而由于你对指针的马虎应用,这三个字节的值被改变了!这会造成崩溃性的错误。让我们再来看一例: 例十八: 1。char a;2。int*ptr=&a;......3。ptr++;4。*ptr=115;该例子完全可以通过编译,并能执行。但是看到没有?第3句对指针ptr进行自加1运算后,ptr指向了和整形变量a相邻的高地址方向的一块存储区。这块存储区里是什么?我们不知道。有可能它是一个非常重要的数据,甚至可能是一条代码。而第4句竟然往这片存储区里写入一个数据!这是严重的错误。所以在使用指针时,程序员心里必须非常清楚:我的指针究竟指向了哪里。

在用指针访问数组的时候,也要注意不要超出数组的低端和高端界限,否则也会造成类似的错误。

在指针的强制类型转换:ptr1=(TYPE*)ptr2中,如果sizeof(ptr2的类型)大于sizeof(ptr1的类型),那么在使用指针ptr1来访问ptr2所指向的存储区时是安全的。如果sizeof(ptr2的类型)小于sizeof(ptr1的类型),那么在使用指针ptr1 来访问ptr2所指向的存储区时是不安全的。至于为什么,读者结合例十七来想一想,应该会明白的。

第四篇:六年级要求掌握古诗

一年级要求掌握:

4咏鹅(唐)骆宾王 鹅,鹅,鹅,曲项向天歌。课内篇:(6)上册:

白毛浮绿水,红掌拨清波。

1江南 汉乐府

江南可采莲,莲叶何田田。鱼戏莲叶间。

鱼戏莲叶东,鱼戏莲叶西。鱼戏莲叶南,鱼戏莲叶北。

2古朗月行(节选)(唐)李白 小时不识月,呼作白玉盘。又疑瑶台镜,飞在青云端。仙人垂两足,桂树何团团。白兔捣药成,问言与谁餐?

下册:

3村居(清)高鼎 草长莺飞二月天,拂堤杨柳醉春烟。儿童散学归来早,忙趁东风放纸鸢。

5悯农(锄禾)(唐)李绅 锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦。

6悯农(唐)李绅

春种一粒粟,秋收万颗子。四海无闲田,农夫犹饿死。

课外篇:(3)

7江上渔者(宋)范仲淹 江上往来人,但爱鲈鱼美。君看一叶舟,出没**里。

8敕勒歌 北朝民歌 敕勒川,阴山下。天似穹庐,笼盖四野。天苍苍,野茫茫,风吹草低见牛羊。9咏柳(唐)贺知章 碧玉妆成一树高,万条垂下绿丝绦。不知细叶谁裁出,二月春风似剪刀

二年级要求掌握:

课内篇:(7)上册:

10静夜思(唐)李白 床前明月光,疑是地上霜。举头望明月,低头思故乡。11长歌行 汉乐府

青青园中葵,朝露待日晞。阳春布德泽,万物生光辉。常恐秋节至,焜黄华叶衰。百川东到海,何时复西归?少壮不努力,老大徒伤悲。12登鹳雀楼(唐)王之涣 白日依山尽,黄河入海流。欲穷千里目,更上一层楼。

下册:

13春夜喜雨(唐)杜甫 好雨知时节,当春乃发生。随风潜入夜,润物细无声。野径云俱黑,江船火独明。晓看红湿处,花重锦官城。

14春晓(唐)孟浩然 春眠不觉晓,处处闻啼鸟。夜来风雨声,花落知多少。

15游子吟(唐)孟郊 慈母手中线,游子身上衣。临行密密缝,意恐迟迟归。谁言寸草心,报得三春晖。16忆江南(江南好)(唐)白居易 江南好,风景旧曾谙。日出江花红胜火,春来江水绿如蓝。能不忆江南?

课外篇:(5)17寻隐者不遇(唐)贾岛 松下问童子,言师采药去。只在此山中,云深不知处。18回乡偶书(唐)贺知章 少小离家老大回,乡音无改鬓毛衰。儿童相见不相识,笑问客从何处来。18题西林壁(宋)苏轼 横看成岭侧成峰,远近高低各不同。不识庐山真面目,只缘身在此山中。20泊船瓜洲(宋)王安石 京口瓜洲一水间,钟山只隔数重山。春风又绿江南岸,明月何时照我还。21赠汪伦(唐)李白 李白乘舟将欲行,忽闻岸上踏歌声。

桃花潭水深千尺,不及汪伦送我情。

三年级要求掌握:

课内篇:(9)

上册:

22山行(唐)杜牧 远上寒山石径斜,白云生处有人家。停车坐爱枫林晚,霜叶红于二月花。23枫桥夜泊(唐)张继 月落乌啼霜满天,江枫渔火对愁眠。姑苏城外寒山寺,夜半钟声到客船。24竹石(清)郑燮 咬定青山不放松,立根原在破岩中。千磨万击还坚劲,任尔东西南北风。25九月九日忆山东兄弟(唐)王维 独在异乡为异客,每逢佳节倍思亲。遥知兄弟登高处,遍插茱萸少一人。下册:

26四时田园杂兴(宋)范成大 昼出耘田夜绩麻,村庄儿女各当家。童孙未解供耕织,也傍桑阴学种瓜。27 清明(唐)杜牧 清明时节雨纷纷,路上行人欲断魂。借问酒家何处有? 牧童遥指杏花村。

28望庐山瀑布(唐)李白 日照香炉生紫烟,遥看瀑布挂前川,飞流直下三千尺。疑是银河落九天。

29绝句(唐)杜甫 两个黄鹂鸣翠柳,一行白鹭上青天。窗含西岭千秋雪,门泊东吴万里船。30滁州西涧(唐)韦应物 独怜幽草涧边生,上有黄鹂深树鸣。春潮带雨晚来急,野渡无人舟自横。

课外篇:(6)

31四时田园杂兴(宋)范成大 梅子金黄杏子肥,麦花雪白菜花稀。日长篱落无人过,唯有蜻蜓蛱蝶飞。32蜂(唐)罗隐 不论平地与山尖,无限风光尽被占。采得百花成蜜后,为谁辛苦为谁甜?

33凉州词(唐)王翰 葡萄美酒夜光杯,欲饮琵琶马上催。醉卧沙场君莫笑,古来征战几人回。

34赋得古原草送别(唐)白居易离离原上草,一岁一枯荣。野火烧不尽,春风吹又生。远芳侵古道,晴翠接荒城。又送王孙去,萋萋满别情。35早发白帝城(唐)李白 朝辞白帝彩云间,千里江陵一日还。

两岸猿声啼不住,轻舟已过万重山。

36望天门山(唐)李白 天门中断楚江开,碧水东流至此回。

两岸青山相对出,孤帆一片日边来。

四年级要求掌握:

课内篇:(7)

上册:

37望洞庭(唐)刘禹锡 湖光秋月两相和,潭面无风镜未磨。遥望洞庭山水色,白银盘里一青螺。

38风(唐)李峤

解落三秋叶,能开二月花。过江千尺浪,入竹万竿斜。39元日(宋)王安石

爆竹声中一岁除,春风送暖入屠苏。

千门万户曈曈日,总把新桃换旧符。

40江雪(唐)柳宗元

千山鸟飞绝,万径人踪灭。孤舟蓑笠翁,独钓寒江雪。5

下册:

41江南春(唐)杜牧 千里莺啼绿映江,水村山郭酒旗风。45鹿柴(唐)王维(4)空山不见人,但闻人语响。返景入深林,复照青苔上。46饮湖上初晴后雨(宋)苏轼(4)南朝四百八十寺,多少楼台烟雨中。42池上(唐)白居易 小娃撑小艇,偷采白莲回。不解藏踪迹,浮萍一道开。

43小儿垂钓(唐)胡令能 蓬头稚子学垂纶,侧坐莓苔草映身。路人借问遥招手,怕得鱼惊不应人。

课外篇:(9)44小池(宋)杨万里 泉眼无声惜细流,树阴照水爱晴柔。

小荷才露尖尖角,早有蜻蜓立上头。

水光潋滟晴方好,山色空濛雨亦奇。

欲把西湖比西子,淡妆浓抹总相宜。

47送元二使安西(唐)王维

客舍青青柳色新。劝君更尽一杯酒,西出阳关无故人。

48别董大(唐)高适 千里黄云白日曛,北风吹雁雪纷纷。莫愁前路无知己,天下谁人不识君。49绝句(唐)杜甫

迟日江山丽,春风花草香。

泥融飞燕子,沙暖睡鸳鸯。

50惠崇春江晓景(宋)苏轼(4)竹外桃花三两枝,春江水暖鸭先知。

蒌蒿满地芦芽短,正是河豚欲上时。51春日(宋)朱熹(4)胜日寻芳泗水滨,无边光景一时新。等闲识得东风面,万紫千红总是春。52凉州词(唐)王之焕 黄河远上白云间,一片孤城万仞山。羌笛何须怨杨柳,春风不度玉门关。

五年级要求掌握:

课内篇:(5)上册:

53所见(清)袁枚 牧童骑黄牛,歌声振林樾。意欲捕鸣蝉,忽然闭口立。

54黄鹤楼送孟浩然之广陵(唐)李白 故人西辞黄鹤楼,烟花三月下扬州。孤帆远影碧空尽,唯见长江天际流。

下册:

55游园不值(宋)叶绍翁

小扣柴扉久不开。

春色满园关不住,一枝红杏出墙来。

56六月二十七日望湖楼醉书(宋)苏轼 黑云翻墨未遮山,白雨跳珠乱入船。

卷地风来忽吹散,望湖楼下水如天。57晓出净慈寺送林子方(宋)杨万里

毕竟西湖六月中,风光不与四时同。

接天莲叶无穷碧,映日荷花别样红。

课外篇:(8)58出塞(唐)王昌龄(5)秦时明月汉时关,万里长征人未还。

但使龙城飞将在,不教胡马度阴山。

59书湖阴先生壁(宋)王安石 茅檐长扫净无苔,花木成畦手自栽。

一水护田将绿绕,两山排闼送青来。

60芙蓉楼送辛渐(唐)王昌龄(5)寒雨连江夜入吴,平明送客楚山孤。洛阳亲友如相问,一片冰心在玉壶。61三衢道中(南宋)曾几 梅子黄时日日睛,小溪泛尽却山行。

绿阴不减来时路,添得黄鹂四五声。62题临安邸(宋)林升

山外青山楼外楼,西湖歌舞几时休。暖风熏得游人醉,直把杭州当汴州。

63秋夜将晓出篱门迎凉有感(宋)陆游 三万里河东入海,五千仞岳上摩天。遗民泪尽胡尘里,南望王师又一年。64早春呈水部张十八员外(唐)韩愈 天街小雨润如酥,草色遥看近却无。最是一年春好处,绝胜烟柳满皇都。

65江畔独步寻花(唐)杜甫黄师塔前江水东,春光懒困倚微风。桃花一簇开无主,可爱深红爱浅红?

六年级要求掌握:

课内篇:(6)上册:

66示儿(宋)陆游 死去元知万事空,但悲不见九州同。王师北定中原日,家祭无忘告乃翁。

67观书有感(宋)朱熹

半亩方塘一鉴开,天光云影共徘徊。问渠哪得清如许? 为有源头活水来。

下册:

68夏日绝句(宋)李清照 生当作人杰,死亦为鬼雄。至今思项羽,不肯过江东。

69渔歌子(唐)张志和 西塞山前白鹭飞,桃花流水鳜鱼肥。

青箬笠,绿蓑衣,斜风细雨不须归。

70石灰吟(明)于谦 千锤万击出深山,烈火焚烧若等闲,粉骨碎身浑不怕,要留清白在人间。

71墨梅(元)王冕 吾家洗砚池头树,个个花开淡墨痕。不要人夸颜色好,只流清气满乾坤。

课外篇:(4)

72塞下曲(唐)卢纶 月黑雁飞高,单于夜遁逃。欲将轻骑逐,大雪满弓刀。

73浪淘沙(唐)刘禹锡 九曲黄河万里沙,浪淘风簸自天涯。如今直上银河去,同到牵牛织女家。

74乡村四月(宋)翁卷 绿遍山原白满川,子规声里雨如烟。乡村四月闲人少,才了蚕桑又插田。75己亥杂诗(清)龚自珍浩荡离愁白日斜,吟鞭东指即天涯。落红不是无情物,化作春泥更护花。

第五篇:学生掌握游泳技能协议书

佛山市顺德区勒流中心小学

学生掌握游泳技能协议书

勒流河涌错综复杂,遇溺事件时有发生,不谙水性是主要原因之一,为此,防溺水须从家长做起,从学生做起,而学会游泳是保障生命安全的重要保证,为提高自护自救能力,除加强防范外,每一个学生都必须掌握游泳技能。

特此,学校与家长、学生签订如下协议,并共同执行。

1、学校须对学生加强防溺教育。

2.学校当年6月1日至9月30日须有目的地开展学生游泳技能培训辅导(上课期间)。

3、学校须与家长保持联系,提醒家长认真履行监护人职责。

4、家长须对子女履行监护人的义务,对子女加强安全教育及管理。

5、家长须根据子女的实际情况,制定学习游泳技能计划,利用暑假戓休闲时间陪同

子女学习游泳技能。

6、家长须保证在年之内(即从签订协议之日起到年月日)让子女________________掌握游泳技能。

7、本协议从签订之日起至约定学生掌握游泳技能之日止。

8、本协议一式两份,学校与家长各执一份。

学校(盖章)家长(签名)

_____年____班 班主任:学生(签名)

签订日期:年月日

下载学习指针万用表要求掌握的技能(最终版)word格式文档
下载学习指针万用表要求掌握的技能(最终版).doc
将本文档下载到自己电脑,方便修改和收藏,请勿使用迅雷等下载。
点此处下载文档

文档为doc格式


声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:645879355@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。

相关范文推荐

    学习大数据开发前需要掌握哪些技能?

    www.xiexiebang.com 老男孩IT教育,只培养技术精英 学习大数据开发前需要掌握哪些技能? 1. 数学知识 数学知识是数据分析师的基础知识。 对于初级数据分析师,了解一些描述统计......

    小学生应掌握的劳动技能

    小学生应掌握的劳动技能 小学低年级:主要安排一些力所能及的自我服务劳动。通过自我服务劳动和其他劳动项目的训练和实践,使学生认识劳动光荣,初步培养学生爱劳动的观 念,争做爱......

    办公室人员应掌握的技能

    办公室人员应掌握的技能 公文处理工作业务 档案管理业务 公文接待礼仪 调研文章和领导起草 信息工作业务 办公室工作规范 保密知识 值班工作和突发事件应急处理......

    Java工程师要掌握哪些技能

    Java工程师要掌握哪些技能 Java是目前世界上最流行的计算机编程语言,全球共计有25亿Java器在运行Java,几百万的Java开发者遍布世界各地,Java运行在数以亿计的手机、智能卡和PC......

    汽车驾驶员必备技能掌握知识点

    全国首家互联网驾校 汽车驾驶员必备技能掌握知识点 一、如何提高汽车驾驶员预防事故的措施 1、认识和掌握“信息处理特性”,驾驶员无论是在滩区或在路上行驶,他的行动过程首......

    幼儿园保育员须掌握的技能

    幼儿园保育员须掌握的技能 一、掌握“幼儿生活管理”技能 1、晨、午检: 质量标准:协助老师晨、午检,做到一摸、二看、三问、四查。 技能技巧: 一摸:摸摸幼儿头额部有无发热; 二看......

    大学生应该掌握的十大技能

    大学生应该掌握的十大技能 大学生应该掌握的十大技能 ........................................................................................................... 1......

    C语言和C的指针学习总结

    C语言之指针、数组和函数基本解释1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);数组的本质则是一系列的变量。2、数组名对应着(而不是指向)一块内存,其......