c语言内部函数与,C语言-内部函数和外部函数

LAP 8.108.10 内部函数和外部函数内部函数和外部函数 函数本质上是全局的,因为一个函数要被另外的函数调用,但是,也可以指定函数 不能被其他文件调用 根据函数能否被其他源文件调用,将函数区分为内部函数和外部函数。 8.10.18.10.1 内部函数内部函数 如果一个函数只能被本文件中其他函数所调用,它称为内部函数。 在定义内部函数时,在函数名和函数类型的前面加 static。即 static 类型标识 符函数名(形参表)如: static int fun(int a,int b) 内部函数又称静态函数。 使用内部函数,可以使函数只局限于所在文件,如果在不同的文件中有同名的内 部函数,互不干扰。 这样不同的人可以分别编写不同的函数,而不必担心所用函数 是否会与其他文件中函数同名,通常把只能由同一文件使用的函数和外部变量放 在一个文件中,在它们前面都 static 使之局部化,其他文件不能引用。 8.10.28.10.2 外部函数外部函数 (1) 在定义函数时,如果在函数首部的最左端冠以关键字 extern,则表示此函数 是外部函数,可供其他文件调用。 如函数首部可以写为 extern int fun (int a, int b) 这样,函数 fun 就可以为其他文件调用。C 语言规定,如果在定义函数时省略 extern,则隐含为外部函数。本书前面所用的函数都是外部函数。 LAP (2) 在需要调用此函数的文件中,用 extern 声明所用的函数是外部函数。 例 8.22 有一个字符串,内有若干个字符,今输入一个字符,要求程序将字符串中该字符删 去。 用外部函数实现。 file1.c(文件 1) main() { extern enter-string(char str[80]); extern delete-strin g(char str[ ],char ch); extern print-string(char str[]); //以上 3 行声明在本函数中将要调用的在其他文件中定义的 3 个函数 char c; char str[80]; enter-string(str); scanf("%c",&c); delete-string(str,c); print-string(str); } file2.c(文件 2) #include enter-string(char str[80])/定义外部函数 enter-string*/ {gets(str);} /读入字符串 str*/ file3.c(文件 3) delete-string(char str [] , char ch) //定义外部函数 delete-string { int i,j; for(i=j=0;str[i]!=′\0′;i++) if(str[i]!=ch) str[j++]=str[i]; str[j]=′\0′; LAP } file4.c(文件 4) print-string(char str[])/定义外部函数 print-string/ { printf("%s",str); } 运行情况如下: abcdefgc(输入 str) c(输入要删去的字符) abdefg (输出已删去指定字符的字符串) 整个程序由 4 个文件组成。每个文件包含一个函数。主函数是主控函数,除声明 部分外,由 4 个函数调用语句组成。其中 scanf 是库函数,另外 3 个是用户自己 定义的函数。函数 delete-string 的作用是根据 给定的字符串 str 和要删除的字符 ch,对 str 作删除处理。算法是这样的: 对 str 数组的字符逐个检查,如果不是被删除的字符就将它存放在数组中,见图 8.21(设删除空格)。从 str[0]开始逐个检查数组元素值是否等于指定要删 除的字符,若不是就留在数组中,若是就不保留。从图中可以看到,应该使 str [0]赋给 str[0],str[1]str[1],str[2]str[2],str[3]str [3],然后 str[5]str[4]……请读者注意分析如何控制 i 和j的变化, 以便使被删除的字符不保留在原数组中。这个题目当然可以设两个数组,把不删 除的字符一一赋给新数组。 但我们只用一个数组, 只把不被删除的字符保留下来。 由于 i 总是大于或等于j, 因此最后保留下来的字符不会覆盖未被检测处理的字 符。最后将结束符‘\0’也复制到被保留的字符后面。 程序中 3 个函数都定义为外部函数。在 main 函数中用 extern 声明在 main 函数中用到的 enter-string、delete-string、print-string 是在其他文件中定 义的外部函数。通过此例可知:使用 extern 声明就能够在一个文件中调用其他 文件中定义的函数,或者说把该函数的作用域扩展到本文件。extern 声明的形 式就是在函数原型基础上加关键字 extern(见本例 main 函数中的声明形式)。 由于函数在本质上是外部的,在程序中经常要调用外部函数,为方便编程,C 语 言允许在声明函数时省写 extern。例 8.21 程序 main 函数中对 power 函数的声 明就没有用 extern,但作用相同。一般都省写 extern,例如例 8.22 程序 main 函数中的第一个函数声明可写成 enter-string(char str[80]);这就是我们多 次用过的函数原型。由此可以进一步理解函数原型的作用。用函数原型也能够把 函数的作用域扩展到定义该函数的文件之外(不必使用 extern)。只要在使用 该函数的每一个文件中包含该函数的函数原型即可。函数原型通知编译系统:该 函数在本文件中稍后定义,或在另一文件中定义。利用函数原型扩展函数作用域 最常见的例子是#include 命令的应用。在前面几章中曾多次使用过#include 命 令,并提到过:在#include 命令所指定的“头文件”中包含有调用库函数时所 LAP 需的信息。例如,在程序中需要调用 sin 函数,但三角函数并不是由用户在本文 件中定义的,而是存放在数学函数库中的。 按以上的介绍,必须在本文件中写出 sin 函数的原型,否则无法调用 sin 函数。sin 函数的原型是 double sin(double x);显然,要求程序设计者在调用 库函数时先从手册中查出所用的库函数的原型, 并在程序中一一写出来是麻烦而 困难的。为减少程序设计者的困难,在头文件 math.h 中包括了所有数学函数的 原型和其他有关信息,用户只需用以下#include 命令: #include 这样,在该文件中就能合法地调用各数学库函数了。 举例加深理解: C 语言的内部函数指的是 C 语言自带的函数,无论是动态链接的或静态链接的. 这些函数通过 C 语言的头文件定义了. 例如, sin(),cos()等数学函数,在 math.h 中定义了,输入输出函数 printf(),fgetc()在 stdio.h 中定义了,时间函数表 time(),ctime()等在 time.h 中定义了.还有许多其他 内部函数.编程时,只要用#include 写在编程头部,程序中就可调用. 自定义函数,就是用户自己写的函数. 第二种凡加写了 extern 的函数是外部函数: 自定义函数可以与程序的 main()写在同一个文件中,也可以写在另一个文件中,这 时你可能还另写自己的头文件或者写 extern....,告诉编译器,main 中用到的某某 函数是"外部函数". 例如,main()在 a.c 中,自定义函数 my_func()在 a2.c 中 a.c 内容: #include extern float my_func(float a); main() { printf("result=%f\n",my_func(2.0)); } a2.c 内容: float my_func(float a) { return a; LAP } 编译: cl -c a.c[得到 a.obj] cl -c a2.c[得到 a2.obj] cl a.obj a2.obj[链接成 a.exe] 运行: a.exe 得 result=2.000000 extern float my_func() 是外部说明,告诉编译,main()里的 my_func 是外部函数, 要通过链接(.obj)得到. 如果把 my_func 写在 a.c 里: #include float my_func(float a){ retun a; } main() { printf("result=%f\n",my_func(2.0)); } my_func() 就不是外部函数. 编译: cl a.c [得 a.exe] 运行: a.exe 得 result=2.000000

展开阅读全文

你可能感兴趣的:(c语言内部函数与)