C语言,第8章 数组做函数参数
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
之前哪些地方涉及过“地址”这个概念
1、输入的时候。
scanf(“%d ”, &a);
2、数组名。
int a[10], b[10];
a = b; //错误,为什么
一维数组做函数参数
• 在调用函数时,如果被调函数的形参是一维 数组,则对应的实参是一个内存单元的地址 ,实参数组和形参数组共享一段内存。
变量的存储类别 一、动态存储方式与静态存储方式
⒈ 从变量的作用域(空间)角度分: 全局变量和局部变量 ⒉ 从变量存在的时间(生存期)来分: 静态存储方式和动态存储方式 ⒊ 静态存储方式 定义:在程序运行期间分配固定存储空间的方式。
⒋ 动态存储方式
定义:在程序运行期间根据需要进行动态分配存储空 间的方式。即:在函数调用时开始分配动态存储空间,函数 结束时释放这些空间。
int b,c;
…… } }
int b,c;
……
2. 全局变量
全局变量:一个源文件可以包括一个或若干个函数。在函
数内部定义的变量是局部变量,在函数之外定
义的变量称为外部变量。也称全局变量或全程 变量。 全局变量可以为本文件中的其它函数所共用,其有效 范围为从定义变量的位置开始到本源文件结束。
例如: int p=1,q=5; float f1(int a) { int b,c; …… } char c1,c2; char f2(int x,int y) { int i,j; …… } main() { int m,n; …… }
int search(int a[], int n, int m) { int weizhi = -1, i;
for (i=0; i<n; i++) { if (a[i] == m) { weizhi = i; break; } } }
return weizhi;
程序举例
P817.C 程序的功能是:从键盘输入一行可带空格的 字符串(约定:字符数≤127字节),调用函数将该字 符串逆序存放,然后输出该字符串。
void nixu(char a[]) { int i, j; char tmp; for (i = 0, j = strlen(a) - 1; i < j; i++, j--) { tmp = a[i]; a[i] = a[j]; a[j] = tmp; }
}
二维数组做函数参数
• 在调用函数时,如果被调函数的形参是二维数组,
第 8讲 函
数_2
内 容 提 要
•
•
•
•
一维数组做函数参数 二维数组做函数参数 变量的作用域和存储类别(理论性 知识) 进一步理解函数的递归调用和递归 算法的应用
回顾上周内容
怎样编写自定义函数?
怎样调用自定义函数?
函数的格式
函数值类型 函数名(形式参数)
{ 函数体 } 说明:
• 如果函数没有函数值,函数值类型为void • 如果函数有函数值,函数值类型为某种数据类型,函数值由 return语句返回; • 如果函数没有形式参数,表示为void • 如果函数有形式参数,则每一个形参的说明均为: 数据类型 形参名 如果有多个形参,用逗号分隔。
for (i=0; i<n; i++) { printf("%d ", a[i]); }
}
程序举例
P243.C 程序的功能是:从键盘分别读入5个数到arrA 中、8个数至arrB中,然后分别调用自定义函数计算 数组arrA和arrB各元素的平均值、再输出平均值。
float average(int a[], int n) { int i, sum = 0;
函数总结
1、实参与形参的个数相等,类型一致;
2、实参可以是变量、表达式、常数,实参必须有确
定的值;
3、在调用函数时,如果被调用函数的形参是变量,
实参和形参分别拥有各自的内存空间,实参将值传递
给对应的形参,形参值的改变不影响实参;
4、如果函数调用在前,函数定义在后,则在调用函
数前必须对函数进行原型声明。
则对应的实参是一个内存单元地址,实参数组和形
参数组共享一段内存。
• 在函数中对形参数组定义时,可以指定每一维的大
小,也可以省略第一维的大小说明,但不能只指定
第一维而省略第二维。例如:
int array[3][4]; int array[ ][10]; ( 正确!) int array[ ][ ]; int array[3][ ]; ( 错误!)
例如:
对静态局部变量: static int a; (a=0) 对自动变量: int a; (a的值不确定)
static float b;
static char c;
(b=0.0)
(c=„\0‟)
float b;
char c;
(b的值不确定)
(c的值不确定)
递归算法 一、递归求n!
递归算法的两个必要条件:
说明:关键字“auto”可以省略不写(隐含指定为自动变量)。
例如: auto int b,c=3; int b,c=3;
三、 用static声明局部变量
静态局部变量:
⒈ 特点:函数中的局部变量的值在函数调用结束后不消失而
保留原值,即其所占用的存储单元不释放,在下一 次调用该函数时,该变量已有值,就是上一次函数 调用结束时的值。 ⒉ 声明:(用关键字static进行声明)
(1)n的求解必然和前面n-1的求解,甚至n-2…的求解有联系,即是 和前一(或前几)层之间存在递归规律 (2)递归到前面的某一层一定有确定的返回值或结束继续递归
for (i=0; i<n; i++) { sum = sum + a[i]; }
return (float)sum/n; }
程序举例
P244.C 程序的功能是:从键盘分别读入5个数到arrA 中、8个数至arrB中,再读入一个欲查找的数searchVal ,然后分别调用自定义函数在数组arrA和arrB中查找 searchVal所在位臵的下标(不考虑在数组中存在多个 searchVal的情况)、输出查找结果。
这些空间。即:动态分配和释放。
二、 auto变量(用auto声明的局部变量)
自动变量: 自动变量用关键字auto作存储类别的声明。
特点:
在调用该函数时,系统给变量分配存储空间,函数调用结 束时自动释放这些空间。
默认的局部变量都是auto类型
例如:
源自文库
int f(int a)
{ auto int b, c=3; …… }
• 在函数中对形参数组定义时,可以省略数组
的大小说明。例如, int arr[ ]
程序举例
P241.C 程序的功能是:从键盘分别读入5个数到arrA 中、8个数至arrB中,然后分别调用自定义函数输出 数组arrA和arrB的各元素。
void printArray(int a[], int n) { int i;
程序举例
P818.C 程序的功能是:找出任意的一个m×n矩阵每 一行上的最大值的列下标并按示例格式要求显示。
void max(int a[N][N], int hang, int lie) { int i, j, maxvalue, maxlie; for (i=0; i<hang; i++) { maxvalue = a[i][0]; maxlie = 0; for (j=1; j<lie; j++) { if (a[i][j] > maxvalue) { maxvalue = a[i][j]; maxlie = j; } } printf("The max value in line %d is %d\n", i, maxlie); } }
数范围内部定义的变
量,称为局部变量。 它只在本函数范围内 有效,即:只有在本 函数内才能使用它们,
在此函数以外不能使
用这些变量。
几点说明: (1) 主函数main中定义的变量也只在主函数中有效。主函数也 不能使用其它函数中定义的变量。
(2) 不同函数中可以使用相同名字的变量,它们代表不同的对
象,互不干扰。 例如: float f1(int a) { char f2(int a, int y) {
如果在同一个源文件中,全局变量与局部变量同名,则在 局部变量的作用范围内,全局变量被“屏蔽”,即它不起作 用。 例 外部变量与局部变量同名。 #include <stdio.h> int a=3,b=5; int max(int a,int b) { 形参a、b的作 int c; c=a>b?a:b; 用范围 return(c); 全局变量a、b } 的作用范围 int main(void) { int a=8; 局部变量 printf(“max=%d”,max(a,b)); a的作用 return 0; 范围 }
}
}
变量的作用域(局部变量和全局变量)
1. 局部变量
局部变量:在一个函
#include <stdio.h> int max( int x, int y ); int main(void) { int a, b, c; scanf(“%d,%d”,&a,&b); c=max(a,b); printf(“max=%d\n”,c); return 0; } int max( int x, int y ) { int z; if(x>y) z=x; else z=y; return(z); }
程序举例
P823.C 程序的功能是:将m(2<=m<=20)行m列的二 维数组arrayA中的最后一行放到二维数组arrayB的第0 列中,把二维数组arrayA中的第0行放到二维数组 arrayB的最后一列中,二维数组arrayB中的其他数据 和arrayA一致。
void zh(int a[20][20], int b[20][20], int n) { int i, j; for (i=0; i<n; i++) { for (j=0; j<n; j++) { b[i][j] = a[i][j]; } } for (i=0; i<n; i++) { b[i][n-1] = a[0][i]; b[i][0] = a[n-1][i];
函数的调用
要让计算机执行一个函数,就必须对函数进行调用。 说明:
•
调用库函数,需要在源程序最前面通过include预编译指令
•
•
引入对应库函数的头文件 调用库函数的关键是遵守函数原型定义的约定 • 使用正确的函数名 • 传递的实参在数量,类型和顺序必须和形参一致 • 如果有函数值,注意返回值的类型 函数可以嵌套调用,递归调用,但是不能循环调用。
⑴ 静态存储方式的数据: ☆ ☆ 全局变量 静态局部变量
特点:在程序编译时分配内存单元,在整个程序执行期间占
据固定存储单元,直到程序执行完毕才释放。 ⑵ 动态存储方式的数据: ☆ 自动变量 ☆ 函数的形式参数
☆ 函数调用时的现场保护和返回地址等。
特点:函数调用时分配动态存储空间,函数调用结束时释放
static 类型标识符
例如: static float a;
变量名
例 考察静态局部变量的值。 #include <stdio.h>
int f(int a) i=0 { 函数调用开始 int b = 0; a b c static int c = 3; 2 0 3 b = b + 1; c = c + 1; return (a + b + c); } int main(void) i=1 { 函数调用开始 int am = 2, i; a b c for(i=0; i<2; i++) { printf(“%d”, f(am)); } 2 0 4 return 0; }
全局变 量c1,c2 的作用 范围
全局变 量p,q的 作用范 围
例如:
#include <stdio.h>
int a, b; void f1(void); int main(void) { a=2, b=4; f1( ); printf(“a=%d, b=%d\n”, a, b); return 0; } void f1(void) { int t1, t2; t1=a*2; t2=b*3; b=100; printf(“t1=%d, t2=%d\n”, t1, t2) }
函数调用结束 a b c 2 1 4
函数调用结束 a 2 b 1 c 5
运行结果:?
关于静态局部变量的说明: ☆ 如在定义静态局部变量时不赋初值,编译时自动赋初值0 (对数值型数据)或空字符(对字符变量)。而对自动变
量来说,如果不赋初值,它的值是一个不确定的值。
☆ 静态局部变量仍属于局部变量,其它函数不能引用它。