第9章%20指针_第1页
第9章%20指针_第2页
第9章%20指针_第3页
第9章%20指针_第4页
第9章%20指针_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、12int main() int a, b; a = 5; b = 9; Swap(a, b); printf( a=%d,b=%d ,a,b); return 0;程序程序 1:简单变量作函数参数:简单变量作函数参数void Swap(int *x,int *y) int temp; temp = *x; *x = *y; *y = temp;int main() int a, b; a = 5; b = 9; Swap( &a, &b ); printf( a=%d,b=%d ,a,b); return 0;程序程序 2:指针变量作函数参数:指针变量作函数参数 Not Wo

2、rk!Why?指针指针为函数为函数提供修改变提供修改变量值的手段量值的手段 3变量的地址变量的地址变量名变量名内存:计算机内的存储部件内存:计算机内的存储部件所有指令和数据都保存在内存里所有指令和数据都保存在内存里速度快,可随机访问,但掉电即失速度快,可随机访问,但掉电即失编译或函数调用时为变量分配内存单元编译或函数调用时为变量分配内存单元0000ContentsContentsContentsContentsContentsContentsContents变量的值变量的值某存储区域4变量的地址变量的地址内存中的每个字节都有唯一的编号(地址)内存中的每个字节都有唯一的编号(地址)地址是一个十六

3、进制无符号整数地址是一个十六进制无符号整数其字长一般与主机相同其字长一般与主机相同地址按字节编号,按类型分配空间地址按字节编号,按类型分配空间0000ContentsContentsContentsContentsContentsContentsContents某存储区域Address Operator5如何读写内存中的数据?如何读写内存中的数据?0000ContentsContentsContentsContentsContentsContentsContents某存储区域只要指明要访问的变量的内存单元地址只要指明要访问的变量的内存单元地址就可以立即访问到变量所在的存储单元就可以立即访问到变

4、量所在的存储单元scanf(%d, &a);6表示输出变量表示输出变量a的地址值?的地址值?7如何读写内存中的数据?如何读写内存中的数据?0000ContentsContentsContentsContentsContentsContentsContents某存储区域直接寻址:按变量地址存取变量值直接寻址:按变量地址存取变量值scanf(%d, &a);8如何读写内存中的数据?如何读写内存中的数据?0000ContentsContentsContentsContentsContentsContents0 x0037b000某存储区域间接寻址:通过存放变量地址的变量去访问变量间接

5、寻址:通过存放变量地址的变量去访问变量9i的值被当作地址。如的值被当作地址。如i=100,则输入的整数就会从地址则输入的整数就会从地址100开开始写入内存始写入内存输入以输入以int的二进制形式写到的二进制形式写到c所所在的内存空间。在的内存空间。c所占内存不足以放下一个所占内存不足以放下一个int,其后的空间也被覆盖其后的空间也被覆盖10 每个变量在内存中都占据一定字节数的存储每个变量在内存中都占据一定字节数的存储单元。编译时根据程序中变量定义的类型为其单元。编译时根据程序中变量定义的类型为其分配存储空间分配存储空间 将每个数据的将每个数据的首字节地址首字节地址作为该数据的作为该数据的地址地

6、址。内存是一个连续编址的空间,每一个存储单元都有内存是一个连续编址的空间,每一个存储单元都有一个固定的编号,这个编号称为一个固定的编号,这个编号称为地址地址。 地址的概念地址的概念 地址地址 指针指针 间接访问间接访问11例如:例如:已定义了一个整型数组已定义了一个整型数组d6。设该数组的设该数组的起始地址为起始地址为0023EE10(d0的地址),的地址),赋值赋值d0=10。数组名是一个数组名是一个常量地址常量地址 , 也为也为0023EE1012注意:注意:变量的内容与变量的地址是两个不同的概念。变量的内容与变量的地址是两个不同的概念。 变量的地址是变量在内存所占存储空间的变量的地址是变

7、量在内存所占存储空间的首地址。首地址。 变量的内容是变量在内存所占存储单元中变量的内容是变量在内存所占存储单元中存放的数据。存放的数据。如变量如变量d0的内容是整数的内容是整数10,而地址是,而地址是0023EE10。13 地址地址 指针指针 间接访问间接访问指针是指针是C语言的重要特点。语言的重要特点。指针既可以指向各种类型的变量,也可以指向函指针既可以指向各种类型的变量,也可以指向函数。数。 P264正确的使用指针,能有效地表示和处理复杂的数正确的使用指针,能有效地表示和处理复杂的数据结构,特别有利于对动态数据的处理。据结构,特别有利于对动态数据的处理。P3351415 指针变量指针变量

