马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 6bingame 于 2024-12-4 17:24 编辑
内部函数和外部函数,main() 函数
内部函数
如果一个源文件中定义的函数只能被本文件中的函数调用,而不能被同一源程序其他文件中的函数调用,这种函数称为内部函数。
定义内部函数的一般形式是:
static 类型说明符 函数名([形参表])
其中,“[]"中的部分是可选项,即该函数可以有参函数,也可以是无参函数。如果为无参函数,形参表为空,但括号必须要有。
例如:
static int f(int a,int b); //内部函数前面加 static 关键字
{
......
}
说明:f() 函数只能被本文件中的函数调用,在其他文件中不能调用此函数。
内部函数也称静态函数。但此处静态 static 的含义并不是指存储方式,而是指对函数的调用范围只局限于本文件,因此在不同的源文件中定义同名的内部函数不会引起混淆。通常把只由同一个文件使用的函数和外部变量放在一个文件中,前面加上 static 使之局部化,其他文件不能引用。
外部函数
外部函数在整个源程序中都有效,只要定义函数时,在前面加上 extern 关键字即可。其定义的一般形式为:
extern 类型说明符 函数名(<形参表>)
例如:
extern int f(int a,int b)
{
......
}
如果定义为外部函数,不仅可被定义它的源文件调用,而且可以被其他文件中的函数调用,即其作用范围不只局限于本源文件,而是整个程序的所有文件。在一个源文件的函数中调用其他源文件中定义的外部函数时,通常使用 extern 说明被调函数为外部函数。
题1:调用外部函数。
解://文件1
#include<stdio.h>
int main()
{
int a,b;
printf("a=");
scanf("%d",&a);
printf("b=");
scanf("%d",&b);
printf("\n");
add(a,b);
printf("\n");
sub(a,b);
return 0;
}
//文件2
#include<stdio.h>
extern add(int c,int d) //定义外部函数 add(),extern 可省略不写
{
printf("%d+%d=%d\n",c,d,c+d);
}
//文件3
#include<stdio.h>
extern sub(int c,int d) //定义外部函数 sub(),extern 可省略不写
{
printf("%d-%d=%d\n",c,d,c-d);
}
例题分析:
本例题的整个程序是由3个文件组成的,每个文件包含一个函数。主函数是主控函数,使用了4个函数的调用语句。其中,printf()、scanf()是库函数,另外两个是用户自定义的函数,它们都定义为外部函数。在 main() 函数中,使用 extern 说明在 main() 函数中用到的 add() 和 sub() 都是外部函数。
main() 函数
从开始学C语言,我们就一直使用 main() 函数,都知道一个C程序必须有并且只能有一个主函数,C程序的执行总是从 main() 函数开始的。
归纳起来,main() 函数在使用过程中应该注意以下几点。
(1)main() 函数可以调用其他函数,包括本程序中定义的函数和标准库中的函数,但其他函数不能反过来调用 main() 函数。main() 函数也不能调用自己。
(2)之前用到的 main() 函数都没有在函数头中提供参数。其实,main() 函数可以带有两个参数,其一般形式是:
int main(int argc, char *argv[])
{
函数体
}
其中,形参 arge 表示传给程序的参数个数,其值最少是1;而 argv 则是指向字符串的指针数组。
题2:带参数的 main() 函数。
解:#include<stdio.h>
int main(int argc,char *argv[])
{
int count;
printf("The command line has %d arguments:\n",argc-1);
for(count=1;count<argc;count++) //依次读取命令行输入的字符串
printf("%d:%s\n",count,argv[count]);
}
例题分析:
从本题可以看出,程序从命令行中接受到3个字符串,并将它们存放在字符串数组中,其对应关系为:
argv[0]------>I
argv[1]------>am
argv[2]------>happy!
argc 的值即是参数的个数,程序在运行时会自动统计。
需要注意的是,在命令行的输入都将作为字符串的形式存储于内存中。也就是说,如果输入一个数字,那么要输出这个数字,就应该用 %s 格式,而非 %d 格式或者其他。
main() 函数也有类型。如果它不返回任何值,就应该指明其类型为 void;如果默认其类型为 int。那么在该函数末尾应由 return 语句返回一个值,例如 0.
综合应用——用截弦法求方程的根
题3:编写一个程序,实现用截弦法求方程 x³-5x²+16x-80=0 在区间 [-3,6] 内的根。
解:#include<stdio.h>
#include<math.h> //下面程序中使用了 pow 等函数,需要包含头文件 math.h
float func(float x) //定义 func 函数,用来求函数 func(x)=x*x*x-5*x*x=16x-80
{
float y;
y=pow(x,3)-5*x*x+16*x-80.0f; //计算指定 x 值的 func(x) 的值,赋给 y
return y; //返回 y 的值
}
float point_x(float x1,float x2) //定义 point_x 函数,用来求出弦在 [x1,x2] 区间内与 X 轴的交点
{
float y;
y=(x1*func(x2)-x2*func(x1))/(func(x2)-func(x1));
return y;
}
float root(float x1,float x2) //定义 root 函数,计算方程的近似根
{
float x,y,y1;
y1=func(x1); //计算 x 值为 x1 时的 func(x1) 函数值
do{ //循环执行下面的语句
x=point_x(x1,x2); //计算 x 点对应的函数值
y=func(x); //计算 x 点对应的函数值
if(y*y1>0) //func(x) 与 func(x1) 同号,说明根在区间 [x,x2] 之间
{
y1=y; //将此时的 y 作为新的y
x1=x; //将此时的 x 作为新的 y
}
else //否则将此时的 x 作为新的 x
{
x2=x;
}
}while(fabs(y)>=0.0001);
return x; //返回根 x 的值
}
void main()
{
float x1=-3,x2=6;
float t=root(x1,x2);
printf("方程的根为:%f\n",t);
}
例题分析:
本题用截弦法求方程的根,方法如下。
(1)取两个不同的点 x1 和 x2 ,如果 f(x1)、f(x2) 符号相反,则 (x1,x2) 区间内必有一个根;但如果 f(x1)、f(x2) 符号相同,就应该改变 x1 和 x2 直到上述条件成立为止。
(2)连接 f(x1)、f(x2) 两点,这个弦就交 x轴于 x处,那么求 x点的坐标就可以用下面的公式求解。x=(x1*func(x2)-x2*func(x1))/(func(x2)-func(x1)),由此可以进一步求由 x点对应的 f(x)。
(3)如果 f(x)、f(x1) 同号,则根必定在 (x,x2) 区间内,此时将 x 作为新的 x1。如果 f(x)、f(x1) 异号,表示根在 (x1,x) 区间内,此时可将 x 作为新的 x2。
(4)重复步骤 (2)、(3),直到 |f(x)|< ε 为止,ε 为一个很小的数,程序中设为 0.0001,此时可认为 f(x) ≈ 0。 |