【教学课件】第三讲指针引用运算符语句.ppt
第三讲指针引用运算符语句,本讲内容,上次作业讲解指针及其应用引用运算符循环语句本讲作业,3.1 指针和引用,指针指针和数组引用,指针,具有指针类型的变量统称为指针变量。指针变量所表示的数据值是某个变量在内存中的地址值。称这个指针指向该变量。指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,因为任何指针本身数据值的类型都是unsigned long int型。如:int a=5;int*p=/定义一个指向整型变量空间的指针,并初始化为整型变量a的起始地址,使p指向a。,1、指针概念,2、指针的定义,格式为:*;例如:int*pi;/一个指向整型变量的指针 float*pl;char*pc;char(*pa)3;/一个指向数组空间的指针 int*pp;/一个指向指针变量空间的指针 注:类型的不同,并不影响指针本身空间大小的不同(都是内存地址值),但却决定了指针所指向的空间的不同,也带来了对指针所指向空间的不同操作。,一、赋值运算 定义一个指针后,必须先给它赋值后才能引用,否则易出错。如:int a=1,*p1,*p2;p1=/给p2所指向的变量赋值,3、指针的运算,1,2,3,此处无,代表取值,二、加一或减一运算如:int a10,*p;p=a;/p指向数组a中的a0元素 p=p+1;/这时p指向a1,三、相减运算(一定条件下)如:int a10,*p1,*p2;p1=/所得为指针间相隔的元素个数,0 x00428D54,指针地址是无符号长整形:4 byte,C+中,数组元素可以用下标表示也可用指针表示。1、一维数组的指针表示如:int a5;a2=3;/下标表示 ai*(a+2)=3;/指针表示*(a+i)其中a是数组名,C+规定数组名是一个常量指针,其值是该数组首元素的地址值。如:int a5,*p;p=a;/与p=/错误!为什么?,指针和数组,2、二维数组的指针表示如:int b34;b23=3;/下标表示 bij*(*(b+2)+3)=3;/指针表示*(*(b+i)+j)其中b是二维数组名,对于b而言,b0等是其元素,但要注意这些元素的类型并不是int型,而是相当于int 3型。因此,我们称b0等为第0行。其中b0行中有b00 b02三个元素,注意这些元素的类型才是int型。则有以下表示方式:b12*(b1+2)(*(b+1)2*(*(b+1)+2),#include iostream.hvoid main()int a12,*p=a;for(int i=0;i12;i+)*p=i+1;/元素赋值 if(i%4=0)coutendl;cout*pt;p=p+1;,a12,p,a0,a1,a2,a9,a10,a11,*pa0,指针下跳1,*pa1,给一维数组赋值并按每4个一行方式输出,a23,a00,int a34;int*pa=a00;/指针指向数组首元素for(int i=1;i=12;i+)*pa=i;/给元素赋值 cout*pat;/输出元素的值 pa=pa+1;/指针往下走一单元/如果是4的倍数换行 if(i%4=0)coutendl;,给二维数组赋值并按每4个一行方式输出,行i,组j,列k,a,b,c,d,0,u,v,w,x,0,s6,p,char s6=abcde;char*p=s;coutpors;p=p+1;coutp;,例3.1#include void main()static int a5=5,4,3,2,1;int i,j;i=a0+a4;/下标表示 j=*(a+2)+*(a+4);/指针表示 coutitj;int*pa=a;pa=pa+1;/pa=?*pa=?pa+;/pa=?*pa=?a0、a1、a2=?,6 4,1005 4,1009 3,5 4 3,例3.2#include void main()static int b 4=1,2,3,4,5,6;b02=7;b12=8;cout*bt*(b+1)n;cout*(*b+1)t*(*(b+1)+2)n;coutb02+b12+b22;,7,8,输出结果为:1 4 2 815,#include iostream.hvoid main()static char s1=abcde,s25=m,n,p,q,0;char*ps=s1;couts1 or s2endl;coutpsn;couts21s22s13s14endl;cout*ps*(ps+2)*(ps+4)*ps+2;,abcde or mnpqabcdenpdeace99,S1,S2,ps,int A4,A0,A1,A2,A3,1000,1004,1008,100C,int B44,B0,B1,B2,B3,用数组存放26个字母并输出,#include iostream.hvoid main()char s 26;for(int i=0;i26;i+)si=A+i;/si=65+i/给数组元素赋值 coutsi;/输出数组,ABCDEFGHIJKLMNOPQ,引用作为一种数据类型,通常被认为是另一种变量的别名。其定义格式为:则m是对a的一个引用,所有对m的操作都是对a的操作。注意:引用必须初始化,且一旦被初始化后不能再被重新赋值。即不能改变引用目标。,3.2引用,8,引用可以针对一个常量。如:int,3.3 运算符,算术运算符关系运算符逻辑运算符位操作运算符赋值运算符其他运算符运算符的优先级和结合性,算术运算符,单目运算符(-(负)双目运算符(+(加)、-(减)、*(乘)、/(除)、%(模,求余)优先级为:负号级别最高,其次为*/%,再就是+-。要求:操作数为数值型数据其中%要求为整型/与%的第二操作数不为0特别注意“/”,当分子分母都是整数是做整除!,1、普通算术运算符,2、增1和减1运算符增量操作表示加1,减量操作表示减1。如:int a=4;a+;/等效于a=a+1;+a;/等效于a=a+1;a-;/等效于a=a-1;-a;/等效于a=a-1;增量操作符有前增量与后增量之分。前增量操作+a的意义为:先修改操作数的值再将增1后的a值作为表达式的值。而后增量操作a+的意义为:先将a的值作为表达式的值确定下来,再将a增1。,如:int a=3;int b=+a;int c=a+;则:a:5,b:4,c:4。相应的,有-a和a-。增量和减量操作符都是单目操作符。,近水楼台先得月,3,4,5,4,4,4,关系运算符,C+提供了6种关系运算符:(小于)、(大于)、=(小于等于)、=(大于等于)、=(等于)、!=(不等于)关系运算符都是双目运算符。优先级:、=、=四种比=、!=两种要高要求:两个操作数为同一类型其结果值为1(代表逻辑真)或0(代表逻辑假)。,逻辑运算符,三种逻辑运算符:&(逻辑与)、|(逻辑或)、!(逻辑非)。其中逻辑非为单目运算符,逻辑与和逻辑或为双目运算符。优先级:!的优先级最高,而&又比|要高。逻辑表达式中的操作数是作为逻辑量,但C+并不专门提供逻辑类型,只用1与0来代表逻辑结果真与假。对于参与逻辑运算的操作数,其值为0代表逻辑假,为非0时代表逻辑真。如:!(a=9),位操作运算符,位运算是指直接对int型或char型数据的各位进行运算。C+中的位运算符有两类:1、按位逻辑运算符共有四种:(按位取反运算符)、(按位与运算符)&(按位异或运算符)、(按位或运算符)|如:a:01101110,则a为10010001(按位取反)如:a:10101101,b:11001011则:a&b为10001001(都为1时才为1)ab为01100110(同号为0,异号为1)a|b为11101111(都为0时才为0)优先级:高于&,&高于,高于|。,2、移位运算符()移位运算是指将一个操作数中的各位都向左(用)移动若干位。如:a:10001101则:a4为00001000,赋值运算符,如:I=j=k=5;则等效于:k=5;j=k;I=j;当赋值号两边的数据类型不一致时,编译器会在赋值前将右操作数自动转换为同左操作数相同的类型。如:int a=3.14;/a:3注意:1、赋值运算符=与比较运算符=的混淆。2、int x=1;与int x;x=1;在概念上的区别。,在C+中,将算术运算符、位运算符同赋值运算符结合可形成复合赋值运算符。一共有十种:+=、-=、*=、/=、%=、=、&=、=、|=。如:a+=b 等效于 a=a+b注意:运算时右边的表达式是被作为一个整体参与运算的。如:a*=3+b 等效于 a=a*(3+b)而不是等效于 a=a*3+b,x=015 00001101 y=0 x2b 00101011 x|y 00101111 47 xy 00100110 38 x&y 00001001 9 x 1 1 1 1 0 0 1 0 y 1 1 0 1 0 1 0 0 x+y 10 0 0 0 0 1 1 0 x=4 0000 00102,例题:位运算,已知:unsigned int x=015,y=0 x2b,A:!a,int a(5),b(3);求表达式、a、b的值,9,1,0,5,3,1,5,3,3,1,3,15,10,4,8,8,3,1,5,3,简称:短路,A:d+-rd;B:*pd*rd;C:+*pd-rd;D:+rd-d;,int d(5),*pd=&d,&rd=d,求表达式的值,A:0B:25C:0D:0;,其他运算符,1、条件运算符语法为:(条件表达式)?(条件为真时的表达式):(条件为假时的表达式)如:x=ab?a:b;/实现把a和b中较小的值赋给x条件运算符是C+中唯一的一个三目运算符。,2、逗号运算符语法为:表达式1,表达式2,表达式n C+将顺序计算表达式1,表达式2,表达式n的值。而整个逗号表达式的值是表达式n的值。如:int a,b,c,d;d=(a=1,b=a+2,c=b+3);则:a、b、c、d的值分别为1、3、6、6,最后一个表达式的值就是逗号表达式的值,3、强制类型转换运算符用来将指定的表达式的值强制为所指定的类型。格式为:()或:()如:int a;double b=3.8921;a=int(b)+(int)b;则:a值为6注意:是对所求表达式的值指定类型,并不是改变b变量的类型。,运算符的优先级和结合性,1、优先级共15种优先级。分别为:元素/成员-单目-双目-三目-赋值-逗号常用的双目运算符的优先级又分为:算术-移位-关系-逻辑位-逻辑,2、结合性大多数为从左至右,只有三类是从右至左。分别为:单目、三目和赋值,除最高的元素成员,最低的逗号外,其余的一二三赋值,对双目运算:算术关系逻辑,移位逻辑位放中间,口诀:,3.5 表达式,表达式的种类表达式的值和类型表达式中的类型转换,表达式的种类,表达式是由运算符和操作数组成的式子。常见的有如下6种:算术表达式。如:a+5.2/3.0逻辑表达式。如:!a&8|7关系表达式。如:m=n赋值表达式。如:a=7条件表达式。如:a4?+a:-a逗号表达式。如:a+5,a=7,a+=4,表达式的值和类型,任何一个表达式经过计算都应有一个确定的值和类型。计算一个表达式的值时要注意两点:先确定运算符的功能。再确定计算顺序。要注意优先级和结合性的影响。一个表达式的类型由运算符种类和操作数类型来决定。如:1、算术表达式 int a=7*2+-3%5-4/3;/a:10b:3523.33 int m(3),n(4);a=m+-(-n);/a:0 m:4 n:3,如:2、关系表达式 char x(m),y(n);int n;n=x3)+(y-x=1);/n:3,如:3、逻辑表达式 int a(3),b(0);!a/a:3 a|b|b+/b:0注意:C+规定:在一个逻辑表达式中,当计算出一个子表达式的值后便可确定整个逻辑表达式的值时,后面的子表达式就不再计算。,简称:短路,如:4、条件表达式 int a(3),b(4),c;c=ab?+a:+b;/c:5 c=a-b?a+b:a-3?b:a;/c:8 从右向左结合 c=a-b?a+b:(a-3?b:a);/相当于,如:5、赋值表达式 int x(1),y(3),z(5);/从右向左结合 x+=y*=z-=2;/?(10,9,3)z=(x*=2)+(y+=4)+2;/?(2,7,11),如:6、逗号表达式 int a,b,c;a=1,b=2,c=a+b+3;/c:6 c=(a+,a+=b,a+b);/c:6,表达式中的类型转换,1、隐含转换一般双目运算中的两个操作数的类型是要一致,不一致则自动将低类型的数据向高类型转换,然后再运算并得到高类型的表达式值。所谓的类型高低关系如下:short,char-int-long-double,float-double如:3+4.0 a-4 2、强制转换将某种类型强制转换为指定的类型。并分为显式和隐式两种。如:b=a+int(3.14);/显式转换如:int a(5),b;b=a+3.14;/两次隐式转换,类型定义,即通过关键字typedef来为现有类型取别名。如:typedef double wages,bonus;作用:改善程序的可读性。(取一个有意义的类型别名)减少定义变量的过于繁琐。提高程序的可移植性。,第1行一个第2行二个。第N行N个,int i,j,n;coutn;for(int i=1;i=n;i+)for(j=1;j=i;j+)cout*;/打印若干个 coutendl;/换行,for(j=1;j=n-i+1;j+),第1行:4个,接着1个,换行第2行:3个,接着3个,换行第3行:2个,接着5个,换行第4行:1个,接着7个,换行第5行:0个,接着9个,换行,每行的个数:5-i每行的个数:2*i-1每次循环要做三件事:先打印(5-i)个 后,接着打印(2*i-1)个,再换行,for(int i=1;i=5;i+)for(j=1;j=5-i;j+)cout;/打印若干个 for(k=1;k=2*i-1;k+)cout;/打印若干个 coutendl;/换行,1,2,3,4,7,打印九九乘法口诀表,#include iostream.h#include iomanip.h/manipulate,操作void main()int i,j;for(i=1;i=9;i+)for(j=1;j=9;j+)couti*j=setw(2)i*j;coutendl;,设置后面内容宽度为2,for(j=1;j=10-i;j+),for(j=1;j=i;j+),for(i=1;i=9;i+)for(k=1;k=9-i;k+)cout;/7个空格 for(j=1;j=i;j+)couti*(9-i+j)=setw(2)i*(9-i+j);Coutendl;,3,2,#include iostream.h#include iomanip.h/manipulate,操作void main()int i,j;for(i=1;i=10;i+)for(j=1;j=11-i;j+)cout;/2个空格 for(j=1;j=i;j+)/限定为两个位置的长度 coutsetw(2)i;coutendl;,条件语句格式:if()else if()else if()else if()else,条件语句,格式如下:switch()case:case:case:default:/可无,语义为:根据对整型表达式的计算得到的值,从第一个case常量开始从上到下逐个进行匹配,若相等,则以此为入口,顺序向下执行各条语句序列。,开关语句,格式如下:switch()case:;break;case:;break;case:;break;default:/可无,通过加break强行跳转语句,在执行完第一个语句序列后,就强行跳出switch结构,格式:for(e1;e2;e3),计算e2,执行,非0,0,退出循环,计算e1,计算d3,e1;while(e2);e3;,for循环语句,格式:break;该语句在程序中可用于下列两种情况:1、在开关语句中,其功能是退出开关语句,执行其后的语句;2、在循环体中,其功能是用来退出该重循环,break语句,#define M 10void main()int num,sum(0);coutnum;if(num0)break;sum+=num;coutsum=sumendl;,求10个数之和,遇负数终止,格式:continue;功能:只用在循环体中,用来结束该次循环。在循环体中遇到continue语句时,本次循环结束,回到循环条件判断是否执行下一次循环。,continue语句,#define M 10void main()int num,sum(0);coutnum;if(num0)continue;sum+=num;coutsum=sumendl;,求10个中的正数之和,m是素数的条件是不能被2,3,m-1整除。long m;coutm;/输入 for(int I=2;I=m)coutmis prime.n;else coutmisnt prime.n;/输出,判断整数m其是否为素数,快速算法:判断它能否被2到sqrt(m)之间的数整除,若不能则是素数。long m;coutm;int sqrtm=sqrt(m);for(int I=2;I=sqrtm+1)coutmis prime.n;else coutmisnt prime.n;/输出,判断素数的快速算法,分析程序运行结果。int I(1),a(0);for(;I=5;I+)do i+;a+;while(I3);I+;couta,Iendl;,7,本讲作业1,1、编程实现两个浮点数的四则运算;2、编程求出50至100之内的素数并输出;3、求两个数的最大公约数和最小公倍数;4、求一元二次方程ax2+bx+c=0的解;5、打印如下图形:,1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 10 10 10 10 10 10 10 10 10,1、打印以下图形:A ABC ABCDE ABCDEFGABCDEFG.S,本讲作业2,2、百钱买百鸡。公鸡每只7元,母鸡每只5元,小鸡1元3只,用100地元买100只鸡(每种鸡都要有),请问公鸡母鸡小鸡各有多少?3、编程求水仙花数。水仙花数是指一个三位数,如果其各位数的立方和刚好等于该数本身)。如1531353334、求1000以内的所有完数(指一个数恰好等于它的包括1在内的所有因子之和)。如6123,5、将100元兑换成10、5、1元,有哪些兑换方法?,void main()double d1,d2;char op;double temp;coutd1opd2;switch(op)case+:temp=d1+d2;break;case-:temp=d1-d2;break;case*:temp=d1*d2;break;case/:temp=d1/d2;break;default:couterror!n;coutd1opd2=tempendl;,#include#include#define MIN 51#define MAX 100void main()int i,j,k,n(0);for(i=MIN;i=MAX;i+=2)k=(int)sqrt(double(i);for(j=2;j=k;j+)if(i%j=0)break;,if(j=k+1)if(n%6=0)coutendl;n+;cout i;/if/forcoutendl;/结束,编程求出50至100之内的素数,求两个数的最大公约数,int a,b,r;couta;coutb;if(ab)r=a,a=b,b=r;/交换两数 r=a%b;while(r)a=b;b=r;r=a%b;/辗转相除 cout最大公约数:bendl;,求两个数的最小公倍数,int a,b,s;couta;coutb;s=a;while(1)if(s%b=0)break;s+=a;cout最小公倍数:sendl;,int a,b;couta;coutb;while(a!=b)if(ab)a-=b;if(ab)b-=a;cout最大公约数:aendl;,求两个数的最大公约数(2),int a,b,k;couta;coutb;k=a*b;while(a!=b)if(ab)a-=b;if(ab)b-=a;cout最小公倍数:k/aendl;,求两个数的最小公倍数(2),int a,b;couta;coutb;if(a=1;i-)if(a%i=0,求两个数的最大公约数(3),int a,b,k;couta;coutb;if(ab)r=a,a=b,b=r;/交换两数 for(int i=a;i+)if(i%a=0,求两个数的最小公倍数(方法3),