8、指向指向 变量变量变量的地址(指针)变量的地址(指针)变量值变量值变量地址存入变量地址存入指针变量指针变量16定义了指针变量定义了指针变量pa,但,但pa并未指向并未指向a?如果指针指向一个非你控制的内存空间如果指针指向一个非你控制的内存空间并对该空间进行访问,将可能造成危险并对该空间进行访问,将可能造成危险17指针变量使用之前必须初始化指针变量使用之前必须初始化Never use uninitialized pointers1819Pointers have names, types and values20指针变量指向的数据类型称为基类型指针变量指向的数据类型称为基类型指针变量只能指向同一

9、基类型的变量指针变量只能指向同一基类型的变量21不能写成:不能写成:int *pa, pb;22 指针的几个概念指针的几个概念2324例如:例如:float *pointer_x;int *p1,* p2;作用:作用:定义某些变量为指针类型,使之专门定义某些变量为指针类型,使之专门用于存放地址。用于存放地址。2526(3)变量前面的)变量前面的“*”不能省略。不能省略。 如:如: int *ptr1,ptr2; 则则 ptr2 被定义为整型变量而非指针变量。被定义为整型变量而非指针变量。 (4)定义指针变量后,并未确定该变量指向)定义指针变量后,并未确定该变量指向 何处。在引用指针变量前,必须

10、让它指何处。在引用指针变量前,必须让它指 向一个变量。向一个变量。 int a=3; float x=2.5 ; int *p1,*p2; p1=&a; p2=&x; 27定义指针变量定义指针变量pa,pb将将a的地址送的地址送pa将将b的地址送的地址送pb输出所指向的变量的内容输出所指向的变量的内容运行结果为运行结果为100,10100,1028二、指针变量的引用二、指针变量的引用 在定义指针变量的同时,在定义指针变量的同时, 可对其初始化。可对其初始化。 如:如: int int * *ip; ip=&i;ip; ip=&i; 可为可为 int int *

11、*ip=&i;ip=&i; 注意:注意:i i的定义一定在的定义一定在ipip定义之前。定义之前。 int i, int i,* *ip=&i;ip=&i; 假设假设i i为整型变量,且有为整型变量,且有 int *p1,*p2;则可通则可通过下面三种方式为指针变量过下面三种方式为指针变量 p1 p1 或或 p2 p2 赋值。赋值。292.2.使用取地址运算符,把地址值赋给指针变量。使用取地址运算符,把地址值赋给指针变量。 例如:例如: p1=&ip1=&i;( (求出变量求出变量i i的内存地址赋给的内存地址赋给p1)p1)。 i i的地址赋予

12、的地址赋予p1p1之后,之后,* *p1p1总是与总是与i i等价。等价。 3. 3. 把指针变量的值直接赋给指针变量。把指针变量的值直接赋给指针变量。 例如:例如: p1=&ip1=&i,p2=p1p2=p1;将使将使p1p1和和p2p2均指向变量均指向变量i i。 3031int *p;float *q;p=q;int i;float *p;p=&i;int *p;p=100;指针变量只指针变量只存放地址存放地址!一个指针变量不能一个指针变量不能指向与其类型不同指向与其类型不同的变量的变量!我是真的,我是真的,你对了吗?你对了吗?应在类型相应在类型相同的指针变同的指

13、针变量之间赋值量之间赋值32例例1 :#include void main()int i,*ip; ip=&i; i=10; printf( %d,%dn ,i,*ip); *ip=100; printf( %d,%dn ,i,*ip);运行结果:运行结果:10,10100,10033voidmain() char ch=A;char *ch_ptr ;ch_ptr=&ch; /*使使ch_ptr指向指向ch*/printf(ch=%cn,ch);printf(*ch_ptr=%cn,*ch_ptr);*ch_ptr=X; /*间接改变间接改变ch的值的值*/printf(ch

14、=%cn,ch);printf(*ch_ptr=%cn,*ch_ptr); printf(ch的地址是的地址是%xn,ch_ptr); /*输出输出ch的地址的地址*/例例2 :34每个变量名都与一个唯一的地址相对应,每个变量名都与一个唯一的地址相对应,用于存放特定类型的数据。用于存放特定类型的数据。指针:指针:一个变量的地址称为该变量的指针。一个变量的地址称为该变量的指针。指针不但指示了数据的存储位置,还标明指针不但指示了数据的存储位置,还标明了该数据的类型。了该数据的类型。指针:指针:指针与地址的区别:指针与地址的区别:3536 三、三、指针的运算指针的运算 指针运算就是地址运算。指针运算

15、就是地址运算。 可以使用的几种运算如下:赋值运算可以使用的几种运算如下:赋值运算, ,加减算术运算加减算术运算( (两指针变量间的运算两指针变量间的运算) ),关系运算。,关系运算。 指针变量初始化指针变量初始化指针在使用前一定要赋值指针在使用前一定要赋值 将一个变量地址赋予指向相同数据类型的指针变量将一个变量地址赋予指向相同数据类型的指针变量 将一个指针变量的值赋予指向相同类型的另一个指将一个指针变量的值赋予指向相同类型的另一个指针变量针变量 如:如:int a,int a,* *pa=&a,pa=&a,* *pb; pb=pa;pb; pb=pa; 把数组的首地址赋予指向数

16、组的指针变量把数组的首地址赋予指向数组的指针变量 如:如: int a5,int a5,* *pa; pa=a; (pa; pa=a; (或或pa=&a0) P314pa=&a0) P314(1)(1)赋值运算赋值运算37 把字符串首地址赋予指向字符类型的指针把字符串首地址赋予指向字符类型的指针变量。如:变量。如: char char * *pcpc; pc=“c language” pc=“c language”; 或:或:char char * *pc=“c language”pc=“c language”;注意:注意: 仅将首地址赋入,仅将首地址赋入, 而不是将字符串而不

