7.6 数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)

2024-08-11
| 29页
| 48人阅读
| 6人下载
普通

内容正文:

第7章 函数 内容概述 函数的概念和分类 函数的定义、声明及调用 函数间参数的传递及返回值 函数的嵌套及递归 变量作用域及存储特性 教学目标 掌握自定义函数的一般结构及定义函数的方法; 掌握形参、实参、函数原型等重要概念。掌握函数声明、函数调用的一般方法; 熟悉函数嵌套的概念,能定义和使用嵌套函数。 了解局部变量、全局变量和变量的存储类型的概念,掌握auto型和static型局部变量的特点和用法。 了解main函数的参数及用法。 7.6.1 实参到形参的数据传递方式 传值方式传递数据 函数调用时,调用函数把实参的值复制一份,传送给被调用函数的形参,从而实现调用函数向被调用函数的数据传送。实参对形参的数据传送是单向的。 传址方式传递数据 函数调用时,将实参的地址传给被调用函数,被调用函数从传过来的地址中取出实参所存的数据进行操作。在传址方式中,实参和形参占用是同一段内存单元,因此形参值的修改实际是就是对实参值的修改。 7.6 数组作为函数的参数 数组用作函数参数有两种形式:数组元素 作为实参;数组名作为函数的形参和实参。 1 数组元素作函数实参 数组元素也可以作函数的实参,把作为实参的数组元素的值传送给形参,实现单向的值传送。 7.6.2 数组作为函数的参数 【例7.10】判别一个整数数组中各元素的值,若大于0 则输出该值,若小于等于0则输出0值。 #include<stdio.h> void nzp(int v) { if(v>0) printf("%d ",v); else printf("%d ",0); } main() { int a[5] , i; printf("input 5 numbers "); for(i=0;i<5;i++) { scanf("%d",&a[i]); nzp(a[i]); } } 2 数组名作为函数的参数 数组名作函数参数时,要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当函数调用发生时,实参数组的首地址传递给形参变量(其实质是一个指针变量),所以被调用函数中所处理的数组即为主调函数中的数组,这是一种地址传递方式。 #include<stdio.h> float aver(float a[ ]) /*定义求平均值函数,形参为一浮点型数组名*/ { int i; float av, s=a[0]; for(i=1;i<5;i++) s += a[i]; av=s/5; return av; } 【例7.11】已知某个学生5门课程的成绩,求平均成绩。 void main() { float sco[5],av; int i; printf(" input 5 scores: "); for(i=0;i<5;i++) scanf("%f",&sco[i]); av=aver(sco); /*调用函数,实参为一数组名*/ printf("average score is %5.2f ",av); } 说明: (1)用数组名作函数参数,应该在调用函数和被调用函数中分别定义数组,且数据类型必须一致,否则结果将出错。例如,在本案例中,形参数组为a[],实参数组为sco[],它们的数据类型相同。 (2)C编译系统对形参数组大小不作检查,所以形参数组可以不指定大小。例如,本案例中的形参数组a[]。 (3)数组名作函数实参时,将数组的首地址传给函数的形参数组,两个数组共占同一段内存。 【例7.6】编写函数int cpystr (char dest[],char src[],int s,int n),实现将字符串src中从第s个字符开始的n个字符复制到dest中,要考虑s大于src中字符的个数、s<1或n≤0等情况。 〖程序分析〗 字符串的复制即逐个字符的复制。本程序的字符复制过程可分解如下: (1)要先求出src的长度len; (2)若s>len、s<1或n≤0则退出程序; (3)否则先定位到src的第s个字符; (4)再依次将src中的字符复制到dest中; (5)直到复制了n个字符或遇到结束符为止。 #include “stdio.h” void main ( ) { int cpystr(char dest[], char src[], int s, int n); /* 函数声明 */ char a[] = "C Programing Design"; char b[20]; int res; res = cpystr (b, a, 3, 17); if (res > 0 ) printf ("the copy result is:%s ", b); else printf ("Error. "); } int cpystr(char dest[], char src[], int s, int n) { int i, j, l ; if (s<1||n<=0) return -1; l= 0; while( src[l] ) l++; /*求src的长度*/ if (s>l) return 0; for ( i = 0; i < n; i++) { j= s–1+i; if ( src[j] == '\0' ) break; dest[i] = src[j]; /*字符复制*/ } dest[i] = '\0'; return n; } 变量的数据类型 变量应占用的内存空间大小 变量在存储空间分配时所限定的边界条件 变量的性质 变量的数据类型 变量存储类型 变量的作用域 变量的生存期 共同决定 7.7变量的作用域及存储特性 局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。 全局变量也称为外部变量,它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。 7.7.1. 变量的作用域 1. 变量按作用域:分为全局变量和局部变量 2. 区别:见下表 全局变量(外部变量) 局部变量(内部变量) 定义位置 函数体外 函数体内 作用域 从定义处到文件结束 从定义处到本函数结束 举例 所有在函数体外定义的变量 (1) 所有在函数体内定义的变量 (2)形式参数 注意 与局部变量同名的处理 不同函数中同名局部变量互不干扰 关于局部变量的作用域还要说明以下几点: 主函数中定义的变量也只能在主函数中使用,不能在其他函数中使用。同时,主函数中也不能使用其他函数中定义的变量。因为主函数也是一个函数,它与其他函数是平行关系。 允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。 在复合语句中也可定义变量,其作用域只在复合语句范围内。 对于全局变量的几点说明: 外部变量定义必须在所有的函数之外,且只能定义一次。其一般形式为 [extern] 类型说明符 变量名,变量名,…; 外部变量可加强函数模块之间的数据联系,但是又使函数要依赖这些变量,因而使函数的独立性降低。从模块化程序设计的观点来看这是不利的,因此在不必要时尽量不要使用全局变量。 在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。 课堂练习1:分析下面的程序的运行结果。 void f1( ) { int t=2; a *= t; b /= t; } void main( ) { int a, b; printf(”Enter a,b:”); scanf(”%d,%d”, &a, &b); f1( ); /* 调用函数f1( ) */ printf (”a=%d,b=%d ”, a, b); } 编译程序会提示出错: undefined symbol ‘a’ 和 undefined symbol ‘b’ 。 为什么? 课堂练习2:分析下面的程序的运行结果 #include <stdio.h> int a=2,b=4; /*a,b为全局变量*/ void f1( ) { int t1,t2; t1 = a * 2; t2 = b * 3; b = 100; printf (” t1=%d,t2=%d ”, t1, t2); } void main() { int b=4; f1( ); printf (” a=%d,b=%d ”, a, b); } 程序输出结果为: t1=4,t2=12 a=2, b=4 结论: 全局变量与局部变量同名时,局部变量的作用域屏蔽全局变量 7.7.2 变量的存储特性 变量的 存储特性 变量的生存期 变量的存储类型 变量的存在时间,即变量的存在性。 变量存放的存储媒介,如存储器、外存储器和CPU的通用寄存器。 变量 (按存在时间) 静态 存储变量 (static) 动态 存储变量 (auto) 生存期为程序执行的整个过程,在该过程中占有固定的存储空间,也称永久存储。 只生存在某一段时间内 函数的形参、函数体或分程序中定义的变量,只有当程序进入该函数或分程序时才分配存储空间,函数/分程序执行完后,变量的存储空间又被释放。 变量属性 数据类型 存储特性 C语言变量的存储特性可分四类: 自动型(auto)、静态型(static)、外部型(extern)和寄存器型(register)。 完整的变量定义: [存储特性] [数据类型] 变量名; 自动型变量 [auto] 类型标识符 变量列表;常常可以缺省auto。 函数内定义的局部变量、函数的形式参数和函数体内分程序的局部变量。 随函数的调用而存在,随函数的返回而消失,它们在一次调用结束到下一次调用开始之间不再占有存储空间。 作用域局限于所定义的函数,其生存期就是函数的生存期,在一个函数中引用另一个函数的自动型变量的值是错误的。 外部型变量 “外部型变量”,是相对于在函数“内部”说明的变量而言的,它们在函数外部定义。 外部型变量又称为全局变量,在编译时分配存储单元。 若变量的定义与引用分别处于不同的源文件中,即将变量的作用域延伸到其它的源文件,则需要在引用该变量的源文件中对它进行声明,源文件或源文件中的函数才能引用它。 若变量的定义与引用处于同一源文件(即全局变量),在该源文件的不同函数中可以通过变量名对这种变量进行直接引用,作用域在整个源文件。 外部型变量的声明形式: extern 类型标识符 变量名; 在引用外部型变量的文件中不会为其分配内存空间。 外部型变量生存期为整个程序的运行期。 void main() { … /*在函数main中引用变量a不必声明*/ } extern int a; /*声明变量a为外部型变量*/ void fac(int n) { … a=a*n;/*函数fac外已声明a为外部变量,函数fac可以引用a*/ … } int a=1; /* 在s.c文件定义了全局变量a */ void fun() { … /*在函数fun中引用变量a不必声明*/ } /*源文件s.c*/ /*源文件d.c*/ 例如: 静态型变量 静态型变量是指在编译时分配存储空间的变量。 static 类型标识符 变量列表; 局部静态变量 全局静态变量 函数内部定义的静态变量 作用域与自动型变量相同 当所在的函数执行结束后,静态变量所占内存单元并不释放,其值仍然保留 函数外部定义的静态变量 在程序中凡未指明存储类型的全局变量均为全局静态型变量 作用域仅限所在的源程序文件 int f(int a) { int b=0; static int c=3; b++;c++; printf(" %5d%5d%5d ",a,b,c); return(a+b+c); } void main() { int a=2,k; for(k=0;k<3;k++) printf("%5d ",f(a)); } 课堂练习3:分析下面的程序的运行结果。 运行结果为: 1 4 7 2 1 5 8 2 1 6 9 寄存器型变量 变量 (按使用的 存储媒介) 内存 变量 寄存器 变量 使用CPU中的寄存器来存取变 量的值 前面所介绍的变量都为内存变量 由编译程序在内存中分配存储单元 变量的存取在内存储器中完成。 寄存器处在CPU的内部 可避免CPU频繁访问存储器, 从而提高程序的执行速度。 数据 内存 运算器 运算器 结果 控制器 数据 寄存器 寄存器型变量 不能定义为全局变量 只限于整型、字符型和指针型局部变量。 不可以定义为静态局部变量。 只能为动态变量 一般只允许同时定义两个寄存器变量。 register 类型名 变量名; 寄存器型变量的定义形式: register int a; register char b; $$

资源预览图

7.6  数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)
1
7.6  数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)
2
7.6  数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)
3
7.6  数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)
4
7.6  数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)
5
7.6  数组作为函数的参数(课件)-《 C语言程序设计》同步教学(电子工业出版社)
6
由于学科网是一个信息分享及获取的平台,不确保部分用户上传资料的 来源及知识产权归属。如您发现相关资料侵犯您的合法权益,请联系学科网,我们核实后将及时进行处理。