returns;
}
main()
{intx,a[]={1,2,3,4,5,6,7,8,9};
x=f(a,3,7);
printf("%d\n",x);
}
A)10
B)18
C)8
D)15
答案:
A
函数的调用
解析:
在mainO函数中定义了一个变量x,以及一个有9个元素的数组a,并且每个元素分别赋初值为1、2、3、4、5、6、7、8和9。
执行函数调用f(a,3,7),把a的首地址赋给形参b,把3和7分别赋给形参m和n。
在f()函数中,for循坏执行了2次:
第一次,i的值为3,相当于执行了语句“s二s+b[3]”,b⑶的值就是a[3]的值4,故s的值变为4;第二次,i值为5,相当于执行了语句“s二s+b[5];”,b[5]的值为6,故s的值变为10。
把s作为函数值返回并赋值给X。
函数调用的一般形式:
函数名(实参表列);
若实参表列包含了两个以上实参,各参数之间用逗号分隔。
实参的个数应与形参的个数相同,且按顺序对应。
若调用的是无参函数,则不用“实参表列”,但括号不能省略。
函数调用的一般方式:
(1)函数语句:
函数调用单独成为一条语句。
例如:
puts(strl);/*调用系统提供的标准函数*/swap(xl,x2);/*调用用户自定义的函数swap*/以语句的形式调用的函数一般只需要完成一定的操作而不必有返回值。
(2)函数表达式:
函数出现在一个表达式中,例如:
if(strcmp(sl,s2)>0)…/*函数调用位于条件表达式式中*/
n_max=max(x,y,z);/*函数调用位于赋值语句右侧的表达式中*/
因为耍参与表达式中的计算,所以要求函数有一个确定的返回值提供给表达式。
(1)
(2)函数参数:
函数调用结果作为另外一个函数的实参。
例如:
printf(“%d\n”,max(x,y,z));/*max函数是printf函数的部分参数*/
funl(fun2(t));/*fun2函数是funl函数的实参*/
被调用函数必须返回一个确定的返回值,提供给主调函数作为实际参数,一进行后续操作。
函数的声明:
(1)函数的声明
用户(自定义)函数一般应定义在前,调用在后。
若被调函数出现调用在前,定义在后时,则应在主调函数的适当位置,对被调函数作声明。
函数声明的一般格式为:
函数类型函数名(参数类型1,参数类型2,…)
或
函数类型函数名(参数类型1参数名1,参数类型2参数名2,…)
注意:
此处的参数名完全是虚设的,即不必与函数首部的形参名一致,又可以与程序中任意用户标示符同名,实际上,这里的参数名常常省略。
函数声明语句屮的“函数类型”必须与函数返回值的类型一致。
函数的嵌套调用
C语言的函数之间都是独立的、平行的,函数之间没有从属关系,即不能在一个函数内定义另外一个函数。
但可以嵌套调用,即函数调用中又存在调用。
如函数1调用函数2,函数又调用函数3…每个函数既可以被其它幣数调用,也可以调用其它幣数。
函数的递归调用
函数的“递归调用”是指一个函数直接调用自己(即直接递归调用)或通过其它函数间接地调用自己(即I'可接递归调用)。
•试题解析
1.下面程序的运行结果是:
O
fun(intt[],intn)
{inti,m;
if(n==l)returnt[0];
else
if(n>=2){m=fun(t,n-1);returnm;}
}
main()
{inta[]={11,4,6,3,8,2,3,5,9,2};
printf("%d\rT,fun(a,10));
}
解析:
此题涉及函数的调用和if语句。
程序先执行第二个if语句,然后在执行第一个if语句,最后用return返回数值。
答案11
2.有以下程序
intfun(intn)
{if(n==l)return1;
else
return(n+fun(nT));
}
main()
{intx;
scanf("%d",&x);x=fun(x);printf("%d\n",x);
}
执行程序吋,给变量X输入10,程序的输出结果是(A)
A)55B)54
C)65D)45
解析:
本程序考察的是函数的递归调用,在调用一个函数的过程中乂出现直接或间接地调用该函数本身,称为函数的递归调用,执行结果为1+2+3+4+5+6+7+8+9+10二55。
3.有以下程序
voidf(inta[],inti,intj)
{intt;
if(i{t=a[i];a[i]=a[j];a[j]=t;
f(a,i+1,j-1);
}
}
main()
{inti,aa[5]={l,2,3,4,5};
f(aa,0,4);
for(i=0;i<5;i++)printf("%d,“,aa[i]);printf("\n");
}
执行后输出结果是
A)5,4,3,2,1,B)5,2,3,4,1,C)1,2,3,4,5,D)1,5,4,3,2,
答案:
A
解析:
f(aa,0,4)调用是地址双向传递.i=0,j=4,交换aa=[0]、aa[4]的值使aa[5]={5,4,3,2,1);接着递归调用f(a,i+1,j-l)即f(a,1,3),交换aa[l]、aa=[3]的值使aa[5]={5,4,3,2,1};接着递归调用f(a,i+1,j-l)即f(a,2,2),由于i=j=2,退出函数调用,依次输出aa[5]的数组元素为〃5,4,3,2,1,〃答案:
A
4.以下程序的输出结果是。
main()
{intx=0;
sub(&x,&1);
printf("%d\n",x);
}
sub(int*a,intn,intk)
{if(k<=n)sub(a,n/2,2*k);
*a+二k;
}
解析:
在主函数中定义了一个变量x并赋初值0,然后执行函数调用语句,该语句的执彳亍过程为sub(&x,8,1)调用sub(&a,4,2),sub(&a,4,2)调用sub(&a,2,4),sub(&a,2,4)屮由于2<4,所以if后面括号里的判断为假,递归结束,执行其后的*a+二k;语句此时x=x+k=0+4=4,回退到上一层调用函数sub(&x,4,2)中,执行后面的语句,x=x+k=4+2=6,再回推到最上一层调用函数sub(&x,8,1)执行后面的语句,x=x+k=6+l=7,所以最后输出7。
G.
考点°变量的作用域、局部和全局变量
变量的作用域:
变量的作用域指(从空间角度来看)变量的有效范围或者变量的可见性。
变量定义的位置决定了变量的作用域。
变量从作用域的角度可以分为:
局部变量,全局变量。
局部变量:
所谓“局部变量”指在一定范围内有效的变量。
C语言中,在以下各位置定义的变量均属于局部变量,其作用域也不同。
(1)在函数体内定义的变量,在本函数范围内有效,即其作用域只局限在本函数体内。
(2)在复合语句内定义的变量,仅在本复合语句范围内有效。
(3)有参函数中的形式参数也是局部变量,只在其所在的函数范围内有效。
说明:
(1)局部变量所在的函数被调用或执行时,系统临时给相应的局部变量分配存储单元,一旦函数执行结束,则系统立即释放这些存储单元。
(2)因为所有局部变量的定义都位于函数中,且从宏观角度来说,局部变量的作用域也都局限于函数内,所以局部变量也可称作内部变量。
(3)不同函数中和不同的复合语句中可以使用(即定义)同名变量。
因为它们的作用域不同,程序运行时在内存中占据不同的存储单元,各自代表不同的对象,所以它们之间互不干预。
全局变量:
所谓“全局变量”是指在函数之外定义的变量。
全局变量的定义位置可以在所有函数Z前、各个函数之间。
当然从理论上讲,也可以在所有函数之后(但实际应用中很少用)。
全局变量作用域:
从定义全局变量的位置起到本源程序结朿为止。
说明:
(1)因为全局变量的定义位置都在函数Z外(且作用域范围较广,不局限于一个函数内),所以全局变量又可称为外部变量。
(2)使用全局变量可以增加各个函数之间数据传输的渠道,即在某个函数中改变一全局变量的值,就可能影响到其它函数的执行结果。
但它会使函数的通用性降低,使程序的模块化、结构化变差,所以应慎用、少用全局变量。
(3)全局变量可以和局部变量同名,当局部变量有效时,同名的全局变量不起作用。
•试题解析
1.程序如下:
main()
{inti=5;
funl(i/2);printf("i=%d\rT,i);
funl(i=i/2);printf("i=%d\rT,i);
funl(i/2);printf("i=%d\n",i);
fun2(i);printf("i=%d\n",i);
}
funl(inti)
{i二i<=2?
15:
0;
return(i);
}
fun2(inti)
{i二(i%i)*((i*i)/(2*i)+4);
printf(/zi=%d\n",i);
return(i);
解析:
该程序运行结果为:
i二5
i=2
i=2
i=0
i=2
该例中三个函数main、funl和fun2中的局部变量均是i,要注意它们各自的作用域。
2.程序如下:
intd=l;
fun(intp)
{intd二5;
d+二p++;
printfd);
}
main()
{inta二3;
fun⑶;
d+=a++;
printf("%d\n",d);
}
以上程序运行后,输出结果是
A)84B)99C)95D)44
解析:
由程序可见,全局变量d和fun函数中定义的局部变量d同名了。
根据它们的作用域及使用规律可知,在fun函数中局部变量d起作用,全局变量d不起作用,在main函数中全局变量d起作用。
故该题结果应选A)。
3.程序如下:
intxl=30,x2=40;
main()
{intx3=10,x4=20;
sub(x3,x4);
sub(x2,xl);
printf("%d,%d,%d,%d\rT,x3,x4,xl,x2);
}
sub(intx,inty)
{xl=x;x=y;y=xl;}
该程序的运行结果为:
10,20,40,40
变量的存储类别(生存期)
解析:
该程序在运行过程中,全局变量xl发生两次变化。
第一次是调用sub函数后,xl变为10,第二次也是调用sub函数后,xl变为40。
从变量的作用域(即空间角度)来看,变量可分为局部变量和全局变量。
若从变量存在的吋I'可长短(即吋间角度)来划分,变量还可以分为:
动态存储变量、静态存储变量。
变量的存储方式决定了变量的生存期。
动态存储方式:
在程序运行期间根据需要为相关的变量动态分配存储空间的方式。
动态存储方式主要有:
(1)自动型存储方式(auto)
(2)寄存器型存储方式(register)
自动型存储方式(auto)
白动型存储方式(auto)是C语言中使用最多的存储方式,也是系统默认的存储方式。
由自动型存储的变量也称为自动变量。
自动变量定义的一般格式为:
[auto]类型说明符变量名1[,变量名2,…];
其屮,auto为自动存储类别符,它可以省略。
当其缺省时,系统默认为autoo比如在函数体内定义变量时,下面两种写法是等价的。
intx,y,z;
autointx,y,z;
说明:
(1)自动变量属于局部变量范畴。
通常情况下,其作用域局限于定义它的函数范围内。
(2)C语言允许在复合语句内定义白动变量,此时,其作用域仅局限于该复合语句内。
(3)当自动变量所在函数(或复合语句)执行后,系统即动态地为相应的自动变量分配存储单元。
(4)自动变量的生存期为该变量所在的函数(或复合语句)的执行时间,当函数(或复合语句)执行结束后,自动变量已失效,即其存储单元被系统释放掉了。
所以,其原来的值不能保留下来。
若对同一函数进行再次调用时,系统会对相应的白动变量重新分配存储单元。
寄存器型存储方式(register)
是C语言中使用较少的一种存储方式。
该存储方式是将相关变量的值存储在CPU的通用寄存器内。
从通用寄存器内读取数据比由内存中读取数据要快得多。
因此,对于一些需要反复操作的数据,可使用寄存器型存储方式。
由该存储方式存储的变量也可称为寄存器变量。
寄存器变量定义的一般格式为:
register类型说明符变量名1[,变量名2,…];
其中,register是寄存器型存储方式类别符,不可省略。
寄存器变量也属于局部变量范畴。
静态存储方式:
在程序编译时就给相关的变量分配固定的存储空间(在程序运行的整个期间内都不变)的方式。
静态存储方式主要有:
(1)静态存储的局部变量(static)
(2)静态存储的全局变量
静态存储的局部变量:
静态存储方式存储的局部变量也可称为静态局部变量。
该类变量的定义格式为:
static类型说明符变量名[二初始化值][,…];
其中,static是静态型存储方式类别符,不可省略。
(1)静态局部变量的存储空间是在程序编译时由系统分配的,且在程序运行的整个期间都固定不变。
因此,该类变量在其所在函数调用结束后仍然可以保留变量值。
(2)静态局部变量的初值是在程序编译时一次性赋予的,即在程序运行期间不再赋初值。
如上例在程序编译时给变量a赋予10,对未给定初值的变量b,C编译系统自动给它赋0值。
若变量b为字符型变量,则C编译系统自动给它赋'\x0'(即ASCH代码为0的字符)。
静态存储的全局变量
全局变量全部是静态的,不必用static修饰。
如果全局变量用static修饰,并不是限定全局变量为静态的,而是声明全局变量只能用于本模块(本文件),不能被其他文件所引用。
也就是说,不加static声明的全局变量是可以被其他文件所引用的。
即:
这两种形式所定义的全局变量都是静态存储方式,只是作用范围不同而已。
用extern声明全局变量
全局变量(即外部变量)的作用域是从定义的位置起到本文件的末尾止。
若在全局变量作用域之外采欲引用全局变量,则要在引用前用extern來声明全局变量,以扩大全局变量的作用域。
内部函数
所谓“内部函数”是指只能被本文件中的各个函数所调用,不能被其他文件中的函数所调用的一类函数而言。
它们必须用static来说明,其一般格式为:
static函数类型说明符函数名(形式参数)
说明:
(1)内部函数又可称为静态函数。
它的使用范围仅限于定义它的源程序文件内。
对其他文件而言,它是屏蔽的、不可见的。
因而,内部函数的保密性很好。
(2)不同文件中的内部函数可以同名,因它们的作用范围不同,不会造成混淆。
内部函数的static不可省略。
外部函数
所谓“外部函数”是指可以被任何文件的任何函数所调用的一类函数。
它们可以用extern来说明,其一般格式为:
extern函数类型说明符函数名(形式参数)
说明:
(1)外部函数的extern可省略。
如果在定义函数时省略extern,则系统默认该函数是外部函数。
(2)外部函数可以被其他文件所调用。
当某文件需调用其他文件定义的外部函数时,需在该文件的适当位置(通常在其首部)用extern来声明所用的函数是外部函数。
•试题解析
1.在C语言中,形参的缺省存储类是
A)auto
B)register
C)static
D)extern
答案:
A
解析:
本题考核的知识点是定义函数时形参的缺省存储类。
在C语言屮,形参的缺省存储类为autOo
2.有以下程序
intfun(intx[],intn)
{staticintsum=O,i;
for(i=0;ireturnsum;
}
main()
{inta[]二{1,2,3,4,5},b[]={6,7,8,9},s二0;
s=fun(a,5)+fun(b,4);printf("%d\n",s);
}
程序执行后的输出结果是(C)
A)45B)50
060D)55
解析:
内部静态变量是始终存在的,当函数被调用退出后,内部静态变量会保存数据,再次调用该函数时,以前调用时的数值仍然保留着。
Fun5)的值是15,再次调用后simF15,所以Fun(b,4)=45,s二45+15二60。
3.以下程序的输出结果是
intx=3;
main()
{inti;
for(i=l;i<