17、是将字符串“c c language”language”赋予赋予pcpc, P280P280 将函数的入口地址赋予指向函数的指针变将函数的入口地址赋予指向函数的指针变量。量。P264P264 如:如:int (int (* *pf)( ); pf=fun;(funpf)( ); pf=fun;(fun为函数名为函数名) )38(2)(2)加减算术运算加减算术运算(仅对数组指针变量进行)(仅对数组指针变量进行)P314P314(3)(3)两指针变量间的运算两指针变量间的运算要求:必须是指向要求:必须是指向同一数组同一数组的两个指针变量之间。的两个指针变量之间。相减:求出两者之间的数据个数。(注:

18、相减:求出两者之间的数据个数。(注:不可相加不可相加)关系运算:表示两者所指数组元素间的关系。关系运算:表示两者所指数组元素间的关系。 可进行的运算:可进行的运算:=、=、!= 39交换地址交换地址按原序输出按原序输出由大到小由大到小运行情况:运行情况:5,9 a=5,b=9larger=9,little=5注意:注意:a和和b并未交换,但并未交换,但p1和和p2的值交换了的值交换了40错!41 0 &a 地址地址 指针指针 间接访问间接访问42 0 &a引用指针所指向的变量的值引用指针所指向的变量的值P254称为指针的解引用称为指针的解引用(Pointer Dereferen

19、ce)43直接(寻址)通过变量名就可引用变量的内容。如:直接(寻址)通过变量名就可引用变量的内容。如: int a=0;间接(寻址)将要访问的变量的地址存放在另一个变量中。间接(寻址)将要访问的变量的地址存放在另一个变量中。如:如:*pa=9; 地址地址 指针指针 间接访问间接访问442、求地址运算和访问地址运算、求地址运算和访问地址运算(1) 求地址运算(求地址运算(&)每个变量每个变量/数组都有一个内存地址,可通过数组都有一个内存地址,可通过求地址运算得到。求地址运算得到。& 的含义是的含义是 取地址取地址 45例:例:#include main()int a=1;floa

20、t b=2.0;double c=3; int d6=-1,-2,-3,-4,-5,-6;printf( address of a is%xn ,&a);printf( address of b is%xn ,&b);printf( address of c is%xn ,&c);printf( address of d is%xn ,&d);printf( address of d0 is%xn”,&d0);说明:说明:3232位机位机输出的地址值用输出的地址值用8位十六进制数表示。位十六进制数表示。P249&只能用于变量或数组元素。只能用于变

21、量或数组元素。 &25 &( &25 &(x+y)x+y)均是错误的均是错误的内存中的每个字节都有唯一的编号(地址)内存中的每个字节都有唯一的编号(地址)地址是一个十六进制无符号整数地址是一个十六进制无符号整数其字长一般与主机相同其字长一般与主机相同地址按字节编号,按类型分配空间地址按字节编号,按类型分配空间46(2) 访问地址运算(访问地址运算(*) 用变量名、数组元素名访问数据时:用变量名、数组元素名访问数据时: 从用户角度从用户角度“直接直接”访问访问 从内存角度从内存角度“间接间接”访问访问例例1:a=100例例2:利用:利用*运算符访问数据运算符访问数

22、据, 对变量对变量a&a得到得到a在内存中的地址在内存中的地址*(&a)访问访问a所在内存单元中的数据所在内存单元中的数据* 的含义是的含义是 取内容取内容 47学习目标学习目标熟练掌握指针做函数参数的方法熟练掌握指针做函数参数的方法明确指针与函数的关系明确指针与函数的关系 进一步理解函数参数传递的原理进一步理解函数参数传递的原理4849传变量的值传变量的值形参值的改变形参值的改变不会影响对应的实参不会影响对应的实参50传变量地址传变量地址51指针变量作函数参数指针变量作函数参数可以修改实参的值可以修改实参的值52return仅限于仅限于从函数返回一个值从函数返回一个值53vo

23、id Swap(int *x,int *y) int temp; temp = *x; *x = *y; *y = temp;int main() int a, b; a = 5; b = 9; Swap( &a, &b ); printf( a=%d,b=%d ,a,b); return 0; int main() int a, b; a = 5; b = 9; Swap(a, b); printf( a=%d,b=%d ,a,b); return 0;程序程序 1程序程序 2 主调函数主调函数被调被调函数函数实实 参参形形 参参Not Work!Why?54main() a

24、, b; a = 5; b = 9; Swap(a, b); printf( a=%d,b=%d ,a,b); 0;55ab实实 参参形形 参参99xyabxy55temp9x 和和 y是内部变量是内部变量单向值传递单向值传递主调函数主调函数被调函数被调函数程序程序 155main() a, b; a = 5; b = 9; Swap( &a, &b ); printf( a=%d,b=%d ,a,b); 0;&a&a实实 参参形形 参参&b&bxyabxy5temp5ab995*x*y交换的是交换的是x 和和 y指向的单元内容指向的单元内容主调

25、函数主调函数被调函数被调函数程序程序 2 56指针指针pTemp未初始化未初始化指针指针pTemp指向哪里未知指向哪里未知对未知单元写操作是危险的对未知单元写操作是危险的永远要清楚:永远要清楚:每个指针指向了哪里每个指针指向了哪里指针指向的内容是什么指针指向的内容是什么 57指针指针pTemp被赋了值被赋了值但交换的是地址值但交换的是地址值不是指针指向单元的内容不是指针指向单元的内容58运行情况:运行情况:5,9 9,5交换指针所指交换指针所指向的变量值向的变量值59函数调用过程如下图所示函数调用过程如下图所示:调用调用swap函数之前:函数之前:pa &a 5 &b 9 a

26、pb b60开始调用开始调用swap函数,函数,实参实参pa、 pb分别向形式参数分别向形式参数p1、p2传递数据传递数据 5 &a &a 9 &b &b &a 9 &apap1pbp2pap1 a b a 5 &b &bpbp2 b执行函数语句,执行函数语句,p1、p2所指所指向的变量的值相互交换向的变量的值相互交换61pa &a 9 &b 5 a pb b函数调用结束后,函数调用结束后,p1、p2所占用的内存单元被释放,所占用的内存单元被释放,62运行情况:运行情况:5 9 9,5交换形参数组值交换形参数组值6

27、3交换形参变量值交换形参变量值运行情况:运行情况:5,9 5,964为什么使用指针做函数参数?为什么使用指针做函数参数?用指针作函数参数,可以返回多个值用指针作函数参数,可以返回多个值 减少参数传递过程中的数据复制量。减少参数传递过程中的数据复制量。用指针作函数参数,通过将数据区用指针作函数参数,通过将数据区的地址传递给函数,使函数能够改的地址传递给函数,使函数能够改动该地址处的数据。动该地址处的数据。65用指针作函数参数,可以返回多个值用指针作函数参数,可以返回多个值 #include void subfun(int *m, int *n); /*声明自定义函数声明自定义函数*/ void main() int i, j; printf(i, j=?n); scanf(%d, %d, &i, &j); printf( before calling i=%d j=%d i*j=%dn, i, j, i*j); subfun(&i, &

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论