1第六章指针本章要点:一.地址和指针的概念二.变量的指针和指向变量的指针变量三.数组的指针和指向数组的指针变量四.字符串的指针和指向字符串的指针变量五.指针数组和指向指针的指针六.有关指针的数据类型和指针运算的小结一.地址和指针的概念地址:如果在程序中定义了一个变量,在编译时就给这个变量分配内存单元。系统根据程序中定义的变量类型,分配一定长度的空间。例如,C编译系统一般为整型变量分配4个字节,为单精度浮点型变量分配4个字节,为字符型变量分配1个字节。内存区的每一个字节有一个编号,这就是“地址”。变量地址与变量内容如果在程序中定义了一个变量,在编译时就给这个变量分配相应的内存单元。内存区中每一个字节有一个编号,即“地址”。对变量值的存取都是通过地址进行的。直接访问与间接访问按变量地址直接存取变量值的方式为“直接访问”方式。将变量的地址存放在另一个变量中的方式为“间接访问”方式。指针与指针变量指向——通过地址来体现指针——变量的地址指针变量——专门用来表示指针的变量2二.变量的指针和指向变量的指针变量变量的指针——变量的地址指针变量——存放变量指针的变量1.定义一个指针变量基类型*指针变量名说明:1)指针变量名前面的“*”表示该类型为指针类型,不是指针变量名中的一部分;2)在定义指针变量时必须指定基类型;3)一个指针变量只能指向同一类型(基类型)的变量;4)指针变量中只能存放地址(指针);2.合法的定义int*pointer_1,*pointer_2;//定义指针变量*pointer_1,*pointer_2float*pointer_3;//pointer_3是指向单精度型数据的指针变量char*pointer_4;//pointer_4是指向字符型数据的指针变量3.指针变量的引用两个有关的运算符&:取地址运算符*:指向运算符(间接访问运算符)pointer_1=&i;//将变量i的地址存放到指针变量pointer_1中pointer_2=&j;//将变量j的地址存放到指针变量pointer_2中通过指针变量访问整型变量\cy6_1\main(){inta,b;int*pointer_1,*pointer_2;//定义指向整型变量的指针变量3a=100;b=10;pointer_1=&a;//把变量的地址赋值给指针变量pointer_2=&b;printf(“%d,%d\n”,a,b);printf(“%d,%d\n”,*pointer_1,*pointer_2);//输出指针变量所指向的变量值}拓展说明:1.调式技巧,断点的设置,执行跟踪,变量值(地址)的观察。2.分析:变量值、地址43.观察:*,&的意义输入两个整数a,b,按先大后小输出a,b.\cy6_2\main(){int*p1,*p2,*p,a,b;//p1,p2,p为指向整型变量的指针变量,a,b为整型变量//并且保证p1指向较大数,p2指向较小数printf(Pleaseinputaandb:);scanf(“%d,%d”,&a,&b);p1=&a;//p1取变量a的地址p2=&b;if(ab)//a,b变量值不便,但指针指向改变{p=p1;p1=p2;p2=p;}printf(“\na=%d,b=%d\n”,a,b);//输出a,b的值printf(“max=%d,min=%d\n”,*p1,*p2);//输出p1,p2所指向的变量的值}5三.数组的指针和指向数组的指针变量变量有地址。数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。数组第一个元素的地址为该数组的地址,用数组名表示。数组的指针——是指数组的起始地址,数组名代表数组首地址。数组元素的指针——数组元素的地址。1,指向数组的指针数组名本身代表数组的首地址,即下标为0的元素的地址。数组名本身不是变量,其值固定,为数组的首地址。数组名不代表整个数组。2,对指针的算术运算指针变量进行加减运算指针指向存储单元的数据进行算术运算例:指针移动和指针比较。\cy6_4\#includestdio.hvoidmain(){inta[10]={0,1,2,3,4,5,6,7,8,9};int*p=NULL,*q=NULL;p=a;q=&a[3];p=p+8;if(qp)printf(qp\n);elseprintf(q=p\n);printf(q-p=%d\n,q-p);printf(*q-*p=%d\n,*q-*p);}63,通过指针引用数组元素如果指针变量p已指向数组中的一个元素,则,p+1指向同一数组中的下一个元素(而不是将p值简单的加1)如果p的初始值为&a[0](假设p为指针变量,a为数组名,p=&a[0]),则,*(p+i),*(a+i),a[i]表示的都是数组中下标为i的元素,其中p+i,a+i均指向该元素地址,但其实际地址为a+i*d(d为数组中每个元素所占的字节数)上述的数组元素引用中,a[i]为下标法引用,*(p+i),*(a+i)为指针法引用,其中的p是指针变量,其值可变化,即*(p++)是合法的运算并具有实际意义,而a是数组名,其值固定为数组首地址,是一个常量,故*(a++)无实际意义,在程序中无法实现。将++和--用于指针变量是十分有效的,它可以使指针变量自动向前或向后移动,从而指向数组中上一个或下一个的元素例,输出数组中的全部元素。\cy6_3\main(){inta[10],i;int*p;for(i=0;i10;i++){printf(“a[%d]=“,i);scanf(“%d”,&a[i]);}//利用下标法printf(“\nUseMethod1:\n”);for(i=0;i10;i++)printf(“%d”,a[i]);//通过数组名计算数组元素地址printf(“\nUseMethod2:\n”);for(i=0;i10;i++)printf(“%d”,*(a+i));//利用指针法指向数组元素printf(“\nUseMethod3:\n”);for(p=a;p(a+10);p++)printf(“%d”,*p);}73,指向多维数组的指针和指针变量多维数组的地址按行优先存储指向多维数组的指针变量多维数组的指针作为函数参数二维数组名a表示数组的首地址,是a[0][0]的地址。但,a+1表示的地址不是a[0][1]的地址,而是下一行的第一个元素的地址,即a[1][0]的地址。a+2表示的地址是a[2][0]的地址。以此类推。二维数组a中,a+i中i的变化是按行进行。指向二维数组的指针同样按行进行,故需要定义行指针p。即:类型名(*指针名)[m];其中m为正整数,m的值必须与指针变量所指向的数组的列数相等(即每行元素的个数)。例:指针与二维数组。\cy6_6\voidmain(){inti=0,j=0;inta[3][2]={{1,2},{3,4},{5,6}};int(*p)[2];//定义p为行指针,p[]中的数值与所指向的数组中的列数相等p=a;for(i=0;i3;i++){for(j=0;j2;j++)printf(a[%d][%d]=%d,i,j,a[i][j]);for(j=0;j2;j++)printf(p[%d][%d]=%d,i,j,p[i][j]);//p是指向数组的指针,但可以用数组下标的表示方式printf(\n);}//数组每一行第1个元素的地址printf(pointertoa,a+1,a+2=%x,%x,%x\n,a,a+1,a+2);//数组各行首地址printf(pointertoa,a+1,a+2=%x,%x,%x\n,p,p+1,p+2);}8拓展问题:1.如何理解a,a[i],a[i][j]?2.如何理解p,p[i],p[i][j]?3.地址0x0018ff28、0x0018ff30和0x0018ff38的关系如何理解?四.字符串的指针和指向字符串的指针变量1,字符串的表示形式用字符数组存放一个字符串,然后进行处理并完成输出用字符指针指向一个字符串例:字符数组名引用字符串。\cy6_5\#includestdio.h#includestring.hvoidmain(){inti;chara[8]=First;//第1次为字符串赋值printf(1st:\n);puts(a);//第1次输出字符串printf(2nd:\n);printf(%s\n,a);//第2次输出字符串strcpy(a,Second);//第2次为字符串赋值printf(3rd:\n);9for(i=0;*(a+i)!='\0';i++)putchar(*(a+i));printf(\n);//第3次输出字符串printf(4th:\n);for(i=0;*(a+i)!='\0';i++)putchar(a[i]);printf(\n);//第4次输出字符串printf(5th:\n);for(i=0;*(a+i)!='\0';i++)printf(%c,*(a+i));printf(\n);//第5次输出字符串}例:用指针变量引用字符串。\cy6_7\#includestdio.hvoidmain(){char*p=First;//第1次为字符串赋值char*p1;printf(1st:);puts(p);//第1次输出字符串printf(2nd:);printf(%s\n,p);//第2次输出字符串p=Second;//第2次为字符串赋值p1=p;printf(3rd:);for(;*p1!='\0';p1++)putchar(*p1);printf(\n);//第3次输出字符串p1=p;printf(4th:);for(;*p1!='\0';p1++)printf(%c,*p1);printf(\n);//第4次输出字符串}拓展讨论:比较上述2个例程。102,对使用字符指针变量和字符数组的讨论字符数组由若干个元素组成,每个元素中放一个字符字符指针变量中存放字符串的首地址字符数只能对各个元素逐个赋值,字符指针变量可以用字符串加以赋值(此时的字符指针变量就是字符串的首地址)提高部分:五.指针数组和指向指针的指针1,指针数组的概念指针数组——元素均为指针类型数据的数组类型名*数组名[数组长度]指针数组比较适合于用来指向若干个字符串,使字符串处理更加方便2,指向指针的指针3,指针数组作main函数的形参六.有关指针的数据类型和指针运算的小结1.指针变量加(减)一个整数p++;p--;p+i;p-i;……2.指针变量赋值p=&a;p=array;p=&array[0];p1=p2;……3.指针变量为空p=NULL;(NULL是整数0)4.两个指针变量可以相减两个指针变量相减,其值表示两个指针之间的元素个数但指针变量相加无意义5.两个指针变量的比较若两个指针变量指向同一数组的元素,则可以进行比较,指向前面的元素的指针变量“小于”指向后面元素的指针变量。如果两个指针变量指向非同一数组元素则比较无意义。七、上机实训(一)P179,训练6.1(二)P180,训练6.2(三)P181,训练6.3(四)P182,训练6.411八.程序设计题库(以下程序均要求用指针来处理)1.P183思考题1,2,3,42.P183基础练习1,2,3,4,5,63.P184程序设计题74.P184程序设计题85.P184程序设计题96.P184程序设计题107.P184程序设计题118.P184程序设计题129.交换数组A和B中对应的元素。10.通过指针合并两个字符串。11.通过指针求字符串的长度。12.完成对输入的10个整数的冒泡排序(有大到小)。13.完成函数insert(s1,s2,f),实现在字符串s1中的指定位置f处插入字符串s2。14.编写一个函数,完成对一个长度为n的字符串从其第K个字符起,删去m个字符,组成长度为n-m的新字符串(其中n,