您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 谭浩强_c语言程序设计教程_学习笔记_第8章
第8章指针8.1地址和指针的概念按变量地址存取变量值的方式,成为“直接访问”方式。“间接访问”将变量的地址存放在另一个变量中。一个变量的地址称为该变量的“指针”。如果有一个变量专门用来存放另一个变量的地址(即指针),则它称为“指针变量”,指针变量就是地址变量(存放地址的变量)。指针变量的值(即指针变量中存放的值)是地址(指针)。8.2变量的地址和指向变量的指针地址变量的指针就是变量的地址。存放地址的变量是指针变量,它用来指向另一个变量。用“*”表示“指向的对象”。8.2.1怎样定义指针变量?指针变量的基类型用来指定此指针变量可以指向的变量类型。定义指针变量一般形式为:基类型*指针变量名;说明:(1)指针变量前的“*”表示该变量的类型为指针类型。(2)定义指针类型时必须指定基类型。对指针变量赋值时需要注意:(1)指针变量中只能存放地址。(2)赋给指针变量的变量地址不能是任意类型,而只能是与指针变量的基类型具有相同类型的变量的地址。8.2.2怎样引用指针变量(1)给指针变量赋值。p=&a;(2)引用指针变量的值。如:printf(“%o”,p);作用是以八进制输出指针变量p的值,如果p指向了a,就是输出a的地址,即&a。(3)引用指针变量指向的变量。(1)“&”算去地址运算符。(2)“*”指针运算符。例8.1通过指针变量访问整型变量#includestdio.hintmain(){inta,b;int*pointer_1,*pointer_2;a=100;b=200;pointer_1=&a;pointer_2=&b;printf(a=%d,b=%d\n,a,b);printf(*pointer_1=%d,*pointer_2=%d,*pointer_1,*pointer_2);return0;}例8.2输入a,b连个整数,按先大后小的顺序输出a,b。#includestdio.hintmain(){int*p,*p1,*p2;inta,b;printf(pleaseentera,b:\n);scanf(%d,%d,&a,&b);p1=&a;p2=&b;if(ab){p=p1;p1=p2;p2=p;}printf(a=%d,b=%d\n,a,b);printf(max=%d,min=%d\n,*p1,*p2);return0;}8.2.3指针变量作为函数参数指针变量作函数参数的作用是将一个变量的地址传到另一个函数中。例8.3输入a,b连个整数,按先大后小的顺序输出a,b。用指针变量作函数参数。#includestdio.hintmain(){voidswap(int*,int*);int*p1,*p2;inta,b;printf(pleaseentera,b:\n);scanf(%d,%d,&a,&b);p1=&a;p2=&b;if(ab)swap(p1,p2);printf(a=%d,b=%d\n,a,b);printf(max=%d,min=%d\n,*p1,*p2);return0;}voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}不可能通过执行调用函数来改变实参指针变量的值,但是却可以改变实参指针变量所指变量的值。例8.4输入3个整数a,b,c,要求按大小顺序将它们输出。用函数实现改变这3个变量的值。#includestdio.hintmain(){voidexchange(int*,int*,int*);int*p3,*p1,*p2;inta,b,c;printf(pleaseentera,b,c:\n);scanf(%d,%d,%d,&a,&b,&c);p1=&a;p2=&b;p3=&c;exchange(p1,p2,p3);printf(%d,%d,%d\n,a,b,c);return0;}voidexchange(int*q1,int*q2,int*q3){voidswap(int*,int*);if(*q1*q2)swap(q1,q2);if(*q1*q3)swap(q1,q3);if(*q2,*q3)swap(q2,q3);}voidswap(int*p1,int*p2){inttemp;temp=*p1;*p1=*p2;*p2=temp;}8.3通过指针引用数组8.3.1数组元素的指针所谓数组元素的指针就是数组元素的地址。8.3.2指针的运算说明:(1)P+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。(2)如果p原来指向a[0],执行++p后p的值改变了,在p的原值基础上加d,这样p就指向数组的下一个元素a[1].(3)如果p的初值是&a[0],则p+i和a+i就是数组元素a[i]的地址。(4)*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i].(5)如果指针变量p1和p2都指向同一数组,如执行p2-p1,结果是两个数组之差,除以数组元素长度。8.3.3通过指针引用数组元素(1)下标法,a[i]。(2)指针法,*(a+i)。例8.5有一个整型数组a,有10个元素,输出数组中的全部元素。(1)下标法#includestdio.hintmain(){inta[10];inti;for(i=0;i10;i++)scanf(%d,&a[i]);for(i=0;i10;i++)printf(%d\t,a[i]);printf(\n);}(2)通过数组名计算数组元素地址,找出元素的值。#includestdio.hintmain(){inta[10];inti;for(i=0;i10;i++)scanf(%d,&a[i]);for(i=0;i10;i++)printf(%d\t,*(a+i));printf(\n);}(3)用指针变量指向数组元素#includestdio.hintmain(){inta[10];inti,*p;for(i=0;i10;i++)scanf(%d,&a[i]);for(p=a;p(a+10);p++)printf(%d\t,*p);printf(\n);}例8.6通过指针变量输出a数组的10个元素。#includestdio.hintmain(){int*p,i,a[10];p=a;for(i=0;i10;i++)scanf(%d,p++);p=a;for(i=0;i10;i++,p++)printf(%d\t,*p);printf(\n);}8.3.4用数组名作函数参数表以变量名和数组名作为函数参数的比较实参类型变量名数组名要求形参的类型变量名数组名或指针变量传递的信息变量的值实参数组首元素的地址通过函数调用能否改变实参的值不能能改变是参数组元素的值用变量名作为函数参数传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参是指针变量。例8.7将数组a中n个整数按相反顺序存放。#includestdio.hintmain(){voidinv(intx[],intn);inta[10]={23,445,6,67,7,67,576,4,3,324},i;printf(Theoriginalarray:\n);for(i=0;i10;i++)printf(%d\t,a[i]);printf(\n);inv(a,10);printf(Thearrayhasbeenreversed:\n);for(i=0;i10;i++)printf(%d\t,a[i]);return0;}voidinv(intx[],intn){inttemp,i,j,m=(n-1)/2;for(i=0;im;i++){j=n-1-i;temp=x[i];x[i]=x[j];x[j]=temp;}}归纳起来,如果有一个实参数组要想在函数中改变此数组种元素的值,实参与形参的对应关系有以下4种情况:(1)形参和实参都有用数组名;(2)实参用数组名,形参用指针变量;(3)实参形参都引用指针变量;(4)实参为指针变量,形参为数组名;例8.8用实参指针变量改写例8.7.#includestdio.hintmain(){voidinv(int*x,intn);int*p,a[10]={23,445,6,67,7,67,576,4,3,324},i;printf(Theoriginalarray:\n);for(i=0;i10;i++)printf(%d\t,a[i]);printf(\n);p=a;inv(p,10);printf(Thearrayhasbeenreversed:\n);for(p=a;pa+10;p++)printf(%d\t,*p);return0;}voidinv(int*x,intn){inttemp,*i,*j,*p,m;m=(n-1)/2;i=x;j=x+n-1;p=x+m;for(;i=p;i++,j--){temp=*i;*i=*j;*j=temp;}}例8.9用选择法对十个整数按由大到小排序。#includestdio.hintmain(){voidsort(intx[],intn);inta[10],i,*p;printf(pleaseenter10numbers:\n);p=a;for(i=0;i10;i++)scanf(%d,p++);p=a;sort(p,10);for(p=a,i=0;i10;i++){printf(%d\t,*p);p++;}printf(\n);}voidsort(intx[],intn){inti,j,k,t;for(i=0;in-1;i++){k=i;for(j=i+1;jn;j++)if(x[k]x[j])k=j;if(k!=i){t=x[i];x[i]=x[k];x[k]=t;}}}用指针变量作函数形参:#includestdio.hintmain(){voidsort(int*x,intn);inta[10],i,*p;printf(pleaseenter10numbers:\n);p=a;for(i=0;i10;i++)scanf(%d,p++);p=a;sort(p,10);for(p=a,i=0;i10;i++){printf(%d\t,*p);p++;}printf(\n);}voidsort(int*x,intn){inti,j,k,t;for(i=0;in-1;i++){k=i;for(j=i+1;jn;j++)if(*(x+k)*(x+j))k=j;if(k!=i){t=*(x+i);*(x+i)=*(x+k);*(x+k)=t;}}}8.3.5通过指针引用多维数组1多维数组元素的地址多维数组中*(a+i)只是a[i]的另一种表示形式。二维数组中,a+i指的不是一个数组元素的存储单元。在二维数组中,a+i,a[i],*(a+i),&a[i],&a[i][0]的值相等,即它们代表同一地址。2.指向多维数组元素的指针变量例8.10用指向元素的指针变量输出二维数组各元素的值。#includestdio.hintmain(){int*p,a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};for(p=a[0];pa[0]+12;p++){if((p-a[0])%4==0)printf(\n);printf(%d\t,*p);}return0;}例8.11输出二维数组任一行任一列元素的值。#includestdio.hintmain(){inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12},i,j;int(*p)[4];p=a;scanf(%d,%d,&i,&j);printf(a[%d][%d]=%d,i,j,*(*(p+i)+j));return0;}int(*p)[4]表示p是一个指针变量,它指向包含4个整型元素的一维数
本文标题:谭浩强_c语言程序设计教程_学习笔记_第8章
链接地址:https://www.777doc.com/doc-2077203 .html