Loading... # 函数 ## **模块化程序设计思想:** 实现编写好一批常用的函数,需要使用时可直接调用,而不必重复在写,减少了程序的冗余,使得程序变得更加精炼,编写一次,就可以多次调用。 **函数声明的作用**:吧有关函数的信息(函数名、函数类型、函数参数的个数与类型)通知编译系统,以便在编译系统对程序进行编译时,在进行到main函数中调用其它函数时,知道它们是定义的函数而不是变量或其他对象。 说明: **(1)** 一个C程序由一个或多个程序模块组成,每一个程序模块作为一个源程序文件。对于较大的程序,一般不希望把所有的内容全放在一个文件中,而是将它们分别编写成若干个源文件中,由若干个源程序文件组成一个C程序。 **(2)** 一个源程序文件由一个或多个函数以及其他有关内容(如指令、数据声明与定义)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位进行编译的,而不是以函数为单位进行编译的。 **(3)** C程序的执行是从main函数开始的,如果在main函数中调用它其他函数,在调用后流程返回到main函数,在main函数找那个结束整个程序的运行。 **(4)** 所有函数都是平行的,即在定义函数时是分别进行的,是相互独立的;一个函数并不从属于另一个函数,即**函数不能嵌套定义**。 **(5)** 从用户使用的角度看,函数有两种形式 ① 库函数 ② 用户自己定义的函数 **(6)** 从函数的角度看,函数有两种形式 ① 无参函数 ② 有参函数 # 一、函数的定义 一般来说,执行源程序就是执行主函数main,其他函数只能被主函数所调用,而其他函数之间也可以相互调用。 ## 1.标准库函数: 分为:I/O函数,字符串,字符处理函数,数学函数,接口函数,时间转换和操作函数,动态地址分配函数,目录函数,过程控制函数,字符屏幕和图形功能函数。 这些库函数在不同的头文件中声明。比如: `<math.h>`头文件中有:`sin(x),cos(x),exp(x)(求e^x),fabs(x)(求x的绝对值)`等库函数。 `<stdio.h>`头文件中有:`scanf(),printf(),gets(),puts(),getchar(),putchar()`等库函数。 `<string.h>`头文件中有:`strcmp(),strcpy(),strcat(),strlen()`等库函数。 ## 2.函数的定义: ### (1)定义无参函数: ```c 类型名 函数名() {undefined 函数体 } or 类型名 函数名(void) {undefined 函数体 } ``` ### (2)定义有参函数 ```c 类型名 函数名(形式参数表列) {undefined 函数体 } ``` ### (3)定义空函数 ```C 类型名 函数名() { } ``` # 二、函数的调用 ## 1.函数调用时的参数传递 函数间通过参数来传递数据,即通过主调函数中的实际参数( **实参** )向被调用函数中的形式参数( **形参** )进行传递。 **实参** 向 **形参** 传递数据的方式: **实参** 将值单向传递给 **形参** , **形参** 的变化 **不影响** 实 **参值** 。 > 例: ```c #include<stdio.h> #include<stdlib.h> int main() { int a, b; void swap(int a, int b); //函数声明 scanf("%d%d", &a, &b); //键盘输入 swap(a, b); //函数调用 printf("最终的a,b值:\n a=%d b=%d\n", a, b); system("pause"); return 0; } void swap(int a, int b) { int t; if (a < b) { t = a; a = b; b = t; //a中放大值,b中放小值 } printf("自定义函数的a,b值:\n a=%d b=%d\n", a, b); } ``` > 运行结果为: **分析:形参交换了数据,而实参保持原数据不变。这是单向的值传递,所以形参的值改变后而实参的值没有改变。** (1)形参在函数中是变量名,在函数调用时,形参被临时分配相应的内存,调用结束后,形参单元被释放,而实参单元保留并维持原值。 (2)实参是表达式,负责向对应的形参标识的内存单元传递数据,实参向形参的数据传递是“值传递”。 (3)实参与形参必须个数相同 (4)对应的形参和实参的类型必须一致 ## 2.函数的返回值 ### (1)函数的返回值通过函数中的return语句获得。 如果需要从调用函数带回一个函数值(供主函数使用),被调函数中需包含return语句。 > 例: ```c int max(int x,int y) { return(x>y?x:y); } ``` ### (2)在定义函数时要指定函数值的类型 ```c int max(float x,float y) //函数值为整型 char letter(char c1,char c2) //函数值为字符型 double max(int x,int y) //函数值为双精度型 ``` ### (3)函数类型决定返回值的类型。 ## 3.函数的嵌套 定义函数时不能定义另一个函数,但是可以进行嵌套调用函数。 > 例: **用函数嵌套找出4个数中的最大值。** ```c #include<stdio.h> #include<stdlib.h> int max2(int a, int b) //找出a和b中的最大值 { if (a >= b) { return a; // a作为返回值 } return b; // b作为返回值 } int max4(int a, int b, int c, int d) //定义找4个数最大值的函数 { int m; //存最大值 m = max2(a, b); //调用max2函数,将a,b中大的值放在m中 m = max2(m, c); //调用max2函数,将a,b,c中大的值放在m中 m = max2(m, d); //调用max2函数,将a,b,c,d中大的值放在m中 return m; //返回到主函数 } int main() { int a, b, c, d; int max; printf("请输入四个数:\n"); scanf("%d%d%d%d", &a, &b, &c, &d); max = max4(a, b, c, d); //调用max4函数 printf("最大数位:%d\n", max); system("pause"); return 0; } ``` # 三、函数的递归 ## 1.递归概念: 函数的递归调用是指:一个函数在他的函数体内直接或间接地调用它自身。分为:直接递归(函数直接调用自身)和间接递归(函数通过其他函数调用自身)。可分为“回溯”和“递推”两个阶段。 ## 2.递归函数的一般形式: ```c 反值类型 递归函数名(参数说明表) { if(递归终止条件) 返回值=递归终止值; else 返回值=递归调用(...)的表达式; return 返回值; } ``` ## 3.递归函数举例: **用递归求n的阶乘。** ```c #include<stdio.h> #include<stdlib.h> int fac(int n) //定义函数 { int f; if (n < 0) printf("数据错误\n"); else if (n == 0 || n == 1) f = 1; else f = n* fac(n - 1); //n!=n*(n-1) return f; //返回主函数 } int main() { int n, y; printf("请输入n的值\n"); scanf("%d", &n); y = fac(n); //这里n为实参 printf("%d!=%d\n", n, y); system("pause"); return 0; } ``` > 汉诺塔问题为经典的递归调用实例。代码如下: ```c #include<stdio.h> #include<stdlib.h> void move(char x, char y) //输出移盘方案 { printf("%c->%c\n", x, y); } void hanoi(int n, char one, char two, char three) //移盘 { if (n == 1) move(one, three); //如果是1个盘,直接从第一个座移到第3个座上 else { hanoi(n - 1, one, three, two); move(one, three); hanoi(n - 1, two, one, three); } } int main() { int n; printf("输入盘的个数\n"); scanf("%d", &n); printf("移盘的步骤:\n"); hanoi(n, 'A', 'B', 'C'); system("pause"); return 0; ``` **分析:将n个盘子从A座上移到C座上需要三步:** (1)将A上的n-1个盘子借助C座先移到B座上; (2)把A座上剩下的一个盘子移到C座上; (3)将n-1个盘从B座上借助于A移到C座上。 # 四、数组函数 **用数组元素来作为函数参数**。 另外,用**数组名也可以作为实参和形参**,传递的是数组的**首地址**。 ### **一、用数组元素作为函数实参** 这与用变量作为实参一样,是**单向传递**,取“**值传递**”的方式。 ### **二、用数组名作为函数参数** 此时,实参和形参都要用**数组名**(或用指针) **注意:** 1、形参数组名和实参数组名应该在自己所在的函数内部定义,不能只在一方定义; 2、实参数组和形参数组的类型应当一致; 3、不是“值传递”,不是“单向传递”,而是“地址传递”,两个数组共占一段内存单元:形参数组中各元素的值发生变化,会使实参数组中的元素的值通知变化。 | a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | | ---- | ---- | ---- | ---- | ---- | ---- | | 2 | 4 | 6 | 8 | 10 | 12 | | b[1] | b[2] | b[3] | b[4] | b[5] | b[6] | **三、用多维数组作为函数参数** 可以用多维数组作为函数的实参和形参,对于在被调函数中对形参数组的定义,可以指定每一维的大小,也可以省略第一维的大小,但是不能把第二维解其他维的大小省略。 # 局部变量和全局变量 我们首先提出一个问题:在一个函数中定义的变量,在其他函数中能否被引用?在不同位置定义的变量,在什么范围内有效? 以上的问题就是该节讨论的变量的作用域的问题。每一个变量都有一个作用域问题,即它们在什么范围内有效。 ## 局部变量 定义变量可能有3种情况: (1)在函数的开头定义 (2)在函数内的符合语句内定义 (3)在函数的外部定义 在一个函数内部定义的变量只在本函数范围内有效,也就是说只有在本函数内才能引用它们,在此函数以外是不能使用这些变量的。在复合语句内定义的变量只在本复合语句范围内有效,只有在本复合语句内才能引用它们。在该复合语句以外是不能使用这些变量的,以上这些称为“局部变量” ![](/images/Cimages/function-master/1.png) ### 说明: (1)主函数中定义的变量(如m,n)也只能在主函数中有效,并不因为在主函数中定义而在整个文件或程序中有效。主函数不能使用其他函数中定义的变量,如f1中的b,c;f2中的m,n都不能使用 (2)不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰。如f1中定义的b,c也可在f2中定义 (3)形式参数也是局部变量 (4)在一个函数内部,可以在复合语句中定义变量,这些变量只在复合语句中有效,这些复合语句也称为“分程序”或“程序块” ![](/images/Cimages/function-master/2.png) ## 全局变量 程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。 在函数内定义的变量是**局部变量**,而在函数之外定义的变量称为**外部变量**,外部变量是**全局变量**。全局变量可以为本文件中其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。 注意:在函数内定义的变量是局部变量,在函数外定义的变量是全局变量。 ![](/images/Cimages/function-master/3.png) P,q,c1,c2都是全局变量,它们的作用范围不同,在main函数和f2函数中可以使用全局变量p,q,c1,c2,但在函数f1中只能使用p,q而不能使用c1,c2. ###说明: 设置全局变量的作用是增加了函数间数据联系的渠道。由于同一个文件中的所有函数都能引用全局变量的值,因此如果在一个函数中改变了全局变量的值,就能影响到其他函数中全局变量的值。相当于各个函数间有直接的传递通道。由于函数的调用只能待会一个函数返回值,一次有时可以利用全局变量来对增加函数建的联系渠道,通过函数调用能得到一个以上的值。 为了便于区别全局变量和局部变量,在C程序设计中有一个习惯(并非规定)。将全局变量名的第1个字母用大写表示。 ## 说明:建议不再必要时不要使用全局变量,理由如下: (1)全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。故消耗内存单元 (2)它使函数的通用性降低了,如果在函数中引用了全局变量,那么执行情况会受到有关的外部变量影响,如果有一个函数移到另一个文件中,还要考虑把有关的外部变量及其值一起转移过去。但若该外部变量与其他文件的变量同名时,就会出现问题。这就降低了程序的可靠性和通用性。在程序设计中,在划分模块时要求模块的“内聚性”强,与其他模块的“耦合性”弱。即模块的功能要单一,不相互影响或者影响较小。 (3)使用全局变量过多,会降低程序的清晰性,难以判断瞬间各个外部变量的值。由于在各个函数执行过程中都可能改变外部变量的值,故程序容易出错。 注意:如果在同一个源文件中,全局变量与局部变量同名,这时会出现什么情况呢? 答案是,在局部变量的作用范围内,局部变量有效,全局变量被“屏蔽”,即全局变量不起作用。简单说,就是局部变量在该范围内覆盖了全局变量。 # 变量的存储方式和生存期 ## 1、变量的存储类型 存储类型可分为4类,分别是:自动变量(automatic variable)、外部变量(extern variable)、静态变量(static variable)、寄存器变量(register variable)。其中:自动变量和寄存器变量只能是局部变量,采用动态存储方式;外部变量和静态变量具有全程生存期,可为全局变量,采用静态存储方式。 > C语言中对变量存储类型的定义格式如下: ```c 存储类型说明符 数据类型说明符 变量名称列表; ``` ### 存储类别 存储类别指 数据在内存中的存储的方式(如静态、动态存储) C语言的存储类别有4种:自动的(`auto`)、静态的(`static`)、寄存器的(`register`)、外部的(`extend`),根据变量的存储类别可以知道变量的作用域和生存期。 #### 1、`auto` 函数中的局部变量如果不专门声明为static则都是auto存储类别。在调用函数时,系统会给变量分配存储空间,在函数调用结束时就自动释放这些存储空间。 自动变量在函数调用时对其赋值操作。 #### 2、`static` 若函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,再下一次再调用该函数时,该变量已有值(即上次调用结束时的值) 对静态局部变量在编译时赋初值。**(`static`静态变量只在声明时初始化一次)** #### 3、`register` 局部变量的值放在CPU的寄存器中。对寄存器的存取速度远高于对内存的寄存速度,可以提高执行效率。 **(`register`说明的变量是建议编译器将变量的值保存在寄存器中,所以`register`没有地址不能进行地址运算!)** #### 4、`extern` 全局变量都是存放在静态存储区中。因此他们生存期都是固定的,存在于整个运行过程。 它的作用域实从变量的定义处开始,到本程序文件的末尾。但是可扩展外部变量的作用域。 ### 小结 数据定义需要指定两种属性:数据类型和存储类别。 `extern`可声明已定义外部变量。 #### 1.作用域分为局部变量和全局变量 局部变量:自动变量(离开函数,值就消失)、静态局部变量(离开函数,值仍保留) 寄存器变量(离开函数,值就消失)、形参也为自动变量或寄存器变量 全局变量:静态外部变量(只限本文件引用)、外部变量(允许其他文件引用) #### 2.生存期分为动态存储和静态存储 动态存储:自动变量(本函数内有效)、寄存器变量(本函数内有效)、 形参(本函数内有效) 静态存储:静态局部变量(函数内有效)、静态外部变量(本文件内有效)、 外部变量(用extern声明后,其他文件可引用) #### 3.存放位置分为内存静态存储区、内存动态存储区和CPU寄存器 静态存储区:静态局部变量、静态外部变量(函数外部静态变量)、 外部变量(可为其他文件引用) 动态存储区:自动变量和形式参数 CPU寄存器:寄存器变量 #### 4.作用域和生存期 作用域(空间):在此作用域内可以引用该变量,变量在作用域内“可见”(可见性) 生存期(时间):在某一时刻存在,变量在此时刻“存在”(存在性) #### 5.static对局部变量和全局变量的作用不同。(都是使作用域局限) 对局部变量,它使变量由动态存储方式改变为静态存储方式。对全局变量,它使变量局部化(局部于本文件) <table cellspacing="0" border="0" align="center" with="100%"> <tbody> <tr> <td rowspan="2" style="vertical-align:top;width:117.15pt;"> 变量存储类别 </td> <td colspan="2" style="vertical-align:top;width:92.15pt;"> 函数内 </td> <td colspan="2" style="vertical-align:top;width:134.65pt;"> 函数外 </td> </tr> <tr> <td style="vertical-align:top;width:49.6pt;"> 作用域 </td> <td style="vertical-align:top;width:42.55pt;"> 存在性 </td> <td style="vertical-align:top;width:88.2pt;"> 作用域 </td> <td style="vertical-align:top;width:46.45pt;"> 存在性 </td> </tr> <tr> <td style="vertical-align:top;width:117.15pt;"> 自动变量和寄存器变量 </td> <td style="vertical-align:top;width:49.6pt;"> √ </td> <td style="vertical-align:top;width:42.55pt;"> √ </td> <td style="vertical-align:top;width:88.2pt;"> × </td> <td style="vertical-align:top;width:46.45pt;"> × </td> </tr> <tr> <td style="vertical-align:top;width:117.15pt;"> 静态局部变量 </td> <td style="vertical-align:top;width:49.6pt;"> √ </td> <td style="vertical-align:top;width:42.55pt;"> √ </td> <td style="vertical-align:top;width:88.2pt;"> × </td> <td style="vertical-align:top;width:46.45pt;"> √ </td> </tr> <tr> <td style="vertical-align:top;width:117.15pt;"> 静态外部变量 </td> <td style="vertical-align:top;width:49.6pt;"> √ </td> <td style="vertical-align:top;width:42.55pt;"> √ </td> <td style="vertical-align:top;width:88.2pt;"> √(只限本文件) </td> <td style="vertical-align:top;width:46.45pt;"> √ </td> </tr> <tr> <td style="vertical-align:top;width:117.15pt;"> 外部变量 </td> <td style="vertical-align:top;width:49.6pt;"> √ </td> <td style="vertical-align:top;width:42.55pt;"> √ </td> <td style="vertical-align:top;width:88.2pt;"> √ </td> <td style="vertical-align:top;width:46.45pt;"> √ </td> </tr> </tbody> </table> ### 关于变量的声明和定义 一个函数由两部分组成:声明部分和执行语句 声明部分的作用:对有关的标识符(变量、函数、结构体、共用体)的属性进行声明。 函数的声明是函数的原型,而函数的定义是对函数功能的定义。 对于变量而言,声明与定义的关系复杂一些。不过总结出来就是,**建立存储空间的声明称定义,而把不需要建立存储空间的声明称为声明** # 内部函数和外部函数 函数本质上是全局的,因为定义一个函数的目的就是要被另外的函数调用。如果不加声明的话,一个文件中的函数既可以被本文件中其他函数调用,也可以被其他文件中的函数调用。但是,凡事都有特例,也可指定某些函数不能被其他文件调用。 ## 内部函数 如果一个函数只能被本文件中其他函数锁调用,它称为**内部函数**。在定义内部函数时,在函数名和函数类型的前面加static,即 **`static 类型名 函数名(形参表);`** > 如: ```c static int fun(int vara,int varb); ``` 表示fun是一个内部函数,不能被其他文件调用 内部函数又称为**静态函数**,因为它是用static声明的。被static声明的函数作用域只局限于所在的文件。 通常把只能由本文件使用的函数和外部变量放在文件的开头,前面都冠以static使之局部化,其他文件不能引用。这就提高了程序的可靠性 ## 外部函数 如果在定义函数时,在函数首部的最左端加关键字extern,则此函数是**外部函数**,可供其他文件调用,即 **`static 类型名 函数名(形参表);`** 如: ```c extern int function(int vara,int varb); ``` 表示function是一个外部函数,可被其他文件调用。 C语言规定,如果在定义函数时省略extern,则默认为外部函数。 # C语言常用库函数(含详细用法) **一、数学函数** 调用数学函数时,要求在源文件中包下以下命令行: \#include <math.h> | **函数原型说明** | **功能** | **返回值** | **说明** | | ---------------------------------- | ------------------------------------------------------------ | ----------------- | -------------- | | int abs( int x) | 求整数x的绝对值 | 计算结果 | | | double fabs(double x) | 求双精度实数x的绝对值 | 计算结果 | | | double acos(double x) | 计算cos-1(x)的值 | 计算结果 | x在-1~1范围内 | | double asin(double x) | 计算sin-1(x)的值 | 计算结果 | x在-1~1范围内 | | double atan(double x) | 计算tan-1(x)的值 | 计算结果 | | | double atan2(double x) | 计算tan-1(x/y)的值 | 计算结果 | | | double cos(double x) | 计算cos(x)的值 | 计算结果 | x的单位为弧度 | | double cosh(double x) | 计算双曲余弦cosh(x)的值 | 计算结果 | | | double exp(double x) | 求ex的值 | 计算结果 | | | double fabs(double x) | 求双精度实数x的绝对值 | 计算结果 | | | double floor(double x) | 求不大于双精度实数x的最大整数 | | | | double fmod(double x,double y) | 求x/y整除后的双精度余数 | | | | double frexp(double val,int *exp) | 把双精度val分解尾数和以2为底的指数n,即val=x*2n,n存放在exp所指的变量中 | 返回位数x 0.5≤x<1 | | | double log(double x) | 求㏑x | 计算结果 | x>0 | | double log10(double x) | 求log10x | 计算结果 | x>0 | | double modf(double val,double *ip) | 把双精度val分解成整数部分和小数部分,整数部分存放在ip所指的变量中 | 返回小数部分 | | | double pow(double x,double y) | 计算xy的值 | 计算结果 | | | double sin(double x) | 计算sin(x)的值 | 计算结果 | x的单位为弧度 | | double sinh(double x) | 计算x的双曲正弦函数sinh(x)的值 | 计算结果 | | | double sqrt(double x) | 计算x的开方 | 计算结果 | x≥0 | | double tan(double x) | 计算tan(x) | 计算结果 | | | double tanh(double x) | 计算x的双曲正切函数tanh(x)的值 | 计算结果 | | **二、字符函数** 调用字符函数时,要求在源文件中包下以下命令行: \#include <ctype.h> | **函数原型说明** | **功能** | **返回值** | | -------------------- | ------------------------------------------------------------ | -------------------- | | int isalnum(int ch) | 检查ch是否为字母或数字 | 是,返回1;否则返回0 | | int isalpha(int ch) | 检查ch是否为字母 | 是,返回1;否则返回0 | | int iscntrl(int ch) | 检查ch是否为控制字符 | 是,返回1;否则返回0 | | int isdigit(int ch) | 检查ch是否为数字 | 是,返回1;否则返回0 | | int isgraph(int ch) | 检查ch是否为ASCII码值在ox21到ox7e的可打印字符(即不包含空格字符) | 是,返回1;否则返回0 | | int islower(int ch) | 检查ch是否为小写字母 | 是,返回1;否则返回0 | | int isprint(int ch) | 检查ch是否为包含空格符在内的可打印字符 | 是,返回1;否则返回0 | | int ispunct(int ch) | 检查ch是否为除了空格、字母、数字之外的可打印字符 | 是,返回1;否则返回0 | | int isspace(int ch) | 检查ch是否为空格、制表或换行符 | 是,返回1;否则返回0 | | int isupper(int ch) | 检查ch是否为大写字母 | 是,返回1;否则返回0 | | int isxdigit(int ch) | 检查ch是否为16进制数 | 是,返回1;否则返回0 | | int tolower(int ch) | 把ch中的字母转换成小写字母 | 返回对应的小写字母 | | int toupper(int ch) | 把ch中的字母转换成大写字母 | 返回对应的大写字母 | **三、字符串函数** 调用字符函数时,要求在源文件中包下以下命令行: \#include <string.h> | **函数原型说明** | **功能** | **返回值** | | ------------------------------- | ---------------------------------------------- | --------------------------------------------- | | char *strcat(char *s1,char *s2) | 把字符串s2接到s1后面 | s1所指地址 | | char *strchr(char *s,int ch) | 在s所指字符串中,找出第一次出现字符ch的位置 | 返回找到的字符的地址,找不到返回NULL | | int strcmp(char *s1,char *s2) | 对s1和s2所指字符串进行比较 | s1s2,返回正数 | | char *strcpy(char *s1,char *s2) | 把s2指向的串复制到s1指向的空间 | s1 所指地址 | | unsigned strlen(char *s) | 求字符串s的长度 | 返回串中字符(不计最后的'\0')个数 | | char *strstr(char *s1,char *s2) | 在s1所指字符串中,找出字符串s2第一次出现的位置 | 返回找到的字符串的地址,找不到返回NULL | **四、输入输出函数** 调用字符函数时,要求在源文件中包下以下命令行: \#include <stdio.h> | **函数原型说明** | **功能** | **返回值** | | ------------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------- | | void clearer(FILE *fp) | 清除与文件指针fp有关的所有出错信息 | 无 | | int fclose(FILE *fp) | 关闭fp所指的文件,释放文件缓冲区 | 出错返回非0,否则返回0 | | int feof (FILE *fp) | 检查文件是否结束 | 遇文件结束返回非0,否则返回0 | | int fgetc (FILE *fp) | 从fp所指的文件中取得下一个字符 | 出错返回EOF,否则返回所读字符 | | char *fgets(char *buf,int n, FILE *fp) | 从fp所指的文件中读取一个长度为n-1的字符串,将其存入buf所指存储区 | 返回buf所指地址,若遇文件结束或出错返回NULL | | FILE *fopen(char *filename,char *mode) | 以mode指定的方式打开名为filename的文件 | 成功,返回文件指针(文件信息区的起始地址),否则返回NULL | | int fprintf(FILE *fp, char *format, args,…) | 把args,…的值以format指定的格式输出到fp指定的文件中 | 实际输出的字符数 | | int fputc(char ch, FILE *fp) | 把ch中字符输出到fp指定的文件中 | 成功返回该字符,否则返回EOF | | int fputs(char *str, FILE *fp) | 把str所指字符串输出到fp所指文件 | 成功返回非负整数,否则返回-1(EOF) | | int fread(char *pt,unsigned size,unsigned n, FILE *fp) | 从fp所指文件中读取长度size为n个数据项存到pt所指文件 | 读取的数据项个数 | | int fscanf (FILE *fp, char *format,args,…) | 从fp所指的文件中按format指定的格式把输入数据存入到args,…所指的内存中 | 已输入的数据个数,遇文件结束或出错返回0 | | int fseek (FILE *fp,long offer,int base) | 移动fp所指文件的位置指针 | 成功返回当前位置,否则返回非0 | | long ftell (FILE *fp) | 求出fp所指文件当前的读写位置 | 读写位置,出错返回 -1L | | int fwrite(char *pt,unsigned size,unsigned n, FILE *fp) | 把pt所指向的n*size个字节输入到fp所指文件 | 输出的数据项个数 | | int getc (FILE *fp) | 从fp所指文件中读取一个字符 | 返回所读字符,若出错或文件结束返回EOF | | int getchar(void) | 从标准输入设备读取下一个字符 | 返回所读字符,若出错或文件结束返回-1 | | char *gets(char *s) | 从标准设备读取一行字符串放入s所指存储区,用’\0’替换读入的换行符 | 返回s,出错返回NULL | | int printf(char *format,args,…) | 把args,…的值以format指定的格式输出到标准输出设备 | 输出字符的个数 | | int putc (int ch, FILE *fp) | 同fputc | 同fputc | | int putchar(char ch) | 把ch输出到标准输出设备 | 返回输出的字符,若出错则返回EOF | | int puts(char *str) | 把str所指字符串输出到标准设备,将’\0’转成回车换行符 | 返回换行符,若出错,返回EOF | | int rename(char *oldname,char *newname) | 把oldname所指文件名改为newname所指文件名 | 成功返回0,出错返回-1 | | void rewind(FILE *fp) | 将文件位置指针置于文件开头 | 无 | | int scanf(char *format,args,…) | 从标准输入设备按format指定的格式把输入数据存入到args,…所指的内存中 | 已输入的数据的个数 | **五、动态分配函数和随机函数** 调用字符函数时,要求在源文件中包下以下命令行: #include <stdlib.h> | **函数原型说明** | **功能** | **返回值** | | -------------------------------------- | ----------------------------------------------------------- | --------------------------------------- | | void *calloc(unsigned n,unsigned size) | 分配n个数据项的内存空间,每个数据项的大小为size个字节 | 分配内存单元的起始地址;如不成功,返回0 | | void *free(void *p) | 释放p所指的内存区 | 无 | | void *malloc(unsigned size) | 分配size个字节的存储空间 | 分配内存空间的地址;如不成功,返回0 | | void *realloc(void *p,unsigned size) | 把p所指内存区的大小改为size个字节 | 新分配内存空间的地址;如不成功,返回0 | | int rand(void) | 产生0~32767的随机整数 | 返回一个随机整数 | | void exit(int state) | 程序终止执行,返回调用过程,state为0正常终止,非0非正常终止 | 无 | 最后修改:2022 年 07 月 23 日 © 允许规范转载 打赏 赞赏作者 赞 如果觉得我的文章对你有用,请随意赞赏