vlambda博客
学习文章列表

C语言函数完全攻略_1

C 语言强调模块化编程,这里所说的模块就是函数,即把每一个独立的功能均抽象为一个函数来实现。从一定意义上讲,C 语言就是由一系列函数串组成的。

在本章之前,我们的程序只有一个 main 函数,把所有代码都写在 main 函数中,这样虽然程序的功能正常实现,但显得杂乱无章,代码可读性、可维护性较差。学完本节之后,应把每个具体的独立功能单位均抽象为一个函数,在 main 函数中调用各个函数。

C 语言函数大概包括两种,一种是编译系统提供的库函数,如字符串处理复制函数 strcpy,这是 C 编译系统提供的库函数,该函数定义在 string.h 头文件中,在使用时必须包含对应的头文件,即需加上 #include<string.h> 预处理包含命令;另一种是程序设计者自定义的函数。

每一个 C 语言程序都含有一个 main 函数,操作系统调用 main 函数,main 函数调用各个库函数或自定义函数。

函数的定义

函数是用户与程序的接口,在定义一个函数前,首先要清楚以下三个问题。

1) 函数的功能实现及算法选择。算法选择会在后续文章详细讲解,本节重点关注函数的功能实现。一般选取能体现函数功能的函数名,且见名知意,如求和函数的函数名可取为 add,求最大值的函数名可取为 max,排序函数可取名为 sort 等。

2) 需要用户传给该函数哪些参数、什么类型,即函数参数。

3) 函数执行完后返回给调用者的参数及类型,即函数返回值类型。

函教定义格式

函数定义的一般格式为:

返回类型 函数名 (类型参数1,类型参数2,…){ 函数体}


例如,定义一个求两个整数之和的函数,返回该和值。其函数实现代码为:

 
   
   
 
int add (int x,int y){ return (x+y) ; //括号可省略}


说明:
1) 一个函数定义包含函数头和函数体两部分。函数名、参数表和返回类型这三部分一般称为函数头。一对大括号 {} 括起来的为函数体。

2) 函数名:符合标识符的命名规则,最好见名知意。如使用 add 作为求和函数的函数名,sort 作为排序函数名。

3) 参数表:函数定义时的参数又称为形式参数,简称形参。可以含有一个或多个参数,多个形参用逗号隔开。如下格式是错误的。

int add (int x;int y) //错误。函数各形参间用逗号隔开,而非分号{ return x+y;}


各形式参数对应类型均不能省略,如下格式也是错误的。

 
   
   
 
int add (int x,y) //错误。形参y的类型不能省略{ return x+y;}


也可以不含参数,不含参数时,参数表中可写关键字 void 或省略,为规范起见,教程中对没有参数的函数,参数表中统一写 void。例如:

类型 函数名 (){ 函数体}

等价于:

类型 函数名 (void) //建议的书写方式{ 函数体}


4) 在函数定义中,参数表后不能加分号,如下函数定义格式是错误的。

 
   
   
 
float add (float x, float y); //错误。函数定义时,函数头后不能有分号{ return x+y;}

5) 函数体:即函数的功能实现代码部分。用一对大括号 {} 括起来,函数体也可以为空,即函数体内不含任何代码,便于以后扩充。例如:

 
   
   
 
void fun (){

}

6) 返回类型:也称为函数类型,即给调用者返回值的类型。要求显式指定返回类型。可以是基本数据类型如 int、char、float 等,也可以是复合数据类型,如数组类型、指针类型,或者是自定义类型(结构体类型)。

如果返回类型省略,一般默认为 int 型,但不推荐这种不规范的写法。

如果该函数没有返回类型,则为 void 类型。例如:

 
   
   
 
void add (int x,int y){ printf ("sum=%d\n", x+y);}

除了 void 类型外,在函数体中,均需要显式使用 return 语句返回对应的表达式的值。

函教返回值

函数的值是指调用函数结束时,执行函数体所得并返回给主调函数的值。关于函数返回值说明如下。

1) 带返回值的函数,其值一般使用 return 语句返回给调用者。其格式为:

return 表达式;

或者

return (表达式);

例如:

int add (int a, int b){ return (a + b); //return 后为表达式}


2) 函数可以含一个或多个 return 语句,但每次调用时只能执行其中一个 return 语句。


例如,求整数绝对值的函数:

int f (int n) //含多个return语句,但每次调用只执行一个{ if (n >= 0) return n; else return -n; //或为 return (-1 * n);}


3) 不带返回值的函数,其返回类型一般显式指定为 void 类型。如 void print_99 (void); 函数,其返回类型为 void。


4) 如果没有显式指定函数的返回类型,默认为 int 型,不推荐这种不规范的写法。例如:

add (int a, int b) //省略返回类型,默认为int型{ return (a + b);}


5) return 后表达式的类型应与函数返回类型一致,如果不一致,则先将表达式的类型自动转换为函数类型后再返回。例如:

 
   
   
 
int f (void) //函数返回类型为int{ int n = 1; return (n + 2.3); //表达式为 double 型}

上述函数中,函数类型为 int 型,return 后表达式的类型为 double 型值 3.3,两者类型不一致,故首先把表达式的类型 double 自动转换为 int 型值 3,然后再把 3 作为函数返回值返回给调用者。这种情况一般会丢失精度,可能得不到预想的结果。

函教调用格式

无参函数的调用格式

函数名();

注意:无参函数调用时,参数表空着,而不能写出 void,如下函数调用是错误的。

函数名 (void);//错误!无参函数调用时,参数表空着,不能加void

例如,设有定义好的无参函数 void print_99(void); 的调用如下。

 
   
   
 
print_99 ( ) ; //正确。调用无参函数print_99 (void) ; //错误。实参表中不能加void

带参函数的调用格式

函数名(实参1,实参2,…);

说明:
1) 其中各实参可以是各种类型的常量、变量或表达式。例如,对定义好的带参函数 int add (int a,int b); 的调用如下。

 
   
   
 
add (2,5+1); //正确,实参可以为常量、变量或表达式 int n=7;add(3,n); //正确,实参可以是变量

2) 调用函数时,不能写函数类型。

 
   
   
 
int add(2,3);//错误,调用时不能加返回类型