6bingame 发表于 2024-12-4 17:24:20

每日一学10

本帖最后由 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);
}


例题分析:
从本题可以看出,程序从命令行中接受到3个字符串,并将它们存放在字符串数组中,其对应关系为:
argv------>I
argv------>am
argv------>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 函数,用来求出弦在 区间内与 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) 同号,说明根在区间 之间
      {
            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。

天天都可乐 发表于 2024-12-4 19:06:36

好难 新手看不懂
页: [1]
查看完整版本: 每日一学10