您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 国内外标准规范 > programming_in_ANSI_C-Chapter_11Pointer
PointersOutline1.Introduction2.PointerandFunction3.PointerandArray4.Dynamicallocation5.string,characterarray&pointer6.ExamplesIntroduction100110011100101010001100000010111100101010001100address0001000200031023内存RandomAccessMemory地址Address•计算机内的存储部件,所有指令和数据都保存在内存中•速度快,但是掉电即失•可以随机访问–只要指名要访问的内存单元的地址,就可以立即访问到该单元–地址是一个无符号整数,其字长一般与主机相同–内存中的每个字节都有唯一的一个地址–地址按字节编号,空间按类型分配Variables&AddressMemory:inta=0;a0x0037b000ContentsContentsContentsContentsContentsContentsContentsContentsContentsContentsContents变量的地址变量名0变量的值变量p0x0037b003变量p中存放变量a的首地址0x0037b003变量a•Howtostoretheaddress?•Apointer(指针)isavariablethatcontainstheaddressofanothervariable.thepointerofavariable(变量的指针)&thepointervariable(指针变量)•指针是一种特殊的数据类型,用于存放地址型数据•变量的指针thepointerofavariable–identicalwith变量的地址•指针变量thepointervariable–是C语言中专门用于存放地址型数据的变量thepointerofavariable&thepointervariable指针变量p指向变量地址存入指针变量变量a变量a的地址变量a的值100010081004102310abc3.551000iinta=10,c=5;floatb=3.5;Memoryallocationaaddressavaluepointeraaddressa--isintvariable,storevaluei--ispointer,storeaddressaddress=pointer4bytesIntroductionDirectandIndirectAddressing•Howtor/wthedatainmemory?–通过变量的地址访问变量所在的存储单元•两种寻址方式:–DirectAddressing----直接寻址按变量地址存取变量值–IndirectAddressing----间接寻址通过存放变量地址的变量去访问变量Example:inta=0;int*p=&a;•Directaccess:&a•Indirectaccess:*i•Pointervariables,simplycalledpointers•Holdingmemoryaddressesastheirvalues•Akindofdatatype–Normally,avariablecontainsaspecificvalue,e.g.,aninteger,afloating-pointvalue–However,apointercontainsthememoryaddressofavariablethatinturncontainsaspecificvalue.ShortsummaryofPointerIntroductiondefinitionofpointervariablesbase-type*pointer-variable;Where:base-typeisthetypeofthevaluetowhichthepointerpointspointer-variableisthevariablebeingdeclaredint*p;Char*cptr;int*p1,*p2;float*pf;Initialization•inta,b;•int*p1=&a,*p2=&b;–inta,b;–int*p1,*p2;–p1=&a;–p2=&b;IntroductionfundamentalpointeroperationsTwooperatorstomanipulatepointervalues:&Address-of*Value-pointed-to(dereferencing)intx,y;int*p1,*p2;1000100410081012xyp1p2Introductionx=-42;y=163-421631000100410081012xyp1p2p1=&x;p2=&y;-42163100010041000100410081012xyp1p2Introduction*p1=17;p1=p2;-42163100410041000100410081012xyp1p217163100010041000100410081012xyp1p2Analyzing*(&a)/*该表达式引用的是变量a的内容*/&(*p1)/*该表达式的值代表的是变量a的地址*/inta,b;int*p1,*p2;p1=&a;p2=&b;IntroductionspecialpointerNULLNULLisaconstant0int*p;p=NULL指针变量的特点:•指针变量也是一种变量,因此,它与其它类型变量有相同之处:–在内存中都占据一定的存储空间–必须遵循“先定义、后使用”的规律指针变量的特殊性:(1)指针变量的内容只能是地址,而不能是数据intx,*p;floaty;p=x;/*错误,指针p的内容应为地址*/p=&y;/*错误,必须用相同基类型的变量地址对指针赋值*/p=&x;/*正确,用相同基类型的变量的地址对指针变量进行初始化*/指针变量的特殊性:(2)指针变量必须经初始化后才能使用#includestdio.hvoidmain(){intx,*p;x=10;*p=x;printf(%d\n,*p);}/*错误,使用未初始化的指针p,p指向不明就对其进行写操作*/指针变量必须先赋值,再使用指针变量的特殊性:(3)指针运算实质上就是对地址的运算。因此,指针运算只能参与•赋值运算•算术运算•关系运算指针运算——赋值运算•指针在使用前一定要赋值•为指针变量赋的值必须是一个地址voidmain(){int*p;scanf(%d,p);…}voidmain(){inta,*p=&a;scanf(%d,p);…}错!指针运算——算术运算•加和减,即加、减一个整数或加1、减1int*p;p++;/*指针p的指向原指针值加sizeof(int)个字节*/0x0037b0030x0037b003+sizeof(int)指针运算——算术运算•pipid(i为整型数,d为p指向的变量所占字节数•p++,p--,p+i,p-i,p+=i,p-=i•若p1与p2指向同一数组,p1-p2=两指针间元素个数(p1-p2)/d•p1+p2,p1*p2,p1/p2无意义Examples:inta[10];int*p1=&a[2];int*p2=&a[5];则:p2-p1=3;指针运算——算术运算注意区别下面两条语句:a=*p++;a=(*p)++;a=*p;p=p+1;a=*p;*p=*p+1;指针运算——关系运算•指向同一个数组中的不同元素的两个指针可以进行各种关系运算•要求参与比较的两个指针的基类型必须一致•两个指针的关系运算表示它们所指向的变量在内存中的前后位置关系。指针运算——关系运算•若p1和p2指向同一数组,则p1p2表示p1指的元素在前p1p2表示p1指的元素在后p1==p2表示p1与p2指向同一元素•若p1与p2不指向同一数组,则比较无意义•指针不与非指针量进行比较,但可与NULL(即0值)进行等或不等的关系运算–判断p是否为空指针p==NULL或p!=NULL为什么引入指针的概念•指针为函数提供修改变量值的手段•指针可以改善某些子程序的效率•指针为C的动态内存分配系统提供支持•指针为动态数据结构提供支持–链表list–队列queue–二叉树binary-tree–……指针的使用原则–永远要清楚每个指针指向了哪里–地址值的有效性–永远要清楚指针指向的是什么–(间接)访问的变量的正确性inti,*p;p=&i;int*p;float*q;p=q;inti;float*p;p=&i;int*p;p=100;指针变量只存放地址!一个指针变量不能指向与其类型不同的变量!我是真的,你猜对了!应在类型相同的指针变量之间赋值Whichoneiscorrect?&与*&用来取变量的地址–inti,*p;p=&i;–int*p,a[10];p=a;–int*p,a[10];p=&a[0];–int*p,a[10];p=&a[5];*用来取指针指向地址的内容–inti,*p;p=&i;*p=0;–int*p,a[10];p=a;*p=0;–int*p,a[10];p=&a[0];*p=0;–int*p,a[10];p=&a[5];*p=0;指针的指向•指针指向非其定义时声明的数据类型,将引起warning•void*类型的指针可以指向任意类型的变量•指针在初始化时一般int*p=NULL;–NULL表示空指针,即无效指针,不指向任何内存单元–只是逻辑上无效,并不是真正地无效•如果指针指向一个非你控制的内存空间,并对该空间进行访问,将可能造成危险指针变量与其它类型变量的对比•共性–在内存中占据一定大小的存储单元–先定义,后使用•特殊性–内容只能是地址,而不能是数据–必须初始化后才能使用,否则指向不确定的存储单元–只能指向同一基类型的变量–可参与有限的运算:加/减某整数,自增、自减、关系、赋值Outline1.Introduction2.PointerandFunction3.PointerandArray4.Dynamicallocation5.string,characterarray&pointer6.Examples•既然指针是一种数据类型,自然可以做函数的参数argument和返回值的类型•指针做参数的经典例子:两数的互换swap(argument1,argument2)PointerandFunctionvoidSwap(int*x,int*y){inttemp;temp=*x;*x=*y;*y=temp;}main(){inta,b;a=15;b=8;Swap(&a,&b);printf(a=%d,b=%d,a,b);}voidSwap(intx,inty){inttemp;temp=x;x=y;y=temp;}main(){inta,b;a=15;b=8;Swap(a,b);printf(a=%d,b=%d,a,b);}code1code2Swaptwointegers’value主调函数被调函数实参形参结果有何不同?pointerasarguments主调函数被调函数voidmain(){inta,b;a=15;b=8;Swap(a,b);printf(a=%d,b=%d,a,b);}voidSwap(intx,inty){inttemp;temp=x;x=y;y=temp;}1515ab实参形参88xyab程序1xy简单变量作函数参数1581581581515881581515a)调用Swap函数b)执行Swap函数c)从Swap函数返回tempxybmain函数Swap函数①②③aaatemptempxxyybb主调函数被调函数voidmain(){inta,b;a=15;b=8;Swap(&a,&b);printf(a=%d,b=%d,a,b);}voidSwap(int*x,int*y)
本文标题:programming_in_ANSI_C-Chapter_11Pointer
链接地址:https://www.777doc.com/doc-1084744 .html