为什么要采用自创函数?

在设计较复杂的程序时,一般采用自顶向下的方法,将问题划分为几个部分,各个部分再进行细化,直到分解为较好解决问题为止。
模块化程序设计是指在进行程序设计时将一个大程序按照功能划分为若干小程序模块,每个小程序模块完成一个确定的功能,并在这些模块之间建立必要的联系,通过模块的互相协作完成整个功能的程序设计方法。

在C语言中,使用自创函数可以很方便地解决此类问题,下面是一个代码样例:

#include <stdio.h>

int plus(int x,int y);  //此处有分号,表示函数的声明

int main()
{
	int a,b,c;
	a=1;
	b=2;
	c=plus(a,b);        //函数的调用
	printf("%d",c);
	return 0;
}

int plus(int x,int y)   //此处无分号,表示函数的定义
{
	int result;
	result=x+y;
	return result;
}

1.自创函数的写法

自创函数有两种写法:
第一种写法(即上述样例写法),在程序的最前面先声明,在main()函数后定义,这种也是最规范的写法:

#include <stdio.h>
int plus(int x,int y);  //此处有分号,表示函数的声明
int main()
{
	int a,b,c;
	a=1;
	b=2;
	c=plus(a,b);        //函数的调用
	printf("%d",c);
	return 0;
}
int plus(int x,int y)   //此处无分号,表示函数的定义
{
	int result;
	result=x+y;
	return result;
}

这种方法的优点是便于阅读,阅读者可以第一眼就从main()函数开始看,并且一眼看到有多少自创函数。

另一种方法是直接在主函数前定义函数:

#include <stdio.h>
int plus(int x,int y);  //此处无分号
{
	int result;
	result=x+y;
	return result;
}
int main()
{
	int a,b,c;
	a=1;
	b=2;
	c=plus(a,b);        //函数的调用
	printf("%d",c);
	return 0;
}

这种方法也可以正常运行,但是不方便阅读,主函数放在最后极大影响了代码的可读性。

2.函数的参数

#include <stdio.h>
int plus(int x,int y);
int main()
{
	int a,b,c;
	a=1;
	b=2;
	c=plus(a,b);
	printf("%d",c);
	return 0;
}
int plus(int x,int y)
{
	int result;
	result=x+y;
	return result;
}

函数名后面的括号为参数表,括号内表示接收的参数,函数可以不接收参数,也可以接收一个或多个参数。
注意:函数后参数表内定义的变量名仅仅是名字。例如:在本例中,变量x,y可以和变量a,b的名字不同。(因为函数的的本质是传值,这点放在下面会讲解)

3.函数的返回值

函数的返回值最多有一个,或者无返回值。
除了以void声明的函数以外,所有的函数都需要有返回值。(void中文翻译:无类型)
在自创函数里,如果你不需要返回值,那么可以用void来声明函数。
其他的自创函数中,函数有且仅有一个返回值。你可以选择主函数使用这个返回值,也可以把它丢弃,都是没问题的。

1.使用返回值:

#include <stdio.h>
int plus(int x,int y);
int main()
{
	int a,b,c;
	a=1;
	b=2;
	c=plus(a,b);	//函数的调用,并且被赋值给了c,在这里使用了返回值
	printf("%d",c);
	return 0;
}
int plus(int x,int y)
{
	int result;
	result=x+y;
	return result;
}

2.丢弃返回值

#include <stdio.h>
int plus(int x,int y);
int main()
{
	int a,b,c;
	a=1;
	b=2;
	plus(a,b);	//函数的调用,在这里,返回值没有被任何语句接收
	printf("%d",c);  //由于c没有被赋值,所以输出来的会是一个随机值(原先c这个空间内存的值)
	return 0;
}
int plus(int x,int y)
{
	int result;
	result=x+y;
	return result;
}

4.函数内变量的生存周期和作用域

函数内所有变量的作用域都在从变量声明时开始到函数结束时结束。
“变量声明”时开始:如果变量a是在函数的中间声明的,那么在函数的前一半部分,无法使用变量a。
“函数结束”时结束:例如在plus函数中创建的变量,无法在主函数中使用。同理,主函数中的变量也无法在自创变量中使用。
全局变量(声明在最前面,主函数的外面)可以在全局都使用。
一般的变量的生存周期都是会随着函数的结束而销毁,函数开始时为变量分配存储空间,函数结束时函数内的变量销毁,把空间释放。但是static型的变量的生存周期是全局,不会随着函数的结束而销毁。注:static变量的作用域依旧是从变量声明开始,到函数结束。

static变量的举例:

#include <stdio.h>
int plus(void);
int main()
{
	int x;
	x=plus;
	x=plus;
	x=plus;
	printf("%d",x);
	return 0;
}
int plus(int x,int y)
{
	static a=1;
	a++;
	return a;
}

5.“传值”函数

在当下的C语言标准中,函数接受参数的方式是传值调用,即变量的值仅仅是从主函数中传递给函数中的局部变量,而函数中的局部变量的值改变不会影响到主函数中的原变量。因此,我们称主函数中的原变量为实参,称自创函数中接受传值的变量为形参
举一个例子:

#include <stdio.h>
void swap(int a,int b);
int main()
{
	int a=1,b=2;
	swap(a,b);
	printf("%d %d",a,b);
	return 0;
}
int swap(int a,int b)
{
	int temp;
	temp=a;a=b;b=temp;   //此处代码为了交换a,b的值
}

程序运行结束,在输出中我们可以看到,a,b的值并没有交换。因为当swap()函数运行时,只是swap()函数内部的a,b进行了交换,而main()函数中的变量值并没有发生改变,函数仅仅是由主函数中的变量的值“传值”给该函数,并没有把主函数中的变量自身传递给swap()

那么最后的结果是什么样的呢?
主函数中的a的值依旧是1,b的值依旧是2。而swap()函数中的变量a,b都被销毁。

另:如果想要改变原变量的值的话,需要采用指针的方法,在此先不赘述。

6.变量的“就近”

#include <stdio.h>
int main()
{
	int a=1;
	{
		int a=2;
		printf("%d ",a);
	}
	printf("%d",a);
	return 0;
}

在一对{}内声明的变量,作用域和生存周期也不会超出这对{}(一切同上文所述规则)。
在这个例子中,第一条输出语句,输出的是与其最近的2,而不是1。
{}结束后,内部的a变量被销毁,因此第二条输出语句输出的是1.
注意,在同一个区域内,一个变量不能被重复声明。

7.一些其他细节

(1)C语言函数不允许嵌套定义。即在函数中可以调用函数,但是不能定义函数。
(2)在函数参数表中的逗号仅仅用于分隔变量,而不是逗号运算符。

int function((a,b))

在这里,逗号是作为逗号运算符。

int function(a,b)

在这里,逗号的含义仅仅用于分隔(和汉语中逗号作用相似)。