软件技术基础软件技术基础课程安排总学时数:48学分数:3讲课:32学时上机:16学时C语言必备知识C程序设计中使用指针可以使程序简洁、紧凑、高效有效地表示复杂的数据结构动态分配内存得到多于一个的函数返回值实现很多不用指针无法实现的功能一、指针1.指针的概念变量与地址程序中:inti;floatk;内存中每个字节有一个编号-----地址(也称为指针)…...…...6500H6501H6502H6505H内存06503H程序执行时为其分配内存单元ik注:H表示16进制指针与指针变量指针:一个变量的地址指针变量:专门存放变量地址的变量指针指针变量变量的地址…...…...6500H6504H6506H6505H整型变量i=10变量p6501H6502H6503H106500H指针变量变量变量地址(指针)变量值变量的内容&与*运算符含义含义:取变量的地址单目运算符结合性:自右向左含义:取指针所指向变量的内容单目运算符结合性:自右向左两者关系:互为逆运算,即&*和*&相互抵消理解…...…...6500H6504H6506H6505H整型变量i=1010变量p=&i6501H6502H6503H6500H指针变量p-----指针变量,它的内容是地址量*p----指针的目标变量,它的内容是数据&p---指针变量占用内存的地址650010pi*pp等价于&i等价于&(*p)i等价于*p等价于*(&i)指针变量…...…...6500H6504H6506H6505H整型变量i=10变量p=&i6501H6502H6503H106500H直接访问与间接访问直接访问:按变量地址存取变量值间接访问:通过存放变量地址的变量去访问变量例i=3;-----直接访问例*p=20;-----间接访问320指针变量…...…...6500H6504H6506H6505H整型变量i变量p6501H6502H6503H整型变量k106500H例inti=10,*p;p=&i;k=*p;--间接访问102.指针变量指针变量与其所指向的变量之间的关系指针变量的定义一般形式:[存储类型]数据类型*指针变量名;3变量i6500H指针变量p*pi*p&ipi=3;*p=3合法标识符指针变量本身的存储类型指针的目标变量的数据类型表示定义指针变量不是‘*’运算符例int*p1,*p2;float*q;staticchar*name;注意:1、指针变量只能指向定义时所规定类型的变量2、指针变量定义后,变量值不确定指针变量的初始化一般形式:[存储类型]数据类型*指针名=初始地址值;赋给指针变量,不是赋给目标变量例inti;int*p=&i;变量必须是已定义过的例int*p=&i;inti;例inti;int*p=&i;int*q=p;可用已初始化的指针变量赋初值例指针的概念main(){inta;int*b=&a;a=10;printf(%d\n,a);printf(%d\n,*b);printf(%x\n,&a);printf(%x\n,b);printf(%x\n,&b);}运行结果:10104f864f864f8a…...…...4f86H4f8aH4f8cH4f8bH整型变量a10指针变量b4f87H4f88H4f89H4f86H内存内存地址指针变量作为函数参数——地址传递特点:共享内存,双向传递swap(intx,inty){inttemp;temp=x;x=y;y=temp;}main(){inta=5,b=9;swap(a,b);printf(\n%d,%d\n,a,b);}运行结果:例两个变量交换数值值传递5,9swap(int*p1,int*p2){intp;p=*p1;*p1=*p2;*p2=p;}main(){inta=5,b=9;int*pointer_1,*pointer_2;pointer_1=&a;pointer_2=&b;swap(pointer_1,pointer_2);printf(\n%d,%d\n,a,b);}运行结果:例两个变量交换数值地址传递9,53.指针与数组指向数组元素的指针变量例intarray[10];int*p;p=&array[0];//p=array;或int*p=&array[0];或int*p=array;array[0]array[1]array[2]array[3]array[9]...整型指针p&array[0]p数组名是表示数组首地址的地址常量数组元素表示方法a[0]a[1]a[2]a[3]a[9]...aa+9a+1a+2地址元素下标法a[0]a[1]a[2]a[9]a[0]a[1]a[2]a[3]a[9]...pp+9p+1p+2地址元素指针法*p*(p+1)*(p+2)*(p+9)[]变址运算符a[i]*(a+i)a[i]p[i]*(p+i)*(a+i)*a*(a+1)*(a+2)*(a+9)p[0]p[1]p[2]p[9]数组名作函数参数数组名作函数参数,是地址传递数组名作函数参数,实参与形参的对应关系实参形参数组名指针变量数组名指针变量数组名数组名指针变量指针变量4.指针与字符串字符串表示形式用字符数组实现例main(){charstring[]=IloveChina!;printf(%s\n,string);printf(%s\n,string+7);}IloveChistring[0]string[1]string[2]string[3]string[4]string[5]string[6]string[7]string[8]string[9]stringstring[10]string[11]string[12]string[13]n!a\0用字符指针实现例main(){char*string=IloveChina!;printf(%s\n,string);string+=7;while(*string){putchar(string[0]);string++;}}IloveChistringn!a\0字符指针初始化:把字符串首地址赋给stringchar*string;string=IloveChina!;string等价于*string!=05.指针数组和多级指针指针数组定义:数组中的元素为指针变量定义形式:[存储类型]数据类型*数组名[数组长度说明];例int*p[4];指针所指向变量的数据类型指针本身的存储类型区分int*p[4]与int(*p)[4]指针数组赋值与初始化main(){intb[2][3]={4,5,6,7,8,9};int*pb[2];pb[0]=b[0];pb[1]=b[1];……..}int*pb[2]pb[0]pb[1]intb[2][3]456789指针数组赋值与初始化Lisp\0Fortran\0Basic\0p[0]p[1]p[2]p[3]0赋值:main(){chara[]=Fortran;charb[]=Lisp;charc[]=Basic;char*p[4];p[0]=a;p[1]=b;p[2]=c;p[3]=NULL;……..}或:main(){char*p[4];p[0]=Fortran;p[1]=Lisp;p[2]=Basic;p[3]=NULL;……..}初始化:main(){char*p[]={Fortran,Lisp,Basic,NULL};……..}Lisp\0Fortran\0Basic\0p[0]p[1]p[2]p[3]0多级指针定义:指向指针的指针一级指针:指针变量中存放目标变量的地址p1&p2&i3p2i例int**p1;int*p2;inti;p2=&i;p1=&p2;**p1=3;二级指针:指针变量中存放一级指针变量的地址例int*p;inti=3;p=&i;*p=5;&i3P(指针变量)i(整型变量)一级指针单级间接寻址二级指针一级指针目标变量二级间接寻址定义形式:[存储类型]数据类型**指针名;如char**p;例inti,**p;p=&i;╳(p是二级指针,不能用变量地址为其赋值)指针本身的存储类型目标变量的数据类型例inti=3;int*p1;int**p2;p1=&i;p2=&p1;**p2=5;ip1p23&i&p1**p2,*p1*p2多级指针例三级指针int***p;四级指针char****p;*p2是p2间接指向的目标变量的地址**p2是p2间接指向的目标变量的值定义含义inti;int*p;inta[n];int*p[n];int(*p)[n];intf();int*p();int(*p)();int**p;定义整型变量ip为指向整型数据的指针变量定义含n个元素的整型数组an个指向整型数据的指针变量组成的指针数组pp为指向含n个元素的一维整型数组的指针变量f为返回整型数的函数p为返回指针的函数,该指针指向一个整型变量p为指向函数的指针变量,该函数返回整型数p为指针变量,它指向一个指向整型变量的指针变量指针的数据类型二、结构体结构体是一种构造数据类型用途:把不同类型的数据组合成一个整体-------自定义数据类型结构体类型定义struct[结构体名]{类型标识符成员名;类型标识符成员名;…………….};成员类型可以是基本型或构造型struct是关键字,不能省略自定义的结构体类型可省略:无名结构体例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};namenumsexagescoreaddr2字节2字节20字节1字节4字节30字节……..结构体类型定义描述结构的组织形式,不分配内存结构体类型定义的作用域例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};structstudentstu1,stu2;1.结构体变量的定义先定义结构体类型,再定义结构体变量一般形式:struct结构体名{类型标识符成员名;类型标识符成员名;…………….};struct结构体名变量名表列;例#defineSTUDENTstructstudentSTUDENT{intnum;charname[20];charsex;intage;floatscore;charaddr[30];};STUDENTstu1,stu2;定义结构体类型的同时定义结构体变量一般形式:struct结构体名{类型标识符成员名;类型标识符成员名;…………….}变量名列表;例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;直接定义结构体变量一般形式:struct{类型标识符成员名;类型标识符成员名;…………….}变量名表列;例struct{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;2.结构体变量的引用引用规则结构体变量不能整体引用,只能引用变量成员可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用成员(分量)运算符结合性:从左向右引用方式:结构体变量名.成员名例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;stu1.num=10;stu1.sex='M';stu1.age++;stu1.score+=stu2.score;例structstudent{intnum;charname[20];charsex;intage;floatscore;charaddr[30];}stu1,stu2;stu