c语言的指针和结构体课件模板.ppt
C C 语言中的指针与语言中的指针与结构体结构体1A指针指针的概念的概念地址地址 内容内容 变量名变量名intx=20,y=1,z=155;int*p;p=&x;100020 x10021y1004155z20001000p2002 指针变量指针变量指针变量指针变量:存放地址的变量:存放地址的变量某个某个变量变量的地址的地址指向指向(内存单元内存单元)2A指针变量所指向的变量的类型指针变量所指向的变量的类型int*p;p是整型指针,指向整型变量是整型指针,指向整型变量float*fp;fp是浮点型指针,指向浮点型变量是浮点型指针,指向浮点型变量char*cp;cp是字符型指针,指向字符型变量是字符型指针,指向字符型变量类型名类型名*指针变量名指针变量名指针声明符指针声明符指针变量的定义指针变量的定义3A取地址运算取地址运算(&)和间接访问运算和间接访问运算(*)*:间接访问运算符间接访问运算符,访问指针所指向的变量。,访问指针所指向的变量。*p:指针变量:指针变量p所所指向的指向的变量变量。a3&ap*p如果指针的值是某个变量的地址,通过指针就如果指针的值是某个变量的地址,通过指针就能能间接访问间接访问那个变量。那个变量。&:取地址运算符取地址运算符,给出变量的地址。,给出变量的地址。int*p,a=3;p=&a;把把a的地址赋给的地址赋给p,即,即p指向指向a/指针变量的类型和它所指向变量的类型相同指针变量的类型和它所指向变量的类型相同4Aa3&ap*p(1)当当p=&a后,后,*p与与a相同相同(2)int*p;定义定义指针变量指针变量p*p=10;指针指针p所指所指向向的变量的变量,即,即a,改变变量值,改变变量值(3)&*p与与&a相同,相同,是是地址地址*&a与与a相同,相同,是是变量变量(4)(*p)+等价于等价于a+将将p所指所指向向的变量值加的变量值加1*p+等价于等价于*(p+)/先取先取*p,然后,然后p自加自加,此时此时p不再指向不再指向a说明说明 inta=3,*p;p=&a;5A赋值运算赋值运算a3&ap1&ap2*p1*p2inta=3,*p1,*p2;p1=&a;/把把a的地址赋给的地址赋给p1,即,即p1指向指向ap2=p1;/p2也指向也指向a/相同类型的指针才能相互赋值相同类型的指针才能相互赋值6A注意:注意:指针指针变量必须初始化。变量必须初始化。voidmain()inta=1,b=2,*p1,*p2,*pt;p1=&a;p2=&b;printf(a=%d,b=%d,*p1=%d,*p2=%dn,a,b,*p1,*p2);pt=p1;p1=p2;p2=pt;printf(“a=%d,b=%d,*p1=%d,*p2=%dn”,a,b,*p1,*p2);return0;p1b2&bp2*p2a1&a*p1ptb2&ap2*p1a1&bp1*p2pt&aa=1;b=2;*p1=1,*p2=2a=1;b=2;*p1=2,*p2=17A指针指针作为函数参数作为函数参数voidswap(int*px,int*py)intt;t=*px;*px=*py;*py=t;要通过函数调用来改变主调函数中某个变量的值:要通过函数调用来改变主调函数中某个变量的值:(1)在主调函数中,在主调函数中,将该变量的地址或者指向该变量的将该变量的地址或者指向该变量的指针作为实参指针作为实参(2)在被调函数中,在被调函数中,用指针类型形参接受该变量的地址用指针类型形参接受该变量的地址(3)在被调函数中,改变形参所指向变量的值在被调函数中,改变形参所指向变量的值abpxpy1221/swap(&a,&b);8A数组和地址间的关系数组和地址间的关系int a100,*p;数组名代表一个地数组名代表一个地址,它的值是数址,它的值是数组首元素的地址组首元素的地址(基地址)(基地址)a+i是距数组是距数组a的的基地址的第基地址的第i个偏个偏移移3000a0地址地址 内容内容 数组元素数组元素3002a13198a99aiaa+1a+99a+i&ai*(a+i)sum=0;for(i=0;i 100;i+)sum=sum+ai ;*(a+i)下标运算符下标运算符的含义的含义9A任何由数组下标来实现的操作都能用指针来完成任何由数组下标来实现的操作都能用指针来完成inta100,*p;p=a;或或p=&a0;pp+1p+99p+i3000a0地址地址 内容内容 数组元素数组元素3002a13198a99aiaa+1a+99a+i&ai aia+i*(a+i)p+i*(p+i)&pipip=a;sum=0;for(i=0;i100;i+)sum=sum+pi;等价等价等价等价*(p+i)sum=0;for(p=a;p”访问指针指向的结构成员。访问指针指向的结构成员。p-age=26;当当p=&friend1时,以下三条语句相同:时,以下三条语句相同:friend1.age=26;(*p).age=26;p-age=26;29A结构体指针作为函数参数结构体指针作为函数参数当当结结构构指指针针作作为为函函数数的的参参数数时时,执执行行效效率率高高,可以完成比基本类型指针更为复杂的操作。可以完成比基本类型指针更为复杂的操作。例例:输输入入10个个学学生生的的学学号号、姓姓名名和和成成绩绩,输输出出学生的成绩等级和不及格人数。学生的成绩等级和不及格人数。每个学生的记录包括学号、姓名、成绩和等级每个学生的记录包括学号、姓名、成绩和等级要要求求定定义义和和调调用用函函数数set_grade根根据据学学生生成成绩绩设设置置等等级级,并统计不及格人数并统计不及格人数等级设置:等级设置:A:85100;B:7084;C:6069;D:05930A源程序源程序#defineN10structstudentintnum;charname20;intscore;chargrade;intmain(void)intcount;structstudentstuN,*ptr;ptr=stu;/*输入输入略略*/count=set_grade(ptr);intset_grade(structstudent*p)inti,n=0;for(i=0;iscore=85)p-grade=A;elseif(p-score=70)p-grade=B;elseif(p-score=60)p-grade=C;elsep-grade=D;n+;returnn;调用调用set_grade返回主函数后,主函数中结构体数组返回主函数后,主函数中结构体数组stu的的元素的元素的grade成员已经被赋值成员已经被赋值.与结构体变量作为函数参数相比,用结构体指针作为函数参与结构体变量作为函数参数相比,用结构体指针作为函数参数的效率更高,因而是更好的选择。数的效率更高,因而是更好的选择。31A多文件结构多文件结构工作区工作区工程工程1工程工程2工程工程n头文头文件件源文源文件件例:例:VC中的多文件结构中的多文件结构32A示例示例#include#include#include#include/常量定义常量定义#defineLIST_INIT_SIZE100#defineLISTINCREMENT10#defineOK1#defineERROR0#defineOVERFLOW-2#defineTrue1#defineFalse0/函数返回值类型定义函数返回值类型定义typedefintStatus;/表节点数据类型定义表节点数据类型定义typedefintElemType;/顺序表类型定义顺序表类型定义typedefstructElemType*elem;intlength;intlistsize;SqList;/顺序表各操作声明顺序表各操作声明StatusInitList_Sq(SqList&L);StatusDetroyList_Sq(SqList&L);StatusClearList_Sq(SqList&L);intListEmpty_Sq(SqListL);intListLength_Sq(SqListL);StatusGetElem_Sq(SqListL,inti,ElemType&e);StatusListInsert_Sq(SqList&L,inti,ElemTypee);StatusListDelete_Sq(SqList&L,inti,ElemType&e);voidPrintList_Sq(SqListL);头文件:头文件:SqList.h33A#includeSqList.h/各操作的实现各操作的实现StatusInitList_Sq(SqList&L)L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType);if(!L.elem)exit(OVERFLOW);L.length=0;L.listsize=LIST_INIT_SIZE;returnOK;StatusDetroyList_Sq(SqList&L)if(L.elem)free(L.elem);returnOK;StatusClearList_Sq(SqList&L)if(L.elem)L.length=0;L.listsize=0;returnOK;源文件:源文件:SqList.cpp34AintListEmpty_Sq(SqListL)return(L.length=0);intListLength_Sq(SqListL)returnL.length;StatusGetElem_Sq(SqListL,inti,ElemType&e)if(i=L.length)returnERROR;e=L.elemi-1;returnOK;35AStatusListInsert_Sq(SqList&L,inti,ElemTypee)ElemType*newbase,*p,*q;if(iL.length+1)returnERROR;if(L.length=L.listsize)newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType);if(!newbase)exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;q=&(L.elemi-1);for(p=&L.elemL.length-1;p=q;p-)*(p+1)=*p;*q=e;L.length+;returnOK;36AStatusListDelete_Sq(SqList&L,inti,ElemType&e)ElemType*p,*q;if(iL.length)returnERROR;p=&(L.elemi-1);e=*p;q=L.elem+L.length-1;for(+p;pq;+p)*(p-1)=*p;L.length-;returnOK;voidPrintList_Sq(SqListL)inti;if(L.length=0)cout该表为空该表为空endl;elsefor(i=0;iL.length;i+)coutL.elemi;37A#includeSqList.hvoidmain()SqListL;inti,num;cout创建顺序表创建顺序表endl;if(!InitList_Sq(L)cout表创建失败表创建失败;/创建空顺序表创建空顺序表Lelse/产生各节点产生各节点srand(time(NULL);for(i=0;i10;i+)/产生产生10个整数,插入顺序表表尾个整数,插入顺序表表尾num=rand()%100;ListInsert_Sq(L,i+1,(ElemType)num);源文件:源文件:SqDemo.cpp(包含主函数包含主函数main()38A/输出原始顺序表的各个值输出原始顺序表的各个值cout生成的原始表为:生成的原始表为:;PrintList_Sq(L);/输出第输出第2个节点的数据值个节点的数据值GetElem_Sq(L,2,num);coutendl第第2个元素值为:个元素值为:numendl;/删除第删除第2个节点个节点ListDelete_Sq(L,2,num);/输出修改后的顺序表的各个值输出修改后的顺序表的各个值cout修改后的表为:修改后的表为:;PrintList_Sq(L);coutendl;39A