版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
指针1第九章指针指针与指针变量指针与函数指针与数组指针数组29.1指针与指针变量基本概念指针是一种数据类型 整数型int
基本类型 实数型float,double
字符型char
指针类型 数据类型 数组型 构造类型 结构型struct
联合型union
枚举型enum
空类型void数据结构、表示范围、存储分配39.1指针与指针变量指针是一个地址——是变量在内存中所对应存储单元的地址变量的四个属性变量名称变量数据类型变量值变量地址char
c=‘a’;?49.1指针与指针变量变量的地址多数现代计算机用字节(byte)来分割内存,每个字节可以存储8位(bit)信息;每个字节都有唯一的地址(address)。012340100011101101111011011110110010001000011……01000011……n-1地址内容59.1指针与指针变量程序运行时,要将变量的值保存在计算机的存储单元中,每个变量占有一个或多个内存字节,把第一个字节的地址称为变量的地址。…1000charc=‘a’;变量c地址为1000…………floatf=1.6;变量f地址为2000…20002001变量f变量c‘a’2002200369.1指针与指针变量指针变量是存放地址的变量指针变量pc是char型指针;它的值为1000H,即变量c的地址,或称指针变量pc指向变量c;pc拥有自己的内存地址。…1000Hcharc;…变量c‘a’1001H1000H变量pc3000Hchar*pc;pc=&c;c=‘a’;79.1指针与指针变量mark[0]mark[1]mark[2]mark[3]...mark[99]86.592.077.552.0...94.02000H2004H2008H200CH...218CHfloatmark[100]floatmark[100];p=mark;p=&mark[0];指针变量p是float型指针;它的值为2000H,即数组mark的首地址,也是元素(变量)mark[0]的地址float*p;等价89.1指针与指针变量
指针变量与地址常量inta[3]={1,2,3},b,*p;p=a;scanf(“%d”,&b);p=&b;a是数组名,是数组的首地址,是一个地址常量;&b是取b的地址,也是地址常量;p是一个指针变量,它可以用来存放地址——它是一个容器。99.1指针与指针变量小结指针:变量的地址一般变量:存储变量的值指针变量:存储变量地址请注意指针变量与地址常量的区别109.1指针与指针变量指针变量的定义与赋初值数据类型*指针变量名[=初值];例如:inta,*pa;
pa=&a;指针的类型,是指针所指的变量的类型*为指针说明符,说明后面的标识符为指针变量(它也是间接访问符)指针变量是变量,要先定义,再赋值,再使用!119.1指针与指针变量为指针变量赋初值使用赋值语句inta,*pa;/*说明变量a和指针变量pa*/pa=&a;/*将变量a的地址赋给指针pa*/变量说明同时赋初值
inta,*pa=&a;12引用指针变量&——取地址运算符*——指针内容运算符(间接存取运算符)intx=10,*p,y;p=&x;
/*取变量x的地址赋给指针变量p*/y=*p;
/*取指针变量p所指单元的内容赋给变量y*/有类型说明符的作用运算符p自动取两个(或4个)字节的内容给y139.1指针与指针变量变量的两种访问方式直接访问:通过变量名访问该变量。间接访问:通过指针变量中存放的地址访问该变量。inta=10;printf(“%d\n”,a);/*通过访问变量a,输出a的值*/inta=10,*p=&a;printf(“%d\n”,*p);/*通过p间接访问a并输出a值*/149.1指针与指针变量
练习:已知inta,*p=&a;若给a赋值或输出,下面语句正确的是:
A)scanf(“%d”,a); B)scanf(“%d”,p); C)scanf(“%d”,&a); D)printf(“%d”,a); E)printf(“%d”,p); F)printf(“%d”,*p);159.1指针与指针变量例:
已知:intx=2,y,*px; x为一般变量,px为指针型变量px
px=&x;
*px=10;x210
x=10;*px
*(&x)
x169.1指针与指针变量
y=x*100;*px=y*10;++x;x++;pxx210y=*px;
y=*px*100;
x=y*10;++*px;(*px)++;括号不能省略
y=x; 17基本运算辨析
intx=10,y=5,*p=&x,*q=&y;px210qy25p=q;为指针p赋值,使p和指针q指向同一单元qy25p*p=*q;为指针p的内容赋值,使*p和*q的值相同qy25px2105189.1指针与指针变量思考:哪些是正确的?inta=1,*pa;*pa=a;inta=1,*pa=&a;inta=1,*pa;pa=&a;指针变量是变量,要先赋值,再使用!
inta=1,*pa;*pa=&a;
199.1指针与指针变量指针可以指向所有类型的数据指针指向变量--变量的指针(存变量的地址)指针指向数组--数组指针(存数组的起始地址)指针指向函数--函数指针(存放函数的入口地址)指针指向指针--指针型指针(存放某指针的地址)由指针组成的数组--指针数组指针指向结构指针指向文件
——指针是定位其它对象的特殊类型的数据。20第九章指针指针与指针变量指针与函数指针与数组指针数组219.2指针与函数三个方面:指针作为函数的参数函数返回指针指向函数的指针多用于字符串操作229.2指针与函数指针作为函数的参数用指针在函数之间“传递”地址,做到共享存储。必须满足:实参和形参应是同类型的指针或指针变量。23例:交换intswap(intx,inty){intt;t=x;x=y;y=t;printf(“swap:x=%d,y=%d\n”,x,y);return;}intmain(){intx=2,y=3;printf(“before:x=%d,y=%d\n”,x,y);
swap(x,y);printf(“after:x=%d,y=%d\n”,x,y);}输出:before:x=2,y=3swap:x=3,y=2after:x=2,y=3值传递,主函数中x,y值未交换24用指针完成两数的交换intswap(int*px,int*py){intt;t=*px;*px=*py;*py=t;printf(“swap:x=%d,y=%d\n”,*px,*py);return;}intmain(){intx=2,y=3;printf(“before:x=%d,y=%d\n”,x,y);
swap(&x,&y);printf(“after:x=%d,y=%d\n”,x,y);}输出:before:x=2,y=3swap:x=3,x=2after:x=3,y=2由于指针变量px接受的是x的地址,所以*px就是x。地址传递,主函数中x,y值交换25
数组名、指针、形参、实参在函数之间传递数组,数组名可以作函数的实参和形参,指针也可以做函数的实参和形参,对应关系有以下4种:
1.形参和实参都用数组名;
2.实参用数组名,形参用指针变量;
3.实参、形参都用指针变量;
4.实参为指针变量,形参为数组名;在函数之间传递数组,当形参使用指针时,在被调用函数的内部,就可用指针方式访问数组中的元素。26fun(charstr[]){}main(){chars[10]=“abc”;fun(s);}①fun(char*str){}main(){chars[10]=“abc”;fun(s);}②fun(charstr[]){}main(){chara[8],*s=a;fun(s);}④fun(char*str){}main(){chara[8],*s=a;fun(s);}③279.2指针与函数函数返回指针即函数的返回值是指针类型,这样的函数定义形式为:类型*函数名
(形式参数表){…}例如:int*fun
(intx) {…}289.2指针与函数比较返回char值:charmin(chara[10]){chari,m;m=a[0];for(i=1;i<10;i++)if(m>a[i])m=a[i];returnm;}返回char*(char指针)值char*min(chara[10]){chari,*m;
m=&a[0];for(i=1;i<10;i++)if(*m<a[i])
m=&a[i];returnm;}29指向函数的指针函数指针(函数地址):函数的入口地址(用函数名表示)
指向函数的指针变量:
存放函数入口地址的指针变量
定义
int(*p)();p是指向int函数的指针变量
p=max;p是指向int型函数max的指针变量309.2指针与函数用函数指针调用函数max(intx,inty){returnx>y?x:y;}intmain(){intc,a=15,b=12,(*p)();p=max;/*p指向函数max*/c=(*p)(a,b);/*用指针p调用函数*/printf(“max=%d\n”,c);}319.2指针与函数请区分返回指针的函数和指向函数的指针变量:
int*func() {…} int(*func)();定义了一个返回指针的函数定义了一个指向函数的指针变量32第九章指针指针与指针变量指针与函数指针与数组指针数组339.3指针与数组指向数组元素的指针指针基本运算指针加减一个正整数两个指针的关系运算两个指针之间的减法运算指向数组的指针(数组指针)字符指针与字符数组指针数组349.3指针与数组指向数组元素的指针定义
inta[5],*p=a;p指针的基类型是int,它可以指向int型数组元素。通过赋初值,p指向a[0]。a[0]a[1]......a[i]a......a&a[0]
数组在内存中占一片连续的存储单元。用数组名表示该片存储区的首地址。用下标方式引用数组元素。35用指向数组元素的指针引用一维数组元素inta[6]={1,2,3,4,5,6},*p=a;a+i&a[i]地址*(a+i)a[i]内容若p=a;则p+i&a[i]地址*(p+i)a[i]内容
p[i]*(p+i)a[i]相对p指针当前位置移动i个单元的内容aa+1a+ia+2...a[i]a[1]a[2]aa[0]......pp+1p+ip+236aa+1a+4a+2a[3]a[1]a[2]aa[0]pp+1p+2p+3a[4]pa+3p+2p+1a是常量,p是变量!(更灵活更快)pp++p--p-1数组的下标引用数组的指针引用数组的数组名引用37inta[6]={1,2,3,4,5,6},*p;p=a;k=*(p+2);h=p[2];*p=?k=?h=?133p=a+2;k=*(p+2);h=*(p-2)+p[1];*p=?k=?h=?351+4=5p=a;p+=1;k=*p++;h=*++p;(*p)--;*p=?k=?h=?32438用指向数组元素的指针引用二维数组元素多维数组元素在内存中线性排列:b[0][0]b[0][1]b[0][2]b[1][0]b[1][1]b[1][2]指针引用*p*(p+1)*(p+2)*(p+3)*(p+4)*(p+5)指针按下标引用p[0]p[1]p[2]p[3]p[4]p[5]下标引用若p=b[0]:p[i*列数+j]*(p+i*列数+j)b[i][j]399.3指针与数组指向数组元素的指针指针基本运算指针加减一个正整数两个指针的关系运算两个指针之间的减法运算指向数组的指针(数组指针)字符指针与字符数组409.3指针与数组指针基本运算指针加减一个正整数inta[10],*p;设
p=&a[5];若p++;p指向?
若p--;p指向?若a++;a[6]a[4]a=a+1,a是地址常量,不能出现在赋值等号左边
419.3指针与数组放大因子由于指针所指的对象不同,在进行加减运算时,C语言会根据所指对象计算出不同的放大因子。对于char,放大因子为1;对于int,放大因子为2或4;对于long,放大因子为4;对于double,放大因子为8。42例:编写函数,实现字符串复制intmain(){chara[30],b[30];printf("Enterstring:");scanf("%s",a);stringcpy(a,b);/*调用函数的实参为数组名*/printf("a=%s\nb=%s\n",a,b);}stringcpy(str1,str2) /*将串str1拷贝到串str2中*/char*str1,*str2; /*形参为指向字符的指针*/{while((*str2=*str1)!=‘\0’)/*通过指针操作数组*/
{
str1++;str2++;
}}43对上述复制函数的改进原循环语句:while((*str2=*str1)!=‘\0’){
str1++;str2++;}改进1:while((*str2++=*str1++)!=‘\0’);改进2:while(*str2++=*str1++)449.3指针与数组两个指针的关系运算两个指针指向同一数组的元素时才能进行指针关系运算(>、<、>=、<=、!=、==)。例如:当指针p和q指向同一数组中的元素时,则:关系表达式“p<q”:当p所指的元素在q所指的元素之前时,表达式成立;反之,表达式不成立。关系表达式“p==q”:判断指针p和q是指向同一存储单元。当指向同一元素时,表达式成立;反之,表达式不成立。45基本运算辨析
intx=10,y=5,*p=&x,*q=&y;p==q判断指针p和指针q是否指向同一单元*p==*q判断指针p和指针q的内容是否相同46
空指针
NULLNULL具有特殊的含义:表示指针没有指向任何对象;任何指针p与NULL进行“p==NULL”或“p!=NULL”运算均有意义:判断指针p是否指向空;使用NULL时要include<stdlib.h>。void型指针无指定类型的指针(通用型指针)47申请及释放内存函数(malloc、free)void*malloc(unsignedsize)功能:申请长度为size字节的内存区。申请成功,函数返回所分配的内存区首字节的地址,即指向该内存的指针;申请失败,函数返回NULL。voidfree(void*p)功能:释放p所指的内存空间。举例:
int*p; p=
malloc(10*sizeof(int)); … free(p);(int*)malloc的返回值为void型指针,是通用指针类型,在实际申请内存时,要进行指针类型强制转换489.3指针与数组两个指针之间的减法运算当两个指针指向同一数组中的元素时,才能进行指针间的减法运算,当两个指针分别指向不同数组的元素时,无意义。当两个指针指向同一数组中的元素时,p-q的物理意义是:指针p和q所指对象之间的元素的数量。499.3指针与数组例:编写函数,求字符串的长度。stringlen(char*s)/*求串s的长度*/{char*p=s;while(*p)p++;/*找到串结束标记\0*/return(p-s);/*两个指针相减,求出串长*/}abcdef\0sp=s+6串长=6509.3指针与数组指向数组元素的指针指针基本运算指针加减一个正整数两个指针的关系运算两个指针之间的减法运算指向数组的指针(数组指针)字符指针与字符数组51指向数组的指针
回顾二维数组的地址
二维数组名b表示二维数组的首地址
b[i]表示i行一维数组的首地址且有:b[i]+j&b[i][j]b+i表示i行首地址b[i]的地址b[2]b[0]b[1]bb+1b+2174523952b
二维数组是数组的数组*(*(b+i)+j)b[i][j]52指向数组的指针数据类型(*数组名)[元素个数];intb[2][3]={1,2,3,11,12,13};int(*p)[3];p是指向含有3个元素的一维数组的指针,一维数组的3个元素分别是(*p)[0],(*p)[1],(*p)[2]。若p=b:(*(p+i))[j]
b[i][j]*(*(p+i)+j)b[i][j](*p)[0](*p)[1](*p)[2]pp+153比较指向数组元素的指针:inta[3],*pa=a;paa&a[0]指向数组元素的指针仍是指向变量的指针指向一维数组的指针:intb[2][3],(*pb)[3]=b;pbb&b[0]pb指向的是数组,是长度为3的整型数组a[0]b[0][0]b[1][0]apabpbb[0]pa和a是一个级别的指针pb和b是一个级别的指针549.3指针与数组对二维数组元素的引用用指向数组元素的指针引用二维数组元素用指向数组的指针引用二维数组元素559.3指针与数组b[0][0]b[0][1]b[0][2]b[1][0]b[1][1]b[1][2]指向数组元素的指针pb*pb*(pb+1)*(pb+2)*(pb+3)*(pb+4)*(pb+5)
指向数组的指针p(*p)[0] **p(*p)[1] *(*p+1)(*p)[2] *(*p+2)(*(p+1))[0] **(p+1)(*(p+1))[1] *(*(p+1)+1)(*(p+1))[2] *(*(p+1)+2)下标引用intb[2][3],*pb=b[0],(*p)[3]=b;56用指向数组的指针访问二维数组intmain(){intb[2][3]={1,2,3,4,5,6},(*p)[3]=b,i,j;for(i=0;i<2;i++){for(j=0;j<3;j++)printf(“%4d”,);printf(“\n”);}}*(*(p+i)+j)b[i][j]p[i][j](*(p+i))[j]57用指向数组元素的指针引用二维数组元素intmain(){intb[2][3]={1,2,3,4,5,6},*p=b[0],i;for(i=0;i<6;i++){printf(“%4d”,);if((i+1)%3==0)printf(“\n”);}}p是指向数组元素的指针*p++p[i]58指针与数组小结数组名inta[3],b[2][3]; *(a+i)a[i];*(*(b+i)+j)b[i][j];指向数组元素的指针int*p; p=a(或=&a[0]);p=b[0](或=&b[0][0]);*(p+i)a[i];*(p+i*3+j)b[i][j];指向数组的指针int(*p)[3];p=b(或=&b[0]);(*(p+i))[j]b[i][j];599.3指针与数组
inta[3]; int*pa; pa=a; a:一级地址常量
pa:一级指针变量intb[2][3];int(*pb)[3];pb=b;b:二级地址常量pb:“二级”指针变量
请区分指向数组元素的指针和指向数组的指针!60第九章指针指针与指针变量指针与函数指针与数组指针数组619.4指针数组指针数组
数组中的元素均为指针类型,称之为指针数组。 指针数组说明的形式为:数据类型*数组名[常量表达式]
例如:int*p[6];
含义:定义一个由6个指针变量构成的指针数组,数组中的每个数组元素━━指针,都指向一个整数。62比较指针数组:int*p[3];数组p中的每一个元素都是指向int的指针变量数组指针:int(*pb)[3];pb指向长度为3的整型数组p[0]p[1]p[2]intintintintintint(*pb)[0](*pb)[1](*pb)[2]pb63例:w_day表用指针数组实现。char*w_day[8]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",NULL};Sunday\0Monday\0Tuesday\0Friday\0Thursday\0Saturday\0Wednesday\0数组w_dayw_day[0]w_day[1]w_day[2]w_day[3]w_day[4]w_day[5]w_day[6]w_day[7]NULL64
用指针数组实现输入字符串查找是星期几。#include<stdlib.h>char*w_day[8]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday",NULL};intmain(){inth;charstring[20];printf("Enterastring:");scanf("%s",string);h=lookup(string);printf("h=%d\n",h);}lookup(charch[])/*传递字符串(字符数组)*/{inti,j;for(i=0;w_day[i]!=NULL;i++)/*完成查找工作*/if(strcmp(w_day[i],ch)==0)returni;/*找到*/return-1;/*若没有找到,则返回-1*/}659.4指针数组intmain(){char*p[]={"one","two","three"}inti;for(i=0;i<3;i++)printf("%s\n",*p++);}*(p+i)或p[i]
p是数组名,是一个地址常量,不可进行++运算。这里可改为669.4指针数组main函数的参数 主函数也可以有参数:
intmain(intargc,char*argv[])
其中:argc命令行参数个数(包括运行文件名)*argv[]指向命令行各参数的指针数组命令行:运行文件名参数1参数2参数3c:\devc>testa1b2c3argv[1]argv[0]argv[2]argv[3]67例:/*本程序运行文件名为test1.exe*/intmain(intargc,char*argv[]){inti;printf(“argc=%d\n”,argc);for(i=0;i<argc;i++)printf(“%s\n”,argv
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年辽宁省灯塔市高二生物下册期末考试测试卷(培优)附答案
- 2025年云南省腾冲市高二生物下册期末考试试卷及一套完整答案
- 2025年辽宁省盖州市高二生物下册期末考试模拟卷及参考答案【培优A卷】
- 2026年湖北省洪湖市高二生物下册期末考试测试卷【学生专用】附答案
- 2026年山东省乐陵市高二生物下册期末考试试卷附参考答案(培优B卷)
- 2026年广东省普宁市高二生物下册期末考试检测卷附参考答案【预热题】
- 2026年四川省江油市高二生物下册期末考试检测卷及答案(名师系列)
- 2025年云南省泸水市高二生物下册期末考试试卷及参考答案【综合卷】
- 2026年山西省霍州市高二生物下册期末考试模拟卷附参考答案(B卷)
- 2026年江苏省启东市高二生物下册期末考试考试卷及答案【真题汇编】
- 精神科急救知识培训课件
- 光伏安装培训资料
- 药厂质量意识培训
- 二手交易平台运营管理规则
- 陕西榆林能源集团有限公司招聘真题
- 敦煌学智慧树知到期末考试答案章节答案2024年西北师范大学
- 光伏发电站逆变器检修维护规程
- 软件系统调试方案
- 中建悬挑卸料平台专项施工方案
- 2023年电机拖动极其控制(运动控制)期末考试题库
- 铸件验收标准
评论
0/150
提交评论