函数是仅在调用时运行的代码块。可以将数据(称为参数)传递给函数。函数可以返回数据。函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。本文主要介绍C语言函数。

1、定义函数(实现)

在C语言中,函数的定义顺序是有讲究的:默认情况下,只有后面定义的函数才可以调用前面定义过的函数。

例如,

#include <stdio.h>
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2) 
{
   /* 局部变量声明 */
   int result;
   if (num1 > num2)
      result = num1;
   else
      result = num2;
   return result; 
}
int main ()
{
   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   int ret;
   /* 调用函数来获取最大值 */
   ret = max(a, b);
   printf( "Max value is : %d\n", ret );
   return 0;
}

注意:上面这样调用合法的,但如果调换sum函数和main函数的顺序,在标准的C编译器环境下是不合法的(不过在GCC编译器环境下只是一个警告)。

2、函数声明

如果想把函数的定义写在main函数后面,而且main函数能正常调用这些函数,那就必须在main函数的前面进行函数的声明。

函数声明地格式:

返回值类型 函数名 (参数1, 参数2, ...)

例如,

#include <stdio.h>
/* 函数声明 */
int max(int num1, int num2);
int main ()
{
   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   int ret;
   /* 调用函数来获取最大值 */
   ret = max(a, b);
   printf( "Max value is : %d\n", ret );
   return 0;
}
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2) 
{
   /* 局部变量声明 */
   int result;
   if (num1 > num2)
      result = num1;
   else
      result = num2;
   return result; 
}

3、调用函数

函数调用的一般形式为:

函数名(实参列表);

调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如:

#include <stdio.h>
/* 函数声明 */
int max(int num1, int num2);
int main ()
{
   /* 局部变量定义 */
   int a = 100;
   int b = 200;
   int ret;
   /* 调用函数来获取最大值 */
   ret = max(a, b);
   printf( "Max value is : %d\n", ret );
   return 0;
}
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2) 
{
   /* 局部变量声明 */
   int result;
   if (num1 > num2)
      result = num1;
   else
      result = num2;
   return result; 
}

4、函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

当调用函数时,有三种向函数传递参数的方式:

1)传值

#include<stdio.h>
void myswap(int x, int y)
{
    int t;
    t=x;
    x=y;
    y=t;
}
int main()
{
    int a, b;
    printf("请输入待交换的两个整数:");
    a=10,b=20;
    myswap(a,b);  //作为对比,直接交换两个整数,显然不行
    printf("调用交换函数后的结果是:%d 和 %d\n", a, b);
    return 0;
}

2)传引用

#include<stdio.h>
void myswap(int *p1, int *p2)
{
    int  t;
    t=*p1;
    *p1=*p2;
    *p2=t;
}
int main()
{
    int a, b;
    printf("请输入待交换的两个整数:");
    a=10,b=20;
    myswap(&a,&b);  //交换两个整数的地址
    printf("调用交换函数后的结果是:%d 和 %d\n", a, b);
    return 0;
}

5、函数递归

一个函数在它的函数体内,直接或者间接地调用了他本身。

例如,

问第五个学生,说他比第四个学生大两岁

第四个学生说他比第三个学生大两岁

第三个学生说他比第二个学生大两岁

第二个学生说他比第一个学生大两岁

第一个说他10岁

求第五个学生的年龄,可以使用如下解法:

#include<stdio.h>
/*int Age (int n)
{
  int tmp;
  tmp=10;
  for(int i=1;i<n;i++)
  {
    tmp+=2;
  }
  return tmp;
}
*/
//递归法
int Age(int n)
{
  int x=0;
  if(n==1)      //是递归停止的条件,当n=1时停止递归调用
  {
     x=10;
  }
  else
  {
     x=Age(n-1)+2;//调用自身的Age函数
  }
  return x;
}
int main()
{
  printf("%d\n",Age(5));
  return 0;
}

注意:函数的递归调用,就是函数本身调用自己。但是应用递归调用的时候,我们有必要设置一个条件,也就是if语句,目的是能够让这个函数停下来,否则程序将进入到死循环。

6、常用库函数

1)数学函数(#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)的值

计算结果

 

2)字符函数(#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中的字母转换成大写字母

返回对应的大写字母

3)字符串函数(#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所指字符串进行比较

s1<s2,返回负数;

s1= =s2,返回0;

s1>s2,返回正数

char *strcpy(char *s1,

char *s2)

把s2指向的串复制到s1指向的空间

s1 所指地址

unsigned strlen(char *s)

求字符串s的长度

返回串中字符

(不计最后的'\0')个数

char *strstr(char *s1,

char *s2)

在s1所指字符串中,

找出字符串s2第一次出现的位置

返回找到的字符串的地址,

找不到返回NULL

4) 输入输出函数(#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,…所指的内存中

已输入的数据的个数

5)动态分配函数和随机函数(#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非正常终止

推荐文档