C语言程序设计教程(修订本)第7章指针.ppt_第1页
C语言程序设计教程(修订本)第7章指针.ppt_第2页
C语言程序设计教程(修订本)第7章指针.ppt_第3页
C语言程序设计教程(修订本)第7章指针.ppt_第4页
C语言程序设计教程(修订本)第7章指针.ppt_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

第7章 指 针,7.1 指针的基本概念 7.2 指针变量 7.3 数组与指针 7.4 字符串与指针 7.5 指针数组与指向指针的指针 7.6 函数与指针 7.7 程序举例,7.1 指针的基本概念 (1)直接存取 所谓直接存取,是指在程序执行过程中需要存取变量值时,直接存取变量所占内存单元中的内容。 (2)间接存取 所谓间接存取,是指为了要存取一个变量值,首先从存放变量地址的指针变量中取得该变量的存储地址,然后再从该地址中存取该变量值。,返回目录,在C语言中,用符号“*”表示“指向”,反映指针变量与它所指的变量之间的联系: (1)在变量类型说明中,变量前加“*”用于区别于普通变量。 (2)在表达式中,变量前加“*”表示间接访问。,7.2 指针变量 7.2.1 指针变量的定义与引用 变量的指针就是变量的地址,即指针变量用于存放变量的地址(即指向变量)。 定义指针变量的一般形式为 类型标识符 *指针变量名;,返回目录,下面对指针变量作几点说明: (1)指针变量名前的“*”表示该变量为指针变量,而指针变量名不包含该“*”。 (2)一个指针变量只能指向同一类型的变量。 (3)指针变量中只能存放地址,而不能将数值型数据赋给指针变量。 (4)只有当指针变量中具有确定地址后才能被引用。 (5)与一般的变量一样,也可以对指针变量进行初始化。,7.2.2 指针变量作为函数参数 与普通变量一样,指针变量也可以作为函数参数。利用指针变量作为函数的形参,可以使函数通过指针变量返回指针变量所指向的变量值,从而实现函数调用函数与被调用函数之间数据的双向传递。 在用指针变量作为函数形参时,其实参也应为指针变量。,例7.2 利用指针变量实现两个变量值的互换。 其C程序如下: #include “stdio.h“ swap(p1,p2) int *p1, *p2; int t; t*p1; *p1*p2; *p2t; return; main() int a, b; scanf(“%d,%d“,&a,&b); printf(“a%d,b%dn“,a,b); swap(&a,&b); printf(“a%d,b%dn“,a,b); ,7.3 数组与指针 7.3.1 数组的指针与数组元素的指针 所谓数组的指针是指数组的首地址。数组元素的指针是指数组元素的地址。因此,同样可以用指针变量来指向数组或数组元素。,返回目录,例7.3 下列C程序是从键盘为数组元素输入数据: #include “stdio.h“ main() int a10,i; for (i0;i10;ii1) scanf(“%d“,&ai); printf(“n“); for (i0;i10;ii1) printf(“%5dn“,ai); ,也可以直接使用数组名,将上述程序改为 #include “stdio.h“ main() int a10,i; for (i0;i10;ii1) scanf(“%d“,ai); printf(“n“); for (i0;i10;ii1) printf(“%5dn“,*(ai); ,还可以使用指针变量,将上述程序改为 #include “stdio.h“ main() int a10,*pa,i; for (i0;i10;ii1) scanf(“%d“,pi); printf(“n“); for (i0;i10;ii1) printf(“%5dn“,*(pi); ,使用指针变量后,指针变量所指向的数组元素也可以用下标的形式,又可以将上述程序改为 #include “stdio.h“ main() int a10,*pa,i; for (i0;i10;ii1) scanf(“%d“,pi); printf(“n“); for (i0;i10;ii1) printf(“%5dn“,pi); 以上四个程序是等价的。,下面对数组与指针作几点说明: (1)指针变量可以指向数组中的任何一个元素。 (2)用于指向数组或数组元素的指针变量类型必须与数组类型相同。 (3)C语言规定,当指针变量p指向数组的某一元素时,p1将指向下一个元素。 (4)C语言规定,数组名代表数组的首地址,但它是固定不变的,即不能对数组名进行赋值(即赋以新的地址值)。,7.3.2 数组指针作为函数参数 一般来说,在数组指针作函数参数时,有以下四种情况: (1)实参与形参都用数组名。例如, main() f(x,n) int a10; int x,n; f(a,10); ,(2)实参用数组名,形参用指针变量。例如, main() f(x,n) int a10; int *x,n; f (a,10); ,(3)实参与形参都用指针变量。例如, main() f(x,n) int a10,*pa; int *x,n; f (p,10); ,(4)实参用指针变量,形参用数组名。例如, main() f(x,n) int a10,*pa; int x,n; f(p,10); ,7.3.3 多维数组与指针 1对多维数组的理解 2多维数组的指针 多维数组的指针有以下两种。 (1)指向数组元素的指针变量,例7.5 下列C程序是将一个二维数组中的元素按矩阵方式输出。 #include “stdioh“ main() static int a341,2,3,4,5,6,7,8,9,10,11,12; int *p; for (pa0; pa012; pp1) if (pa0)%40) printf(“n“); printf(“%5d“,*p); printf(“n“); ,(2)指向数组行的指针变量 所谓指向数组行的指针变量p,是指当p指向数组的某一行时,p1将指向数组的下一行。即:如果p&ai时,则p1&ai1。 定义指向数组行的指针变量的一般形式如下: 类型标识符 (*指针变量名)数组行元素个数;,7.4 字符串与指针 7.4.1 字符串指针 在C语言中,表示一个字符串有以下两种形式: (1)用字符数组存放一个字符串。 (2)用字符指针指向一个字符串。,返回目录,字符数组和字符指针变量都能实现字符串的存储与运算。两者既有联系又有区别,主要体现在以下几个方面: (1)字符数组由元素组成,每个元素中存放一个字符;而字符指针变量中存放的是地址,也能作为函数参数。 (2)对数组赋初值要用static存储类别。 (3)只能对字符数组中的各个元素赋值,而不能用赋值语句对整个字符数组赋值。 (4)字符数组名虽然代表地址,但数组名的值不能改变。,(5)可以用下标形式引用指针变量所指向的字符串中的字符。 (6)可以通过输入字符串的方式为字符数组输入字符元素;但不能通过输入函数让字符指针变量指向一个字符串,因为由键盘输入的字符串,系统是不分配存储空间的。 (7)可以用指针变量指向的字符串来表示程序中的任何字符串,如printf函数中的格式字符串。,7.4.2 字符串指针作为函数参数 一般来说,当需要在两个函数之间传递字符串时,可以采用以下四种形式: (1)实参与形参都用字符数组名。 (2)实参用字符数组名,形参用字符指针变量。 (3)实参与形参都用字符指针变量。 (4)实参用字符指针变量,形参用字符数组名。,例7.6 编写一个能实现字符串复制以及计算字符串长度功能的函数。 C程序如下(包括主函数): int str_copy(str1,str2) char *str1,*str2; int k; k0; while(str1k!0) str2kstr1k; kk1; str2k0; return(k1); ,#include “stdioh“ main() char str120,str220; int k; printf(“input str1: “); scanf(“%s“,str1); printf(“str1%sn“,str1); kstr_copy(str1,str2); printf(“str2%sn“,str2); printf(“k%dn“,k); ,7.5 指针数组与指向指针的指针 7.5.1 指针数组的概念 元素值均为指针类型数据的数组称为指针数组。 指针数组的定义形式如下: 类型标识 *数组名数组长度说明;,返回目录,图7.2 数组的初始化,如图7.2所示的指针数组:,例7.7 指针数组作为矩阵运算函数的参数。 在下面的C程序中,主函数中定义了一个54的矩阵,然后调用函数asd()对该矩阵赋值,最后在主函数中按矩阵形式输出。在第6章中曾经提到,在用二维数组作为实参时,在被调用函数中均定义为一维的形参数组,根据二维数组中的元素以行为主存储的原则,将二维数组元素中的两个下标(行标与列标)转换成一维数组元素的下标,从而实现一维数组元素与二维数组元素的对应。因此,在本例的函数asd()中,也用一维形参数组b与主函数中的二维数组a对应。,#include “stdioh“ main() int i, j, a54; asd(a,5,4); for (i0; i5; ii1) for (j0; j4; jj1) printf(“5d“,aij); printf(“n“); asd(b,m,n) int m, n, b(或*b); int k1, i, j; for (i0; i5; ii1) for (j0; j4; jj1) bi*njk; kk1; return; ,现在利用指针数组来实现二维数组的传递。在主函数中除了定义一个二维数组a(表示矩阵)以外,再定义一个一维指针数组b,并且在该指针数组的每一个元素中对应存放二维数组a中每一行的首地址,即让指针数组b中的每个元素指向二维数组a的对应行。在调用函数asd()时,实参使用一维指针数组b,即将二维数组a中各行的首地址传递给函数asd()。在这种情况下,函数asd()中的形参也是一维指针数组,其中bij表示bi所指向的数组行中第j个元素,实际上就是主函数中的元素aij。其C程序如下:,#include “stdioh“ main() int i, j, a54, *b5; for (i0; i5; ii1) bi&ai0; asd(b,5,4); for (i0; i5; ii1) for (j0; j4; jj1) printf(“5d“,aij); printf(“n“); asd(b,m,n) int m, n, *b; int k1, i, j; for (i0; i5; ii1) for (j0; j4; jj1) bijk; kk1; return; ,利用指针数组来实现二维数组的传递还可以这样来实现:在主函数中只定义一个一维指针数组,然后利用malloc()函数为该指针数组中的每一个元素指向一个能存放4个整型元素的存储空间,每一个存储空间正好可以存放整型二维数组中一行的4个元素。这样,一维指针数组b中所有元素所指向的存储空间就可以作为二维数组的存储空间。 其C程序如下:,#include “stdioh“ #include “stdlibh“ main() int i, j, *b5; for (i0; i5; ii1) bimalloc(4*sizeof(int); asd(b,5,4); for (i0; i5; ii1) for (j0; j4; jj1) printf(“5d“,bij); printf(“n“); asd(b,m,n) int m, n, *b; int k1, i, j; for (i0; i5; ii1) for (j0; j4; jj1) bijk; kk1; return; ,7.5.2 指向指针的指针 指向指针的指针就是指向指针型数据的指针。如 char *p; 其中*p等价于*(*p)。,例7.8 下列C程序是利用指针的指针来指向数组中的各元素并输出。 #include “stdioh“ main() static int a51,2,3,4,5; static int *num5&a0,&a1,&a2,&a3,&a4; int *p, k; pnum; for (k0; k5; kk1) printf(“%5d“,*p); pp1; printf(“n“); ,7.5.3 main函数的形参 C语言中的主函数是可以有参数的。带参数main函数的一般形式如下: main(argc,argv) int argc; char *argv; 其中argv是一个字符型的指针数组,每个元素可以指向一个字符串。需要说明的是,带参数main函数中的两个参数名不一定非要是argc与argv,也可以是别的名字。,例7.9 编写一个命令程序,其命令符为file,用以输出命令行中除命令符外以空格分隔的所有字符串(一行输出一个字符串)。 其C程序如下: /*filec*/ #include “stdioh“ main(int argc,char *argv) int k; for (k1;kargc1;k) printf(“%sn“,argvk); ,将上述程序以文件名file.c存放,然后在Turbo C系统中进行编译连接: tcc file 生成可执行程序文件fileexe。运行结果为 file new good China asdfg (此为命令行,以下四行为程序输出结果) new good China asdfg,7.6 函数与指针 7.6.1 用函数指针变量调用函数 在C语言中,指针不仅可以指向整型、字符型、实型等变量,还可以指向函数。一般来说,程序中的每一个函数经编译连接后,其目标代码在计算机内存中是连续存放的,该代码的首地址就是函数执行时的入口地址。在C语言中,函数名本身就代表该函数的入口地址。所谓指向函数的指针,就

温馨提示

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

评论

0/150

提交评论