📄 学c51的基础 12《 函 数 》.txt
字号:
量的地址, 当子函数中向相应的地址写入不同的数值之后, 也就改变了调用函数中相应变量的值, 从而达到了返回多个变量的目的。
例4:
#include<stdio.h>
void subfun(int *m, int *n); /*说明子函数*/
int main()
{
int i, j;
printf("i, j=?\n");
scanf("%d, %d", &i, &j); /*从键盘输入2个整数*/
printf("In main before calling\n", /*输出此2数及其乘积*/
"i=%-4d j=%-4d i*j=%-4d\n", i, j, i*j);
subfun(&i, &j); /*以传送地址的方式调用子函数*/
printf("In main after calling\n", /*调用子函数后输出变量值*/
"i=%-4d j=%-4d i*j=%-4d\n", i, j, i*j);
getch();
return 0;
}
void subfun(int *m, int *n)
{
*m=*m+2;
*j=*i-*j;
printf("In subfun after calling\n", /*子函数中输出变量值*/
"i=%-4d j=%-4d i*j=%-4d\n", *i, *j, *i**j);
}
上例中, *i**j表示指针i和j所指的两个整型数*i和*j之乘积。
另外, return语句也可以返回一个指针, 举例如下。
下例中先等待输入一字符串, 再等待输入要查找的字符, 然后调用match() 函数在字符串中查找该字符。若有相同字符, 则返
回一个指向该字符串中这一位置的指针, 如果没有找到,则返回一个空(NULL)指针。
例5:
#include<stdio.h>
char *match(char c, char *s);
int main()
{
char s[40], c, *str;
str=malloc(40); /*为字符串指什分配内存空间*/
printf("Please input character string:");
gets(s); /*键盘输入字符串*/
printf("Please input one character:");
c=getche(); /*键盘输入字符*/
str=match(c, s); /*调用子函数*/
putchar('\n');
puts(str); /*输出子函数返回的指针所指的字符串*/
getch();
return 0;
}
char *match(char c, char *s)
{
int i=0;
while(c!=s[i]&&s[i]!='\n') /*找字符串中指定的字符*/
i++;
return(&s[i]); /*返回所找字符的地址*/
}
三、用全程变量实现参数互传
以上两种办法可以在调用函数和被调用函数间传递参数, 但使用不太方便。如果将所要传递的参数定义为全程变量, 可使变量
在整个程序中对所有函数都可见。 这样相当于在调用函数和被调用函数之间实现了参数的传递和返回。这也是实际中经常使用的方
法, 但定义全程变量势必长久地占用了内存。因此, 全程变量的数目受到限制, 特别对于较大的数组更是如此。当然对于绝大多数
程序内存都是够用的。
例6:
#incluide<stdio.h>
void disp(void);
int m[10]; /*定义全程变量*/
int main()
{
int i;
printf("In main before calling\n");
for(i=0; i<10; i++){
m[i]=i;
printf("%3d", m[i]); /*输出调用子函数前数组的值*/
}
disp(); /*调用子函数*/
printf("\nIn main after calling\n");
for(i=0; i<10; i++)
printf("%3d", m[i]); /*输出调用子函数后数组的值*/
getch();
return 0;
}
void disp(void)
{
int j;
printf("In subfunc after calling\n"); /*子函数中输出数组的值*/
for (j=0; i<10; j++){
m[j]=m[j]*10;
printf("%3d", m[i]);
}
}
2.3 函数的递归调用
Turbo C2.0允许函数自己调用自己, 即函数的递归调用, 递归调用可以使程序简洁、代码紧凑, 但要牺牲内存空间作处理时的
堆栈。
如要求一个n!(n的阶乘)的值可用下面递归调用:
例8:
#include<stdio.h>
unsigned ling mul(int n);
int main()
{
int m;
puts("Calculate n! n=?\n");
scanf("%d", &m); /*键盘输入数据*/
printf("%d!=%ld\n", m, mul(m)); /*调用子程序计算并输出*/
getch();
retun 0;
}
unsigned long mul(int n)
{
unsigned long p;
if(n>1)
p=n*mul(n-1); /*递归调用计算n!*/
else
p=1L;
return(p); /*返回结果*/
}
运行结果:
calculate n! n=?
输入5时结果为:
5!=120
3. 函数作用范围
Turbo C2.0中每个函数都是独立的代码块, 函数代码归该函数所有, 除了对函数的调用以外, 其它任何函数中的任何语句都不
能访问它。例如使用跳转语句goto 就不能从一个函数跳进其它函数内部。除非使用全程变量, 否则一个函数内部定义的程序代码和
数据, 不会与另一个函数内的程序代码和数据相互影响。
Turbo C2.0中所有函数的作用域都处于同一嵌套程度, 即不能在一个函数内再说明或定义另一个函数。
Turbo C2.0中一个函数对其它子函数的调用是全程的, 即是函数在不同的文件中, 也不必附加任何说明语句而被另一函数调用,
也就是说一个函数对于整个程序都是可见的。
4. 函数的变量作用域
在Turbo C2.0中, 变是可以在各个层次的子程序中加以说明, 也就是说, 在任何函数中, 变量说明有只允许在一个函数体的开
头处说明, 而且允许变量的说明( 包括初始化 )跟在一个复合语句的左花括号的后面, 直到配对的右花括号为止。它的作用域仅在
这对花括号内, 当程序执行到出花括号时, 它将不复存在。当然, 内层中的变量即使与外层中的变量名字相同, 它们之间也是没有
关系的。
例9.
#include<stdio.h>
int i=10;
int main()
{
int i=1;
printf("%d\t, i);
{
int i=2;
pritnf("%d\t", i);
{
extern i;
i+=1;
printf("%d\t", i);
}
printf("%d\t", ++i);
}
printf("%d\n", ++i);
return 0;
}
运行结果为
1 2 11 3 2
从程序运行的结果不难看出程序中各变量之间的关系, 以及各个变量的作用域。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -