c语言 第8章 善于利用指针
c语言-C程序设计(第四版)谭浩强_课后习题答案第8章
C程序设计(第四版)谭浩强_课后习题答案第8章第8章善于利用指针2208.1指针是什么2208.2指针变量2228.2.1使用指针变量的例子2228.2.2怎样定义指针变量2238.2.3怎样引用指针变量2248.2.4指针变量作为函数参数2268.3通过指针引用数组2308.3.1数组元素的指针2308.3.2在引用数组元素时指针的运算2318.3.3通过指针引用数组元素2338.3.4用数组名作函数参数2378.3.5通过指针引用多维数组2458.4通过指针引用字符串2558.4.1字符串的引用方式2558.4.2字符指针作函数参数2598.4.3使用字符指针变量和字符数组的比较2638.5指向函数的指针2668.5.1什么是函数指针2668.5.2用函数指针变量调用函数2668.5.3怎样定义和使用指向函数的指针变量2688.5.4用指向函数的指针作函数参数2708.6返回指针值的函数2748.7指针数组和多重指针2778.7.1什么是指针数组2778.7.2指向指针数据的指针2808.7.3指针数组作main函数的形参2828.8动态内存分配与指向它的指针变量2858.8.1什么是内存的动态分配2858.8.2怎样建立内存的动态分配2858.8.3void指针类型2878.9有关指针的小结288习题2918-1#include <stdio.h>int main(){ void swap(int *p1,int *p2);int n1,n2,n3;int *p1,*p2,*p3;printf("input three integer n1,n2,n3:");scanf("%d,%d,%d",&n1,&n2,&n3);p1=&n1;p2=&n2;p3=&n3;if(n1>n2) swap(p1,p2);if(n1>n3) swap(p1,p3);if(n2>n3) swap(p2,p3);printf("Now,the order is:%d,%d,%d\n",n1,n2,n3); return 0;}void swap(int *p1,int *p2){int p;p=*p1; *p1=*p2; *p2=p;}#include <stdio.h>#include <string.h>int main(){void swap(char *,char *);char str1[20],str2[20],str3[20];printf("input three line:\n");gets(str1);gets(str2);gets(str3);if(strcmp(str1,str2)>0) swap(str1,str2);if(strcmp(str1,str3)>0) swap(str1,str3);if(strcmp(str2,str3)>0) swap(str2,str3);printf("Now,the order is:\n");printf("%s\n%s\n%s\n",str1,str2,str3);return 0;}void swap(char *p1,char *p2){char p[20];strcpy(p,p1);strcpy(p1,p2);strcpy(p2,p);}8-3#include <stdio.h>int main(){ void input(int *);void max_min_value(int *);void output(int *);int number[10];input(number);max_min_value(number);output(number);return 0;}void input(int *number){int i;printf("input 10 numbers:");for (i=0;i<10;i++)scanf("%d",&number[i]);}void max_min_value(int *number){ int *max,*min,*p,temp;max=min=number;for (p=number+1;p<number+10;p++)if (*p>*max) max=p;else if (*p<*min) min=p;temp=number[0];number[0]=*min;*min=temp;if(max==number) max=min;temp=number[9];number[9]=*max;*max=temp; }void output(int *number){int *p;printf("Now,they are: ");for (p=number;p<number+10;p++)printf("%d ",*p);printf("\n");}8-4#include <stdio.h>int main(){void move(int [20],int,int);int number[20],n,m,i;printf("how many numbers?");scanf("%d",&n);printf("input %d numbers:\n",n);for (i=0;i<n;i++)scanf("%d",&number[i]);printf("how many place you want move?"); scanf("%d",&m);move(number,n,m);printf("Now,they are:\n");for (i=0;i<n;i++)printf("%d ",number[i]);printf("\n");return 0;}void move(int array[20],int n,int m){int *p,array_end;array_end=*(array+n-1);for (p=array+n-1;p>array;p--)*p=*(p-1);*array=array_end;m--;if (m>0) move(array,n,m);}8-5#include <stdio.h>int main(){int i,k,m,n,num[50],*p;printf("\ninput number of person: n="); scanf("%d",&n);p=num;for (i=0;i<n;i++)*(p+i)=i+1;i=0;k=0;m=0;while (m<n-1){if (*(p+i)!=0) k++;if (k==3){*(p+i)=0;k=0;m++;}i++;if (i==n) i=0;}while(*p==0) p++;printf("The last one is NO.%d\n",*p); return 0;}8-6#include <stdio.h>int main(){int length(char *p);int len;char str[20];printf("input string: ");scanf("%s",str);len=length(str);printf("The length of string is %d.\n",len); return 0;}int length(char *p){int n;n=0;while (*p!='\0'){n++;p++;}return(n);}8-7#include <stdio.h>#include <string.h>int main(){void copystr(char *,char *,int);int m;char str1[20],str2[20];printf("input string:");gets(str1);printf("which character that begin to copy?"); scanf("%d",&m);if (strlen(str1)<m)printf("input error!");else{copystr(str1,str2,m);printf("result:%s\n",str2);}return 0;}void copystr(char *p1,char *p2,int m){int n;n=0;while (n<m-1){n++;p1++;}while (*p1!='\0'){*p2=*p1;p1++;p2++;}*p2='\0';}8-8#include <stdio.h>int main(){int upper=0,lower=0,digit=0,space=0,other=0,i=0; char *p,s[20];printf("input string: ");while ((s[i]=getchar())!='\n') i++;p=&s[0];while (*p!='\n'){if (('A'<=*p) && (*p<='Z'))++upper;else if (('a'<=*p) && (*p<='z'))++lower;else if (*p==' ')++space;else if ((*p<='9') && (*p>='0'))++digit;else++other;p++;}printf("upper case:%d lower case:%d",upper,lower);printf(" space:%d digit:%d other:%d\n",space,digit,other); return 0;}8-9#include <stdio.h>int main(){void move(int *pointer);int a[3][3],*p,i;printf("input matrix:\n");for (i=0;i<3;i++)scanf("%d %d %d",&a[i][0],&a[i][1],&a[i][2]);p=&a[0][0];move(p);printf("Now,matrix:\n");for (i=0;i<3;i++)printf("%d %d %d\n",a[i][0],a[i][1],a[i][2]);return 0;}void move(int *pointer){int i,j,t;for (i=0;i<3;i++)for (j=i;j<3;j++){t=*(pointer+3*i+j);*(pointer+3*i+j)=*(pointer+3*j+i);*(pointer+3*j+i)=t;}}8-10-1#include <stdio.h>int main(){void change(int *p);int a[5][5],*p,i,j;printf("input matrix:\n");for (i=0;i<5;i++)for (j=0;j<5;j++)scanf("%d",&a[i][j]);p=&a[0][0];change(p);printf("Now,matrix:\n");for (i=0;i<5;i++){for (j=0;j<5;j++)printf("%d ",a[i][j]);printf("\n");}return 0;}void change(int *p){int i,j,temp;int *pmax,*pmin;pmax=p;pmin=p;for (i=0;i<5;i++)for (j=i;j<5;j++){if (*pmax<*(p+5*i+j)) pmax=p+5*i+j;if (*pmin>*(p+5*i+j)) pmin=p+5*i+j;}temp=*(p+12);*(p+12)=*pmax;*pmax=temp;temp=*p;*p=*pmin;*pmin=temp;pmin=p+1;for (i=0;i<5;i++)for (j=0;j<5;j++)if (((p+5*i+j)!=p) && (*pmin>*(p+5*i+j))) pmin=p+5*i+j;temp=*pmin;*pmin=*(p+4);*(p+4)=temp;pmin=p+1;for (i=0;i<5;i++)for (j=0;j<5;j++)if (((p+5*i+j)!=(p+4))&&((p+5*i+j)!=p)&&(*pmin>*(p+5*i+j)))pmin=p+5*i+j;temp=*pmin;*pmin=*(p+20);*(p+20)=temp;pmin=p+1;for (i=0;i<5;i++)for (j=0;j<5;j++)if (((p+5*i+j)!=p) && ((p+5*i+j)!=(p+4)) && ((p+5*i+j)!=(p+20)) && (*pmin>*(p+5*i+j)))pmin=p+5*i+j;temp=*pmin;*pmin=*(p+24);*(p+24)=temp;}8-10-2#include <stdio.h>int main(){void change(int *p);int a[5][5],*p,i,j;printf("input matrix:\n");for (i=0;i<5;i++)for (j=0;j<5;j++)scanf("%d",&a[i][j]);p=&a[0][0];change(p);printf("Now,matrix:\n");for (i=0;i<5;i++){for (j=0;j<5;j++)printf("%d ",a[i][j]);printf("\n");}return 0;}void change(int *p) //交换函数{int i,j,temp;int *pmax,*pmin;pmax=p;pmin=p;for (i=0;i<5;i++) //找最大值和最小值的地址,并赋给pmax,pmin for (j=i;j<5;j++){if (*pmax<*(p+5*i+j)) pmax=p+5*i+j;if (*pmin>*(p+5*i+j)) pmin=p+5*i+j;}temp=*(p+12); //将最大值与中心元素互换*(p+12)=*pmax;*pmax=temp;temp=*p; //将最小值与左上角元素互换*p=*pmin;*pmin=temp;pmin=p+1;//将a[0][1]的地址赋给pmin,从该位置开始找最小的元素for (i=0;i<5;i++) //找第二最小值的地址赋给pminfor (j=0;j<5;j++){if(i==0 && j==0) continue;if (*pmin > *(p+5*i+j)) pmin=p+5*i+j;}temp=*pmin; //将第二最小值与右上角元素互换*pmin=*(p+4);*(p+4)=temp;pmin=p+1;for (i=0;i<5;i++) //找第三最小值的地址赋给pminfor (j=0;j<5;j++){if((i==0 && j==0) ||(i==0 && j==4)) continue;if(*pmin>*(p+5*i+j)) pmin=p+5*i+j;}temp=*pmin; // 将第三最小值与左下角元素互换*pmin=*(p+20);*(p+20)=temp;pmin=p+1;for (i=0;i<5;i++) // 找第四最小值的地址赋给pminfor (j=0;j<5;j++){if ((i==0 && j==0) ||(i==0 && j==4)||(i==4 && j==0)) continue;if (*pmin>*(p+5*i+j)) pmin=p+5*i+j;}temp=*pmin; //将第四最小值与右下角元素互换*pmin=*(p+24);*(p+24)=temp;}8-11-1#include <stdio.h>#include <string.h>int main(){void sort(char s[][6]);int i;char str[10][6];printf("input 10 strings:\n");for (i=0;i<10;i++)scanf("%s",str[i]);sort(str);printf("Now,the sequence is:\n"); for (i=0;i<10;i++)printf("%s\n",str[i]);return 0;}void sort(char s[10][6]){int i,j;char *p,temp[10];p=temp;for (i=0;i<9;i++)for (j=0;j<9-i;j++)if (strcmp(s[j],s[j+1])>0){strcpy(p,s[j]);strcpy(s[j],s[+j+1]);strcpy(s[j+1],p);}}8-11-2#include <stdio.h>#include <string.h>int main(){void sort(char (*p)[6]);int i;char str[10][6];char (*p)[6];printf("input 10 strings:\n");for (i=0;i<10;i++)scanf("%s",str[i]);p=str;sort(p);printf("Now,the sequence is:\n"); for (i=0;i<10;i++)printf("%s\n",str[i]);return 0;}void sort(char (*s)[6]){int i,j;char temp[6],*t=temp;for (i=0;i<9;i++)for (j=0;j<9-i;j++)if (strcmp(s[j],s[j+1])>0){strcpy(t,s[j]);strcpy(s[j],s[+j+1]);strcpy(s[j+1],t);}}8-12#include <stdio.h>#include <string.h>int main(){void sort(char *[]);int i;char *p[10],str[10][20];for (i=0;i<10;i++)p[i]=str[i];printf("input 10 strings:\n");for (i=0;i<10;i++)scanf("%s",p[i]);sort(p);printf("Now,the sequence is:\n"); for (i=0;i<10;i++)printf("%s\n",p[i]);return 0;}void sort(char *s[]){int i,j;char *temp;for (i=0;i<9;i++)for (j=0;j<9-i;j++)if (strcmp(*(s+j),*(s+j+1))>0){temp=*(s+j);*(s+j)=*(s+j+1);*(s+j+1)=temp;}}8-13#include<stdio.h>#include<math.h>int main(){float integral(float(*)(float),float,float,int);//对integarl函数的声明float fsin(float); //对fsin函数的声明float fcos(float); //对fcos函数的声明float fexp(float); //对fexp函数的声明float a1,b1,a2,b2,a3,b3,c,(*p)(float);int n=20;printf("input a1,b1:");scanf("%f,%f",&a1,&b1);printf("input a2,b2:");scanf("%f,%f",&a2,&b2);printf("input a3,b3:");scanf("%f,%f",&a3,&b3);p=fsin;c=integral(p,a1,b1,n);printf("The integral of sin(x) is:%f\n",c);p=fcos;c=integral(p,a2,b2,n);printf("The integral of cos(x) is:%f\n",c);p=fexp;c=integral(p,a3,b3,n);printf("The integral of exp(x) is:%f\n",c);return 0;}float integral(float(*p)(float),float a,float b,int n){int i;float x,h,s;h=(b-a)/n;x=a;s=0;for(i=1;i<=n;i++){x=x+h;s=s+(*p)(x)*h;}return(s);}float fsin(float x){return sin(x);}float fcos(float x){return cos(x);}float fexp(float x){return exp(x);}8-14#include <stdio.h>int main(){void sort (char *p,int m);int i,n;char *p,num[20];printf("input n:");scanf("%d",&n);printf("please input these numbers:\n");for (i=0;i<n;i++)scanf("%d",&num[i]);p=&num[0];sort(p,n);printf("Now,the sequence is:\n");for (i=0;i<n;i++)printf("%d ",num[i]);printf("\n");return 0;}void sort (char *p,int m) // 将n个数逆序排列函数{int i;char temp, *p1,*p2;for (i=0;i<m/2;i++){p1=p+i;p2=p+(m-1-i);temp=*p1;*p1=*p2;*p2=temp;}}8-15#include <stdio.h>int main(){void avsco(float *,float *);void avcour1(char (*)[10],float *);void fali2(char course[5][10],int num[],float *pscore,float aver[4]); void good(char course[5][10],int num[4],float *pscore,float aver[4]); int i,j,*pnum,num[4];float score[4][5],aver[4],*pscore,*paver;char course[5][10],(*pcourse)[10];printf("input course:\n");pcourse=course;for (i=0;i<5;i++)scanf("%s",course[i]);printf("input NO. and scores:\n");printf("NO.");for (i=0;i<5;i++)printf(",%s",course[i]);printf("\n");pscore=&score[0][0];pnum=&num[0];for (i=0;i<4;i++){scanf("%d",pnum+i);for (j=0;j<5;j++)scanf("%f",pscore+5*i+j);}paver=&aver[0];printf("\n\n");avsco(pscore,paver); // 求出每个学生的平均成绩avcour1(pcourse,pscore); // 求出第一门课的平均成绩printf("\n\n");fali2(pcourse,pnum,pscore,paver); // 找出2门课不及格的学生printf("\n\n");good(pcourse,pnum,pscore,paver); // 找出成绩好的学生return 0;}void avsco(float *pscore,float *paver) // 求每个学生的平均成绩的函数{int i,j;float sum,average;for (i=0;i<4;i++){sum=0.0;for (j=0;j<5;j++)sum=sum+(*(pscore+5*i+j)); //累计每个学生的各科成绩average=sum/5; //计算平均成绩*(paver+i)=average;}}void avcour1(char (*pcourse)[10],float *pscore) // 求第一课程的平均成绩的函数{int i;float sum,average1;sum=0.0;for (i=0;i<4;i++)sum=sum+(*(pscore+5*i)); //累计每个学生的得分average1=sum/4; //计算平均成绩printf("course 1:%s average score:%7.2f\n",*pcourse,average1);}void fali2(char course[5][10],int num[],float *pscore,float aver[4])// 找两门以上课程不及格的学生的函数{int i,j,k,labe1;printf(" ==========Student who is fail in two courses======= \n"); printf("NO. ");for (i=0;i<5;i++)printf("%11s",course[i]);printf(" average\n");for (i=0;i<4;i++){labe1=0;for (j=0;j<5;j++)if (*(pscore+5*i+j)<60.0) labe1++;if (labe1>=2){printf("%d",num[i]);for (k=0;k<5;k++)printf("%11.2f",*(pscore+5*i+k));printf("%11.2f\n",aver[i]);}}}void good(char course[5][10],int num[4],float *pscore,float aver[4]) // 找成绩优秀学生(各门85以上或平均90分以上)的函数{int i,j,k,n;printf(" ======Students whose score is good======\n");printf("NO. ");for (i=0;i<5;i++)printf("%11s",course[i]);printf(" average\n");for (i=0;i<4;i++){n=0;for (j=0;j<5;j++)if (*(pscore+5*i+j)>85.0) n++;if ((n==5)||(aver[i]>=90)){printf("%d",num[i]);for (k=0;k<5;k++)printf("%11.2f",*(pscore+5*i+k));printf("%11.2f\n",aver[i]);}}}8-16#include <stdio.h>int main(){char str[50],*pstr;int i,j,k,m,e10,digit,ndigit,a[10],*pa;printf("input a string:\n");gets(str);pstr=&str[0]; /*字符指针pstr置于数组str 首地址*/pa=&a[0]; /*指针pa置于a数组首地址*/ndigit=0; /*ndigit代表有多少个整数*/i=0; /*代表字符串中的第几个字符*/j=0;while(*(pstr+i)!='\0'){if((*(pstr+i)>='0') && (*(pstr+i)<='9'))j++;else{if (j>0){digit=*(pstr+i-1)-48; /*将个数位赋予digit*/k=1;while (k<j) /*将含有两位以上数的其它位的数值累计于digit*/{e10=1;for (m=1;m<=k;m++)e10=e10*10; /*e10代表该位数所应乘的因子*/digit=digit+(*(pstr+i-1-k)-48)*e10; /*将该位数的数值\累加于digit*/k++; /*位数K自增*/}*pa=digit; /*将数值赋予数组a*/ndigit++;pa++; /*指针pa指向a数组下一元素*/j=0;}}i++;}if (j>0) /*以数字结尾字符串的最后一个数据*/ {digit=*(pstr+i-1)-48; /*将个数位赋予digit*/k=1;while (k<j) /* 将含有两位以上数的其它位的数值累加于digit*/{e10=1;for (m=1;m<=k;m++)e10=e10*10; /*e10代表位数所应乘的因子*/digit=digit+(*(pstr+i-1-k)-48)*e10; /*将该位数的数值累加于digit*/k++; /*位数K自增*/}*pa=digit; /*将数值赋予数组a*/ndigit++;j=0;}printf("There are %d numbers in this line, they are:\n",ndigit);j=0;pa=&a[0];for (j=0;j<ndigit;j++) /*打印数据*/printf("%d ",*(pa+j));printf("\n");return 0;}8-17#include<stdio.h>int main(){int strcmp(char *p1,char *p2);int m;char str1[20],str2[20],*p1,*p2;printf("input two strings:\n");scanf("%s",str1);scanf("%s",str2);p1=&str1[0];p2=&str2[0];m=strcmp(p1,p2);printf("result:%d,\n",m);return 0;}int strcmp(char *p1,char *p2) //两个字符串比较函数{int i;i=0;while(*(p1+i)==*(p2+i))if (*(p1+i++)=='\0') return(0); //相等时返回结果0return(*(p1+i)-*(p2+i)); //不等时返回结果为第一个不等字符ASCII码的差值}8-18#include <stdio.h>int main(){char *month_name[13]={"illegal month","January","February","March","April", "May","June","july","August","September","October", "November","December"};int n;printf("input month:\n");scanf("%d",&n);if ((n<=12) && (n>=1))printf("It is %s.\n",*(month_name+n));elseprintf("It is wrong.\n");return 0;}8-19-1#include <stdio.h>#define NEWSIZE 1000 //指定开辟存区的最大容量char newbuf[NEWSIZE]; //定义字符数组newbufchar *newp=newbuf; //定义指针变量newp,指向可存区的始端char *new(int n) //定义开辟存区的函数new,开辟存储区后返回指针{if (newp+n<=newbuf+NEWSIZE) // 开辟区未超过newbuf数组的大小{newp+=n; // newp指向存储区的末尾return(newp-n); // 返回一个指针,它指向存区的开始位置}elsereturn(NULL); // 当存区不够分配时,返回一个空指针}8-19-2#include <stdio.h>#define NEWSIZE 1000char newbuf[NEWSIZE];char *newp=newbuf;void free(char *p) //释放存区函数{if (p>=newbuf && p< newbuf + NEWSIZE)newp=p;}8-20#define LINEMAX 20 /*定义字符串的最大长度*/int main(){int i;char **p,*pstr[5],str[5][LINEMAX];for (i=0;i<5;i++)pstr[i]=str[i]; /*将第i个字符串的首地址赋予指针数组pstr 的第i个元素*/ printf("input 5 strings:\n");for (i=0;i<5;i++)scanf("%s",pstr[i]);p=pstr;sort(p);printf("strings sorted:\n");for (i=0;i<5;i++)printf("%s\n",pstr[i]);}sort(char **p) /*冒泡法对5个字符串排序函数*/{int i,j;char *temp;for (i=0;i<5;i++){for (j=i+1;j<5;j++){if (strcmp(*(p+i),*(p+j))>0) /*比较后交换字符串地址*/{temp=*(p+i);*(p+i)=*(p+j);*(p+j)=temp;}}}return 0;}8-21#include<stdio.h>int main(){void sort(int **p,int n);int i,n,data[20],**p,*pstr[20];printf("input n:\n");scanf("%d",&n);for (i=0;i<n;i++)pstr[i]=&data[i]; //将第i个整数的地址赋予指针数组pstr 的第i个元素printf("input %d integer numbers:",n);for (i=0;i<n;i++)scanf("%d",pstr[i]);p=pstr;sort(p,n);printf("Now,the sequence is:\n");for (i=0;i<n;i++)printf("%d ",*pstr[i]);printf("\n");return 0;}void sort(int **p,int n){int i,j,*temp;for (i=0;i<n-1;i++){for (j=i+1;j<n;j++){if (**(p+i)>**(p+j)) //比较后交换整数地址{temp=*(p+i);*(p+i)=*(p+j);*(p+j)=temp;}}}}。
善于利用指针 PPT课件
50
*i_pointer=50;
将i的地址 存到这里
间接存取
i
直接存取
2000
3
间接存取
i_pointer
2000
*i_pointer
3 2000
为了表示将数值3送到变量中,可以有两 种表达方法: (1) 将3直接送到变量i所标识的单元中,例 如:i=3; (2) 将3送到变量i_pointer所指向的单元 (即变量i的存储单元),例如: *i_pointer=3; 其中*i_pointer表示 i_pointer指向的对象
8.1 指针是什么
内存区的每一个字节有一个编号,这就是 “地址”,它相当于旅馆中的房间号。 在地址所标识的内存单元中存放数据,这相 当于旅馆房间中居住的旅客一样。 由于通过地址能找到所需的变量单元,我们 可以说,地址指向该变量单元。 将地址形象化地称为“指针”
务必弄清楚存储单元的地址和存储 单元的内容这两个概念的区别 例如:
指向就是通过地址来体现的
假设i_pointer中的值是变量i的地址 (2000),这样就在i_pointer和变量i之间 建立起一种联系,即通过i_pointer能知道i 的地址,从而找到变量i的内存单元
由于通过地址能找到所需的变量单元,因 此说,地址指向该变量单元
将地址形象化地称为“指针”。意思是通 过它能找到以它为地址的内存单元
#include <stdio.h> 此处*与类型名在一起。 此时共同定义指针变量 int main() { int a=100,b=10; int *pointer_1, *pointer_2; pointer_1=&a; pointer_2=&b; printf(“a=%d,b=%d\n”,a,b); printf(“*pointer_1=%d,*pointer_2= %d\n”,*pointer_1,*pointer_2); return 0; 此处*与指针变量一起使用。此 } 时代表指针变量所指向的变量
C程序设计第四版课件第8章善于利用指针
通过指针访问数组元素
使用指针访问数组元素
01
通过指针可以访问数组中的元素,即通过解引用指针来获取元
素的值。
指针的算术运算
02
可以通过对指针进行算术运算来访问数组中的相邻元素。
指向元素的指针变量
03
可以定义一个指向数组中某个元素的指针变量,通过该变量可
以访问该元素。
指针与字符串
1 2
字符串常量的指针
通过二级指针,可以方便地操 作二维数组和多维数组,实现 更加灵活的数据处理。
THANKS
感谢观看
指针的声明与初始化
声明指针变量时,需要在变量名前加 上星号(*)。
未初始化的指针变量可能指向任何位 置,因此使用前应确保指针已被正确 初始化。
初始化指针变量时,需要将其设置为 某个变量的地址。
指针的赋值与运算
可以将一个变量的地址赋值给指 针变量。
可以对指针进行加法或减法运算 ,以改变指针所指向的内存地址
指针数组可以用来存储多个变量 的地址,通过数组索引访问不同 的地址,实现动态内存分配和字
符串处理等功能。
例如,char *arr[10] 表示一个包 含10个字符指针的数组,每个指
针可以指向一个字符串。
二级指针
二级指针是指向指针的指针, 用于间接地访问和修改变量的 值。
二级指针在处理动态内存分配 、函数参数传递和多维数组等 场景中非常有用。
05
指针的高级应用
指向指针的指针
指向指针的指针是指一个指针变量,它存储的是另一个指针变量的地址,而不是变 量的值。
通过指向指针的指针,可以间接地访问和修改变量的值,增加了对内存地址操作的 灵活性。
指向指针的指针在处理动态内存分配、函数参数传递和多维数组等场景中非常有用 。
08_01_C语言程序设计_第八章 善于利用指针_周常欣
--:指针向低地址方向移动一个数据存储单元
注意:数据类型不同,指针增1和减1运算所引起的 地址变化量是不同的,指向的新地址为: 原地址 sizeof(类型说明符)
C
程 序 设 计 |
第 八 章
第八章 善于利用指针
(2)如p的初值是&a[0],则p+i和a+i就是数组元素a[i] 的地址,或者说,它们指向a数组序号为i的元素
C
程 序 设 计 |
第 八 章
第八章 善于利用指针
8.3.3 通过指针引用数组元素 引用一个数组元素,可以用两种方法: (1)下标法,如a[i]形式 (2)指针法,如*(a+i)或*(p+i)形式 其中a间数组名,p是指向数组元素的指针变量,其初始 值p=a (3)下标法示例 下 标 法
#include <stdio.h> int main() { int i; int a[10]={1,3,5,7,9,11,13,15,17,19}; for(i=0;i<10;i++) printf("%d\n",a[i]); return 0; }
C
程 序 设 计 |
第 八 章
第八章 善于利用指针
8.2 指针变量
8.2.1 使用指针变量的例子
#include<stdio.h> int main() { int a=100,b=10; //定义整型变量a,b,并初始化 int * pointer_1,* pointer_2; // 定义指向整型数据的两个指针 pointer_1=&a; //把变量a的地址赋给指针变量pointer_1 pointer_2=&b; //把变量b的地址赋给指针变量pointer_2 printf(“a=%d,b=%d\n”,a,b); //输出a和b的值 printf(“*pointer_1=%d,pointer_2=%d\n”,* pointer_1,* pointer_2); //输出两指针 return 0; //指定函数返回值为0 }
《C语言第八章》PPT课件
精选PPT
7
8.2 指针变量
8.2.3 指针变量的引用
– 变量的数据访问形式
普通变量:变量名—变量存储的数据 指针变量:*变量名—指向存储单元存储的数据
– 定义时:*p表示为指针;使用时*p表示指针指向的数据
– 变量的地址访问形式
普通变量:&变量名—存储数据的首地址 指针变量:变量名—指向的存储单元
精选PPT
9
8.2 指针变量
8.2.3 指针变量的引用
– 指针和变量的几个换算关系:
对于变量,有:名称=数据、&名称=地址 对于指针,有:名称=地址、*名称=指向的数据ຫໍສະໝຸດ 若有定义:int a, *p 则:
– &a、p 是同一类型数据,为地址 –a、*p 是同一类型数据,为整型数据
一般情况下,使用p=&a的形式,让指针与变量关联, 使用*p的形式,访问指向的数据
– 指针变量:
存放指针的变量,称之为指针变量
– 指针变量里面存放的是指针,也就是地址
– 为什么使用指针
更方便、更主动的操作数据、构建数据结构
精选PPT
2
8.1 什么是指针
学习指针的几点建议
– 弄明白存放在内存中的数据是如何访问的
这是学习指针的基础
– 清晰的记住指针和变量的几个关系:
指针的内容,指针指向的内容等等
– 一般情况下,不要将地址值直接赋给指针变量
精选PPT
8
8.2 指针变量
8.2.3 指针变量的引用
– 一般情况下,不能将地址值直接赋给变量
若有 int a,*p; 则:&a=1000
p=2000是错误的
– 指针不会单独使用,常和其他普通变量关联在 一起使用
C语言 第8章 善于利用指针
第8章善于利用指针指針是什么⏹如果在程序中定义了一个变量,在对程序进行编译时,系统就会给该变量分配内存单元⏹内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号。
⏹在地址所标识的内存单元中存放数据,这相当于旅馆房间中居住的旅客一样。
⏹由于通过地址能找到所需的变量单元,我们可以说,地址指向该变量单元。
⏹将地址形象化地称为“指针”⏹务必弄清楚存储单元的地址和存储单元的内容这两个概念的区别指针变量2怎样定义指针变量⏹定义指针变量的一般形式为:类型*指针变量名;如:i n t*p o i n t e r_1,*p o i n t e r_2;•i n t是为指针变量指定的“基类型”•基类型指定指针变量可指向的变量类型•如p o i n t e r_1可以指向整型变量,但不能指向浮点型变量2怎样定义指针变量⏹下面都是合法的定义和初始化:f l o a t*p o i n t e r_3;c h a r*p o i n t e r_4;i n t a,b;i n t*p o i n t e r_1=&a,*p o i n t e r_2=&b;3怎样引用指针变量⏹在引用指针变量时,可能有三种情况:•给指针变量赋值。
如:p=&a;•引用指针变量指向的变量。
如有p=&a;*p=1;则执行p r i n t f(“%d”,*p);将输出1•引用指针变量的值。
如:p r i n t f(“%o”,p);3怎样引用指针变量⏹要熟练掌握两个有关的运算符:(1)&取地址运算符。
&a是变量a的地址(2)*指针运算符(“间接访问”运算符)如果:p指向变量a,则*p就代表a。
k=*p;(把a的值赋给k)*p=1;(把1赋给a)4指针变量作为函数参数通过指针引用数组1数组元素的指针⏹所谓数组元素的指针就是数组元素的地址⏹可以用一个指针变量指向一个数组元素i n t a[10]={1,3,5,7,9,11,13,15,17,19};i n t*p;p=&a[0];⏹在指针指向数组元素时,允许以下运算:•加一个整数(用+或+=),如p+1•减一个整数(用-或-=),如p-1•自加运算,如p++,++p•自减运算,如p--,--p•两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义)3通过指针引用数组元素⏹引用一个数组元素,可用下面两种方法:(1)下标法,如a[i]形式(2)指针法,如*(a+i)或*(p+i)其中a是数组名,p是指向数组元素的指针变量,其初值p=a 4用数组名作函数参数⏹用数组名作函数参数时,因为实参数组名代表该数组首元素的地址,形参应该是一个指针变量⏹C编译都是将形参数组名作为指针变量来处理的通过指针引用字符串1字符串的引用方式⏹字符串是存放在字符数组中的。
善于利用指针
他变量地址的变量称为指针变量。
内存单元的地址与内存单元的内容是有区别 :假设程序中已定义了2个整型变量i、j, 即 int i , j; 则编译时系统将 2000和2003这四个 字节的内存空间 分配给给变量i; 2004~2007这4个字
内存地址 内存单元内容 变量名
2000 2001 2002 2003 2004 2005 2006 2007
#include <stdio.h> 此处*与类型名在一起。此 int main() 时共同定义指针变量 { int a=100,b=10; int *pointer_1 , *pointer_2; pointer_1=&a; pointer_2=&b; printf(“a=%d,b=%d\n”,a,b); printf(“*pointer_1=%d,*pointer_2= %d\n”, *pointer_1, *pointer_2); return 0; 此处*与指针变量一起使 用。此时代表指针变量所 }
内存地址 内存单元内容 变量名 2000 00 i 00 2001 00 2002
2003 2004 2005 2006 2007 2008 2009 2010 2011
03 00 00 00 06 00 00 00 09 内存单元和地址
j
k
这种直接按变量名存取变量值的方式称 为‚直接访问‛方式 。
指针变量,分别指向这两个整型变量,通过
访问指针变量,可以找到它们所指向的变量 ,从而得到这些变量的值。
#include <stdio.h> int main() { int a=100,b=10; 定义两个指针变量 int *pointer_1, *pointer_2; 使pointer_1指向a pointer_1=&a; 使pointer_2指向b 直接输出变量a和b的值 pointer_2=&b; printf(“a=%d,b=%d\n”,a,b); 间接输出变 printf(“*pointer_1=%d,*pointer_2= 量a和b的值 %d\n”,*pointer_1,*pointer_2); return 0; }
C语言程序设计第8章指针简明教程PPT课件
d
图:变量内存分配示意图
c第8章 指 针
8.2.2 指针变量的引用
有两个有关的运算符: (1) &:取地址运算符。 (2) *:指针运算符(或称“间接访问”运算符)。 例如:&a为变量a的地址,*p为指针变量p所指向的变量。 【例8.1】指针变量的引用。 main() { int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1=&a; /*把变量a的地址赋给pointer_1*/ pointer_2=&b; /*把变量b的地址赋给pointer_2*/ printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1,*pointer_2); } 运行结果为: 100,10 100,10
8.3.2 指针的关系运算
运算规则是:当两个指针变量的值(地址值)满足关系运算时,结果为1(真) ;否则结果为0(假)。所以两个指针变量进行关系运算的结果也是逻辑值。 关系运算可以用于地址常量、指针变量、地址常量与指针变量及地址型表 达式之间的比较。例如,定义了数组a和同类型的指针变量px,py;使px指向数 组元素a[2];py指向数组元素a[3]。看下列的关系表达式及其运算结果: px<py 结果为1(真)。 px++==py 结果为0(假),注意++是后缀。 --py==px 结果为1(真),注意—是前缀。 px<&a[5] 结果为1(真),&a[5]地址是地址常量。 py>=px+2 结果为0(假),px+2是地址型表达式,代表a[4]的地址。 指针的运算应注意以下几点: 指针变量只能和整数或整型变量相加减,而不能和实型数或实型变量相加 减。如px+3.5是错误的.。 指针变量不能进行乘法和除法运算。如px*2或px/4都是错误的。 两个指针变量相减,必须指向同一个数组,否则不能进行减法运算。
善于利用指针
例
整型变量i
i = 3;
-----直接访问
2000 2001 2002 2003 2004
20 3 10
变量i_pointer
2000
2005
2006
指针变量
例 *i_pointer = 20;
-----间接访问
…...
2、指针变量与其所指向的变量之间的关系
i_pointer
2000 变量i 3 *i_pointer i &i i=3; *i_pointer i_pointer *i_pointer=3;
4、指针变量的赋值 初始化赋值
[存储类型] 基类型 *指针名 = 初始地址值;
例
赋给指针变量, int i; int *p = &i; 不是赋给目标变量
例
int i; *p = &i; int int *p = &i; int i; int *q = p;
变量必须已说明过 类型应一致
用已初始化指针变量作初值
(main) 2000 2002 2004
2006 2008
200A 200C 200E 2010
9 5 5 9 2000 2002
(swap)
2000 2002 5
...
…...
整型变量a 整型变量b 指针p_1
指针p_2
指针p1 指针p2
整型p
【例】将数从大到小输出
void swap(int *p1, int *p2) { int p; p = *p1; *p1 = *p2; 地址传 *p2 = p; 递 } void main ( ) { int a, b; int *p_1, *p_2; scanf ("%d,%d", &a, &b); p_1 = &a; p_2 = &b; if (a < b) swap (p_1, p_2); printf ("\n%d,%d\n", a, b); }
c语言程序设计第五版课后答案谭浩强第八章课后答案
c语⾔程序设计第五版课后答案谭浩强第⼋章课后答案c语⾔程序设计第五版课后答案谭浩强习题答案第⼋章善于利⽤指针本章习题均要求使⽤指针⽅法处理。
1. 输⼊3个整数,要求按由⼩到⼤的顺序输出。
解题思路:先获取到三个变量的地址,然后获取三个数据,通过指针进⾏⽐较转换即可答案:#include <stdio.h>void swap(int *p_a, int *p_b){int temp = *p_a;*p_a = *p_b;*p_b = temp;}int main(){int a, b, c, *p_a = &a, *p_b = &b, *p_c = &c; // 获取每个变量空间的地址printf("Please enter three numbers:");scanf_s("%d%d%d", p_a, p_b, p_c);if (*p_a > *p_b) {swap(p_a, p_b);//通过指针进⾏指向空间内的数据交换}if (*p_a > *p_c) {swap(p_a, p_c);}if (*p_b > *p_c) {swap(p_b, p_c);}printf("%d %d %d\n", *p_a, *p_b, *p_c);system("pause");return 0;}2. 输⼊3个字符串,要求按由⼩到⼤的顺序输出。
解题思路:字符串的⽐较可以使⽤strcmp函数,返回值>0表⽰⼤于,返回值⼩于0表⽰⼩于,返回追等于0表⽰相同。
其他的⽐较排序思路与数字的排序交换没有区别,逐个进⾏⽐较先找出最⼤的,然后找出第⼆⼤的。
答案:#include <stdio.h>int main(){char str[3][32];char *p[3];printf("Please enter three strings:");for (int i = 0; i < 3; i++) {p[i] = str[i];scanf_s("%s", p[i], 32);//后边的数字限制缓冲区边界,防⽌缓冲区溢出访问越界}//让p[0]和p[1]/p[2]分别进⾏⽐较,找出最⼤的字符串,i+1之后,则让p[1]和p[2]进⾏⽐较,找出第⼆⼤//i循环总个数-1次,最后⼀个是不需要⽐较的for (int i = 0; i < 2; i++) {for (int j = i + 1; j < 3; j++) {if (strcmp(p[i], p[j]) > 0) {char *tmp = p[i]; p[i] = p[j]; p[j] = tmp;}}}printf("%s %s %s\n", p[0], p[1], p[2]);system("pause");return 0;}3. 输⼊10个整数,将其中最⼩的数与第⼀个数对换, 把最⼤的数与最后⼀个数对换。
C语言程序设计第八章 指针的使用
第八章指针的使用【学习目标】本章将详细介绍在C语言中如何使用指针。
学习要点包括如下几点:(1)掌握指针和指针变量的概念,了解指针变量的特点以及直接访问数据和间接访问数据的原理。
(2)掌握指针变量的定义、赋值方法及指针运算符的使用,熟练运用指针访问简单变量。
(3)熟悉指针和一维数组的关系,掌握指向一维数组的指针变量的定义方法,熟练使用指针变量访问一维数组元素。
(4)了解指针与字符串的关系,能熟练使用指针处理字符串。
(5)熟练掌握用指针变量作函数的参数时函数的定义和调用方法、数组名作函数的参数用法。
(6)指向指针的指针的运用。
【学习导航】本章的在整个课程中的位置如图5-1所示。
图8-1 本章学习导航在本书的第一章介绍C语言有一个灵活性的特点,那么它的灵活性具体体现在哪里呢?其实就是指针。
指针是C语言的精华部分,通过利用指针,我们能很好地利用内存资源,使其发挥最大的效率。
有了指针技术,我们可以描述复杂的数据结构,对字符串的处理可以更灵活,对数组的处理更方便,使程序的书写简洁,高效。
8.1 地址和指针指针是C语言的一种数据类型,类似于整型、字符型等。
既然指针也是一种类型,那么也可以定义该类型的变量,称为指针变量。
指针变量和其他类型的变量的区别是:指针变量存储的是地址。
所以要学好指针,就一定要明白数据在内存中是如何存储的。
计算机所有数据都是存储在存储器里,系统的内存可看作编了号的小房间,如果要取房间的东西(读取数据)就需要得到房间编号。
地址就是内存区中对每个字节的编号。
下面通过两个整型变量来说明。
整型变量x、y(基本整型需4个字节)在内存中的存储如图8-2所示(假设内存编号是从2000开始)。
把变量所占用的存储单元首字节的地址作为变量的地址。
C语言中利用取地址运算符“&”获取变量的存储地址。
例如,&c将返回c的首地址;&x将返回x的首地址。
2000H2004H2008H2012H...图8-2 变量x和y在内存中的存储图8-2中2000H和2004H就是内存单元的地址。
谭浩强所著的《C程序设计》(第5版,清华大学出版社)善于利用指针【圣才出品】
表 8-1 以变量名和数组名作为函数参数的比较
5.通过指针引用多维数组 (1)多维数组元素的地址 如图 8-5 所示是一个多维数组元素地址示意图。其中 a 代表的是首行(即序号为 0 的行) 的首地址、a+1 与 a+2 分别为序号为 1 和 2 的行。
5 / 51
圣才电子书 十万种考研考证电子书、题库视频学习平台
图 8-3 指针变量指向数组元素 2.在引用数组元素时指针的运算
3 / 51
圣才电子书 十万种考研考证电子书、题库视频学习平台
当指针指向数组元素的时候,允许对指针进行加和减的运算。 (1)运算分类 ①加一个整数(用+或+=),如 p+1。 ②减一个整数(用-或-=),如 p-1。 ③自加运算,如 p++,++p。 ④自减运算,如 p--,--p。 ⑤两个指针相减,如 p1-p2(只有 p1 和 p2 都指向同一数组中的元素时才有意义)。 (2)详细说明 ①指针变量 p+1 或 p-1 是加上或减去一个数组元素所占用的字节数。 ②如果 p 的初值为&a[0],则 p+i 和 a+i 是指数组元素 a[i]的地址,如图 8-4 所示。
C语言 第8章 善于利用指针
错!!! 无确定的指向
{ int *temp; *temp=*p1; *p1=*p2; *p2=*temp; }
#include <stdio.h> 错!!! 无法交换a,b int main() {…… if (a<b) swap(a,b); printf(“max=%d,min=%d\n”,a,b); return 0; a } 5 void swap(int x,int y) { int temp; temp=x; x=y; y=temp; 5 9 }
&a &b &b &a p2
a 5 9 b
p1
p
#include <stdio.h> int main() { int *p1,*p2,*p,a,b; printf(“integer numbers:"); scanf(“%d,%d”,&a,&b); p1=&a; p2=&b; if(a<b) { p=p1; p1=p2; p2=p; } printf(“a=%d,b=%d\n”,a,b); printf(“%d,%d\n”,*p1,*p2); return 0; }
第8章 善于利用指针
8.1 指针是什么
8.2 指针变量 8.3 通过指针引用数组 8.4 通过指针引用字符串 8.5 指向函数的指针
8.6 返回指针值的函数
8.7 指针数组和多重指针
8.8 动态内存分配与指向它的指针变量
8.9 有关指针的小结
8.1 指针是什么
如果在程序中定义了一个变量,在对程序进行 编译时,系统就会给该变量分配内存单元 编译系统根据程序中定义的变量类型,分配一 定长度的空间
零基础入门学习C语言课件第八章_指针044
指向多维数组元素的指针变量
从前面的分析可得出*(p+i)+j是二维数组i行j 列 的元素的地址,而*(*(p+i)+j)则是i行j列元素的 值。
二维数组指针变量说明的一般形式为:
类型说明符 (*指针变量名)[长度]
其中“类型说明符”为所指数组的数据类型。 “*”表示其后的变量是指针类型。“长度” 表示二维数组分解为多个一维数组时,一维数 组的长度,也就是二维数组的列数。
void main() {
int a[10]; f (a, 10); } f (int *a, int n) { …… }
小小结
(3)实参形参都用指针变量。例如:
void main() {
int a[10], *p = a; f (a , 10);
} void f (int *x, int n) {
则有……
内存中数据存放图示
第一行地址 a[0]
存放数据
第二行地址 a[1]
存放数据
第三行地址 a[2]
存放数据
2000 a[0][0]
1
2016 a[1][0]
9
2032 a[2][0]
17
2004 a[0][1]
3
2020 a[1][1]
11
2036 a[2]1]
19
2008 a[0][2]
2016
a[1],*(a+1) 1行0列元素a[1][0]的地址 2016
a[1]+2, *(a+1)+2, &a[1][2]
1行2列元素a[1][2] 的地址 2024
*(a[1]+2), 1行2列元素a[1][2]的 *(*(a+1)+2), 值 a[1][2]
C语言指针详细讲解
两者关系:互为逆运算 理解
*i_pointer 10 i
10
i_pointer = &i = &(*i_pointer) i_pointer &i &(*i_pointer) i i = *i_pointer = *(&i) *i_pointer *(&i)
i_pointer-----指针变量,它的内容是地址量 *i_pointer----指针的目标变量,它的内容是数据 &i_pointer---指针变量占用内存的地址
(main) 2000 2002 2004 2006 2008 200A …... 变量a 变量b
5 9
} main() { int a,b; scanf("%d,%d",&a,&b); if(a<b) swap(a,b); printf("\n%d,%d\n",a,b); 运行结果:5, 9 }
…...
指针变量 变量地址(指针) 地址存入 指向 指针变量 变量 变量值 4
你现在所处的位置在:首页 C语言教学 幻灯片版 第八章 指针
&与*运算符
• 含义
含义: 取变量的地址 含义: 取指针所指向变量的内容 单目运算符 单目运算符 i_pointer 优先级: 2 优先级: 2 &i_pointer 2000 结合性:自右向左 结合性:自右向左 …... 2000 2001 2002 2003 2004 2005 2006 …... 2000 变量i_pointer 指针变量 整型变量i
你现在所处的位置在:首页 C语言教学 幻灯片版 第八章 指针
指针与指针变量 指针:一个变量的地址 指针变量:专门存放变量地址的变量叫~
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2000 2001 2002 2003
整型变量i
10
2004
指针变量p例2005206随机…...
12
零指针与空类型指针
p指向地址为0的单元, 系统保证该单元不作它用 零指针:(空指针) 定义:指针变量值为零 表示指针变量值没有意义
表示: int * p=0;
#define NULL 0 int *p=NULL:
6
指针变量
指针变量与其所指向的变量之间的关系: 指向 (用‘*’ 表示)
p
2000 &i
变量i 3 *p
i &i i=3;
*p p *p=3
指针变量的定义
一般形式: [存储类型] 数据类型 *指针名;
指针变量本身的存储类型
基类型
合法标识符
例
int *p1,*p2; 表示定义指针变量不是‘*’运算符 float *q ; static char *name;
a+9
a[9] *(a+9)
p+9
*(p+9) p[9]
下标法 指针法 数组元素 :a[i]、 p[i] 、*(p+i) 、*(a+i) 数组元素地址:&a[i]、&p[i]、 p+i 、 a+i 22
例 数组元素的引用方法(下标法、指针法)
main() { int a[5],*pa,i; for(i=0;i<5;i++) a[i]=i+1; pa=a; for(i=0;i<5;i++) printf("*(pa+%d):%d\n",i,*(pa+i)); for(i=0;i<5;i++) printf("*(a+%d):%d\n",i,*(a+i)); for(pa=a,i=0;i<5;i++) printf("pa[%d]:%d\n",i,pa[i]); for(i=0;i<5;i++) printf("a[%d]:%d\n",i,a[i]); }
p = &i = &(*p) i i = *p = *(&i) *p *(&i)
2003 2004
2005 2006 …... 变量p
2000
指针变量 p-----指针变量,它的内容是地址量 *p----指针的目标变量,它的内容是数据 &p---指针变量占用内存的地址
10
指针变量的初始化
一般形式:[存储类型] 数据类型 *指针名=初始地址值; 例 int i; int *p=&i; 赋给指针变量, 不是赋给目标变量 变量必须已说明过 类型应一致
7
注意:
1、int *p1, *p2; 与 int *p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值
变量的指针与指向变量的指针变量的区别:
◆ ◆
变量的指针:即该变量地址。 指向变量的指针变量:存放着变量地址的变量(即指
第8章 善于利用指针
本章重点: 1、指针的概念; 2、变量的、数组的、函数的、字符串的指针; 3、指针数组。 本章难点:数组的指针。
1
§8.1 地址和指针的概念
地址与指针:
a p 指针变量名:p &a 指针变量值:&a 指针变量的地址: &p
int a=5;
变量名:a
变量值:5 5
int *p;
p P++ a[0] a[1] a[2]
1
a[3] 1 a[4] a[5]
a[6]
a[7] a[8] a[9]
20
指针变量的关系运算
若p1和p2指向同一数组,则 p1<p2 表示p1指的元素在前 p1>p2 表示p1指的元素在后 p1==p2 表示p1与p2指向同一元素 若p1与p2不指向同一数组,比较无意义 p==NULL或p!=NULL
p=&a;
变量的地址:&a
这样,a和地址变量p就建立了联系。对于a变量, 就可以通过指针p去间接的访问。有如下关系:
a &a a=3; *p p *p=3 2
变量与地址
内存中每个字节有一个编号-----地址 内存 0
程序中: int i;
float k;
编译或函数调用时为其分配内存单元
…...
2000 2001 2002 2003
i k
2005
…...
变量是对程序中数据 存储空间的抽象 3
直接访问与间接访问
直接访问:按变量名直接访问存储单元存取变量值 间接访问:通过存放变量地址的变量去访问变量 例 int i=10; i=3; -----直接访问 整型变量i
…...
2000 2001
2002 2003 2004 2005 2006 2000 3 10 20
9
&与*运算符
含义
int i=10;
含义: 取指针所指向变量的内容 int *p=&i; *p 含义: 取变量的地址 p 单目运算符 两者关系:互为逆运算 单目运算符 优先级: 2 10 &i &p 优先级: 理解 2 结合性:自右向左 i *p i 结合性:自右向左 &i p 整型变量 2000 i=3; *p=3 2001 10 p &i &(*p) …... 2002
例 8.3 p227将数从大到小输出 swap(int *p1, int *p2) { int *p; p=p1; p1=p2; p2=p; 地址值传 } 递 main() { int a,b; int *pointer_1,*pointer_2; scanf(“%d%d”,&a,&b); pointer_1=&a; pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf(“max=%d,min=%d\n”,a,b); }
表示: void *p; 使用时要进行强制类型转换
表示不指定p是指向哪一种 类型数据的指针变量
13
[例8.2] p225输入两个数,并使其从大到小输出,不改变a,b的值。
main() { int *p1,*p2,*p,a,b; scanf("%d%d",&a,&b); p1=&a; p2=&b; if(a<b) { p=p1; p1=p2; p2=p;} printf("a=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1,*p2); } 运行结果:输入5 9 a=5,b=9 max=9,min=5
if(a<b) swap(a,b)
运行结果 输入:5, 9 输出:5, 9 17
§8.3 指针与数组
指向数组元素的指针变量
例 int a [10]; int *p; p=&a [0]; // p=a;
p+1=====a+1 p+i======a+i p[i]======a [i]
p p+1,a+1
针变量)。
8
例8.1 (书p222)通过指针变量访问整型变量。
#include <stdio.h> 此处*与类型名在一起。此 int main() 时共同定义指针变量 { int a=100,b=10; int *pointer_1, *pointer_2; pointer_1=&a; pointer_2=&b; printf(“a=%d,b=%d\n”,a,b); printf(“*pointer_1=%d,*pointer_2=%d\n”,*pointer_1,*pointer_2); return 0; } 此处*与指针变量一起使用。此时代表 指针变量所指向的变量
a[0] a[1] a[2] a[3] a[4]
1 2 3 4 5
pa
23
例 int a[]={1,2,3,4,5,6,7,8,9,10},*p=a,i; 数组元素地址的正确表示: (A)&(a+1) (B)a++ (C)&p
(D)&p[i]
数组名是地址常量 p++,p-- () a++,a-- () a+1, *(a+2) ()
Pointer-1 Pointer-2
&a a: 5 b:
&b 9
p1: &b &a p
p2: &b &a
运行结果:输入:5,9 输出:5,9
16
例 8.3 p227将数从大到小输出
swap(int x,int y) { int t; t=x; x=y; y=t; } 值传递 main() { int a,b; COPY int *pointer_1,*pointer_2; scanf("%d%d",&a,&b); pointer_1=&a; pointer_2=&b; if(a<b) swap(*pointer_1,*pointer_2); printf("\n%d,%d\n",a,b); }
变量p 指针变量
例
…...
int *p=&i; *p=20; -----间接访问 4