1.根据函数能否被其他源文件调用来区分:

  • 内部函数
    • static int fun( )
    • 只能被本文件函数调用
  • 外部函数
    • extern int fun( )
    • 定义函数时,表示函数可以供其他文件调用
    • 在需要调用此函数的文件中,用extern声明所用的函数时外部函数
    • 都可以省略关键字extern

2.预处理命令

  • 预处理命令不是C++语句
  • 预处理:在编译之前根据这些特殊的命令对程序进行处理,开始编译时已经不再包括预处理命令。
  • 3种预处理:
    • 宏定义
    • 文件包含
    • 条件编译

3.宏定义

  • define 标识符 字符串

    • 以一个指定的标识符来代表一个字符串
    • 例: #define PI 3.1415926
  • 编译程序将宏定义的内容认为是字符串,无任何实际的物理意义
  • 注意:

    • 宏展开只是一个“物理”替换,不做语法检查,不是一个语句,不加分号
    • define命令出现在函数外面,其有效范围为定义处至本源文件结束。可用#undef命令终止定义的作用域。

      1. #define G 9.8
      2. void main(void )
      3. {.....}
      4. # undef G
      5. int max(int a,int b)
      6. {...... }
    • 对程序中用双引号括起来的字符串内容,即使与宏名相同,也不进行置换。

    • 在进行宏定义中,可用已定义的宏名,进行层层置换。
  • 带参数的宏定义

    • define 宏名(参数表) 字符串

    • 例: ```cpp

      define S(a,b) a*b

      float x,y,area; cin>>x>>y; area=S(x,y); //area = x*y;
  1. - 按#define命令行中指定的字符串从左到右进行置换宏名,字符串中的形参以相应的实参代替,字符串中的非形参字符保持不变。
  2. ![批注 2020-08-09 101549.png](https://cdn.nlark.com/yuque/0/2020/png/2314091/1596953205116-ae843fa0-7b1b-423b-9342-12ebd716e7b0.png#align=left&display=inline&height=219&margin=%5Bobject%20Object%5D&name=%E6%89%B9%E6%B3%A8%202020-08-09%20101549.png&originHeight=292&originWidth=418&size=46887&status=done&style=none&width=314)
  3. **4.文件包含**
  4. - 文件包含:指一个源文件将另一个源文件的所有内容包括进来。
  5. - #include< xxx.h >
  6. - 到系统目录(存放C++系统的目录)中寻找要包含的文件,如果找不到就报错。
  7. - #include " xxx.h "
  8. - 首先到指定目录中寻找要包含的文件,如果没有则至系统目录寻找。
  9. **5.条件编译**
  10. - 用途:希望程序中一部分代码只在满足一定条件时才进行编译。
  11. -
  12. ```cpp
  13. #ifdef 标识符
  14. // 程序段1
  15. #else
  16. // 程序段2
  17. #endif
  18. #define DEBUG
  19. ......
  20. #ifdef DEBUG
  21. cout<<x<<'\t'<<y<<endl;
  22. #endif
  • 当标识符已被定义过(用#define定义),则对程序段1进行编译,否则编译程序段2.

    • ```cpp

      if 表达式

      //程序段1

      else

      //程序段2

      endif

define DEBUG

…..

ifdef DEBUG

  1. cout<<x<<'\t'<<endl;

endif

  1. - 与前一种形式相反,当标识符没有被定义过,则对程序段1进行编译,否则编译程序段2
  2. -
  3. ```cpp
  4. #if 表达式
  5. //程序段1
  6. #else
  7. //程序段2
  8. #endif
  9. #define DEBUG 1
  10. ......
  11. #if DEBUG
  12. cout<<x<<'\t'<<y<<endl;
  13. #endif
  • 当表达式为真(非零),编译程序段1,表达式为0,编译程序段2。调试完后改为#define DEBUG 0,则不输出调试信息。
    • 采用条件编译后,可以使机器代码程序缩短。
  • 补充算法

    • 牛顿切线法

      • 只有少数的方程有精确解,一般都是用迭代法近似求方程的解。方程的实数解实际上是曲线在x轴上交点的值。
      • 步骤:(1)任选一x1值,在y1=f(x1)处做切线与x轴相交于x2处

        1. ![批注 2020-08-10 202239.png](https://cdn.nlark.com/yuque/0/2020/png/2314091/1597062938343-dac2ca61-7f1b-4ec6-a964-8d22eb709ddc.png#align=left&display=inline&height=249&margin=%5Bobject%20Object%5D&name=%E6%89%B9%E6%B3%A8%202020-08-10%20202239.png&originHeight=332&originWidth=431&size=38283&status=done&style=none&width=323)<br />(2)若|x2-x1|或|f(x2)|小于指定的精度,则令x1=x2,继续步骤(1).
      • 根据已知点求其切线的公式:

14、内部函数与外部函数 - 图1

  1. - 牛顿切线法收敛快,适用性强,缺陷是必须求出方程的导数。
  2. - 例: 已知方程f(x)=x*x-a时,用牛顿切线法求方程的解。给定初值x0,精度10
cin>>x1; //从键盘输入x0
do
{ x0=x1;
 x1=x0-(x0*x0-a)/(2*x0) ; //
} while (fabs(x1-x0)>=1e-6) ; 
cout>>”x=”>>x1>>endl;
  • 弦截法
    • 步骤:
    1. 在x轴上取两点x1和x2,确保x1与x2之间有且只有方程唯一的解
    2. x1与x2分别与f(x)相交于y1=f(x1)、y2=f(x2)
    3. 做直线通过y1、y2与x轴交于x0点

批注 2020-08-10 202239.png

  1. 若|f(x0)|满足给定精度,则x0是方程的解,否则若f(x0)*f(x1)<0,则方程的解应在x1与x0之间,令x2=x0,继续做步骤ii。同理,若f(x0)*f(x1)>0,则方程的解应在x2与x0之间,令x1=x0,继续做步骤ii,直至满足精度为止

  - 公式:![](https://cdn.nlark.com/yuque/__latex/856d539d87e829938a943c3ca662b22a.svg#card=math&code=x0%3D%5Cfrac%7Bx1%2Af%EF%BC%88x2%EF%BC%89-x2%2Af%EF%BC%88x1%EF%BC%89%7D%7Bf%EF%BC%88x2%EF%BC%89-f%EF%BC%88x1%EF%BC%89%7D&height=57&width=252)
  - 例:
#include <math.h> 
float f (float x) 
{return x*x*x-5*x*x+16*x-80; }
float xpoint(float x1,float x2)
{ float x0; 
 x0=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1));
 return x0;
}
void main(void ) 
{ 
    float x1,x2, x0, f0, f1, f2;
    do{ 
        cout<<“Input x1, x2\n”;
        cin>>x1>>x2;
        f1=f(x1);
        f2=f(x2); 
    } while (f1*f2>0);
    do{
        x0=xpoint(x1,x2);
        f0=f(x0);
        if ((f0*f1) >0) 
        { 
            x1=x0;
            f1=f0;
        }
        else
        {
            x2=x0;
            f2=f0;
        } 
    }while (fabs(f0)>=0.0001);
    cout<<”x=”<< x0<<endl;
}
  • 两分法
    • 步骤:
    1. 在x轴上去两点x1和x2,要确保x1与x2之间有且只有方程唯一的解
    2. 求出x1、x2的中点x0;
    3. 若|f(x0)|满足给定的精度,则x0即是方程的解,否则,若f(x0)f(x1)<0,则方程的解应在x1与x0之间,令x2=x0,继续做步骤ii。同理,若f(x0)f(x1)>0,则方程的解应在x2与x0之间,令x1=x0,继续做步骤ii,直至满足精度为止。
  - 例:用两分法求方程的根 。x-5x+16x-80=0 。
#include <math.h>
float f (float x)   //输入x,输出f(x)
{
    return x*x*x-5*x*x+16*x-80;
} 
void main( void ) 
{ float x1,x2, x0, f0, f1, f2;
 do
 { cout<<“Input x1, x2\n”;
  cin>>x1>>x2; 
  f1=f(x1); f2=f(x2);    //判断输入是否合法
 } while (f1*f2>0);
 do
 { x0=(x1+x2)/2;     //求x1与x2的
  f0=f(x0);
  if ((f0*f1) >0){ x1=x0;f1=f0;}
  else { x2=x0;f2=f0;} 
 }while (fabs(f0)>=0.0001);
 cout<<”x=”<< x0<<endl;
}
  • 例:根据以下公式,返回满足精度0.0005要求的π的值。

批注 2020-08-11 095912.png

#include "math.h"
double pi(double eps)
{
    double s,t;
    int n;
    for(t=1,s=0,n=1;t>eps;n++)
    {
        s+=t;
        t=n*t/(2*n+1);
    }
    return 2*s;
}
main()
{
    double x;
    cout<<"\nInput a precision:";
    cin>>x;
    cout<<"x="<<pi(x);
}

128ff300a18b87d605f25679100828381e30fdbd_WPS图片.jpg