您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 第二讲 指针和自定义数据类型
第二讲指针和自定义数据类型y=++px——y=(++px)y=px++——y=(px++)注意优先级和结合顺序问题:y=px++和y=(px)++的含义?structstudent{intnumber;charname[4];}student*pst;2.1指针及其运算2.1.1指针的算术运算pstpst=pst+1;pxn:pxnsizeof(T)px-py:((int)px-(int)py)/sizeof(T)px+n,px-n——将指针从当前位置向前或向后移动n个数据单位,而不是n个字节。这取决于指针所指向的数据类型(T)。px-py求出的是两指针位置之间的数据个数,而不是地址差。2.1.2指针的关系运算是对两个相同类型的指针的运算,如pxpy,当px所指位置在py之前时,表达式的值为1,否则为0。px==0,px!=0用来判断px是否为空指针。2.1.3指针的赋值运算赋的值必须是地址常量或变量,而不能是普通整数,有以下几种形式:1.变量地址赋予指向相同数据类型的指针charc,*pc;pc=&c;2.指针赋予相同数据类型的另一指针int*p,*q;inti;q=&i;p=q;不同类型的指针以及指针和一般整数间的关系运算是无意义的。2.2指针和数组2.2.1指针与数组的关系可以用指针代替数组下标来访问数组:f(){inta[5];int*pa;pa=a;*(pa+3)=10;pa[3]=10;*(a+3)=10;a[3]=10;}2.2.2字符指针与字符数组可用字符数组表示字符串,也可用字符指针指向字符串的首址。指针指向字符串可以多次指向不同串值,只要将字符串首址赋给它。字符数组是常量不能赋值。指针与数组的差异:指针是地址变量,可任意改变它的值;数组名是地址常量,其值不能改变。ex.1includeiostream.hmain(){staticcharstr[]=string;char*ps;ps=str;while(*ps!='\0'){cout*ps;ps++;}coutendl;}2.2.3指针数组指向同一类型对象的指针组成的数组。每个数组元素都是一指针变量。存储类型数据类型*指针数组名[元素个数]ex.2voidmain(){inta[2][3],*pa[2];pa[0]=a[0];pa[1]=a[1];for(inti=0;i3;i++)*(pa[0]+i)=i;for(i=0;i3;i++)*(pa[1]+i)=i;}pa[0]pa[1]012012pa[2]a[2][3]a[0][0]a[0][1]a[0][2]a[1][0]a[1][1]a[1][2]2.3指针和函数2.3.1指针函数(指针作为函数的返回值)存储类型数据类型*函数名(参数表)ex.3char*string_name(intn){char*string[]={illegalstring,string1,string2,string3}return(n1||n3)?string[0]:string[n];}static返回的是变量地址,必须保证函数返回后,这个变量仍然存在。要返回函数中局部变量的地址,应声明为静态的。2.3.2函数指针(函数的入口地址可赋给指针)虽然函数不是变量,仍占存储空间,此空间的首地址——函数入口地址。存储类型数据类型(*函数指针名)(参数表)ex.4int(*fp)(char);//fp为一函数指针,此函数的返回值为int,参数为char要将函数指针指向一具体的函数,用赋值语句:ex.5intf(char);fp=&f;inti=f('a');inti=(*fp)('a');要保证函数指针的参数和返回值与所指向的函数正好匹配。ex.6void(*fp)(char*);voidf1(char*s1);intf2(char*s2);voidf3(int*i1);voidmain(){fp=&f1;fp=&f2;fp=&f3;(*fp)(asdf);(*fp)(1);inti=(*fp)(qwer);}C++不能把函数当作参数传递,但传递函数指针允许。ex.7voidsort(void*base,unsignedintn,unsignedintsz,int(*cmp)(void*,void*)){//把n个元素的向量base按升序排列,向量每个元素大小szfor(inti=0;in-1;i++)for(intj=n-1;ij;j--){char*pj=(char*)base+j*sz;//b[j]char*pj1=pj-sz;//b[j-1]if((*cmp)(pj,pj1)0){for(intk=0;ksz;k++){chartemp=pj[k];pj[k]=pj1[k];pj1[k]=temp;}}}}void*性质:任何类型的指针都可以赋给它。作为参数传入指向任何类型的指针都可与它匹配。两个比较函数:#includestring.hintcmp_int(void*p,void*q){if(*(int*)p*(int*)q)return–1;elseif(*(int*)p==*(int*)q)return0;elsereturn1;}intcmp_str(void*p,void*q){returnstrcmp(*(char**)p,*(char**)q);}主程序:#includeiostream.hintmain(){staticintii[]={3,9,5,4};staticchar*str[]={compare,the,string};sort(ii,4,sizeof(int),&cmp_int);sort(str,3,sizeof(char*),&cmp_str);coutTheresultofsortstring:endl;for(inti=0;i3;i++)coutstr[i];}ex.8intf(inti);intf(charc);int(*fp1)(int)=&f;int(*fp2)(char)=&f;int(*fp3)(double)=&f;int(*fp4)(…)=&f;指向常量的指针:constT*pp*p&p修改╳修改√指针常量:T*constpp*p&p修改√修改╳指向常量对象的指针常量:constT*constpp*p&p修改╳修改╳ex.9constintn=1;int*pInt;pInt=&n;╳*pInt=2;╳2.4指针、引用、常量和复杂类型2.4.1指针与常量C++函数可重载,在函数指针赋值时要注意二义性。注意:不能把一个const变量的地址赋给指向非const的指针,否则会无形中改变常量的值2.5结构、联合、和用户自定义类型2.5.1结构的定义和声明structperson{charname[20];charsex;charaddr[50];doublesalary;};定义了结构的组成,未分配存储单元嵌套不能包含自身结构的成员可以是变量,数组,也可是指针和函数。使用结构要创建对象:structpersonLiMing;structperson*p=newperson;结构嵌套(结构的成员是另一结构对象):structdatestructperson{{intday;charname[20];charmonth[5];charsex;intyear;charaddr[50];};doublesalary;datebirthday;}2.5.2对结构的操作运算符.按对象访问成员;运算符-按指针访问成员。如:LiMing.Salary=1200.56;p-sex='M';2.5.3结构、指针和数组结构名结构数组名[元素个数];结构名*结构指针名;ex.10personcompany[52];person*pperson=company;cout(*(pperson+3)).nameendl;结构中成员指针的类型没有任何限制,可以是基本类型,也可以是结构,甚至可以定义引用自身的结构。ex.11structinode{intdata;inode*next;};举例:70%的学生通过考试,从键盘输入学生姓名和成绩,按分数高低输出,并用pass或fail表示是否通过考试ex.12#includestring.h#includeiostream.hstructSTUDENT{charname[30];intgrade;};voidsortclass(STUDENTst[],intnst);voidswap(STUDENT&ps1,STUDENT&ps2);voidmain(){STUDENT*classes;intns;coutNumberofstudents:\n;cinns;classes=newSTUDENT[ns];cout“Enternameandgradeforeachstudent\n”;for(inti=0;ins;i++)cinclasses[i].nameclasses[i].grade;sortclass(classes,ns);constintcutoff=(ns*7)/10-1;for(i=0;ins;i++){coutclassed[i].nameclass[i].grade;if(i=cutoff)coutpass\n;elsecoutfail\n;}}voidsortclass(STUDENTst[],intnst){for(inti=0;i(nst-1);i++){intpick=i;for(intj=i+1;jnst;j++){if(st[j].gradest[pick].grade)pick=j;}swap(st[i],st[pick]);}}voidswap(STUDENT&ps1,STUDENT&ps2){STUDENTtemp;strcpy(temp.name,ps1.name);temp.grade=ps1.grade;strcpy(ps1.name,ps2.name);ps1.grade=ps2.grade;strcpy(ps2.name,temp.name);ps2.grade=temp.grade;}2.5.5联合union联合名{数据类型成员名1;数据类型成员名2;……数据类型成员名n;};成员1、成员2、……成员n共享内存,编译器总是按联合中最大成员类型分配内存。2.5.6枚举(一个有名字的整数集合)enum枚举名{标识符1,标识符2,…,标识符n}例如:enumcolor{red,white,black};//red=0,white=1,black=2colorchair;//chair的取值只能是red,white或black枚举的使用:ex.13voidf(){colorsuit=white;inti=red;suit=i;//错,suit=color(i);//正确,把整数赋给枚举类型要强制类型转换i=suit;suit=4;//错}在特定时刻,联合只有一个成员被保存,而不提供其它成员的信息。标识符的值也可以自己定义:例如:enumcolor{red,white=7,black=2};匿名枚举表示一组常量:例如:enum{ASM,AUTO,BREAK};constintASM=0;constintAUTO=1;constintBREAK=2;2.5.7类型定义typedef(为数据类型定义新名)typedefchar*STRING;char*str;typedefchar(*PFC)(int,char*);PFCf1;STRINGstr;2.6结构与函数2.6.1结构用作函数参数和返回值多个成员的参数传递效率低,一般用结构指针或引用。尽管不允许函数返回数组,但返回整个结构是可以的。效率低的问题仍然可通过指针或引用解决,但只能用全局变量和静态变量。2.6.2成员函数(函数
本文标题:第二讲 指针和自定义数据类型
链接地址:https://www.777doc.com/doc-3961962 .html