C语言中的函数

服务器君一共花费了15.610 ms进行了6次数据库查询,努力地为您提供了提供了这个页面。

C 语言中的函数等价于 Fortran 语言中的子程序或函数,也等价于 Pascal 语言中的过程或函数。函数为计算的封装提供了一种简便的方法,此后使用函数时不需要考虑它是如何实现的。使用设计正确的函数,程序员无需考虑功能是如何实现的,而只需知道它具有哪些功能就够了。在 C 语言中可以简单、方便、高效地使用函数。我们经常会看到在定义后仅调用了一次的短函数,这样做可以使代码段更清晰易读。

到目前为止,我们所使用的函数(如 printf、getchar 和 putchar 等)都是函数库中提供的函数。现在,让我们自己动手来编写一些函数。C 语言没有像 Fortran 语言一样提供类似于**的求幂运算符,我们现在通过编写一个求幂的函数 power(m, n)来说明函数定义的方法。power(m, n)函数用于计算整数 m 的 n 次幂,其中 n 是正整数。对函数调用 power(2,5)来说,其结果值为 32。该函数并非一个实用的求幂函数,它只能处理较小的整数的正整数次幂,但这对于说明问题已足够了。(标准库中提供了一个计算 xy 的函数 pow(x, y)。)

下面是函数 power(m, n)的定义及调用它的主程序,这样我们可以看到一个完整的程序结构。

#include <stdio.h>
int power(int m, int n);

/* test power function */
main()
{
	int i;
	for (i = 0; i < 10; ++i)
	printf("%d %d %d\n", i, power(2,i), power(-3,i));
	return 0;
}

/* power: raise base to n-th power; n >= 0 */
int power(int base, int n)
{
	int i, p;
	p = 1;
	for (i = 1; i <= n; ++i)
		p = p * base;
	return p;
}

函数定义的一般形式为:

返回值类型 函数名(0 个或多个参数声明)
{
	声明部分
	语句序列
}

函数定义可以以任意次序出现在一个源文件或多个源文件中,但同一函数不能分割存放在多个文件中。如果源程序分散在多个文件中,那么,在编译和加载时,就需要做更多的工作,但这是操作系统的原因,并不是语言的属性决定的。我们暂且假定将 main 和 power 这两个函数放在同一文件中,这样前面所学的有关运行 C 语言程序的知识仍然有效。

main 函数在下列语句中调用了两次 power 函数:printf("%d %d %d\n", i, power(2, i), power(-i, 3)); 每次调用时,main 函数向 power 函数传递两个参数;在调用执行完成时,power 函数向 main 函数返回一个格式化的整数并打印。在表达式中,power(2, i)同 2 和 i 一样都是整数

power 函数的第一行语句 int power(int base, int n) 声明参数的类型、名字以及该函数返回结果的类型。power 函数的参数使用的名字只在 power 函数内部有效,对其它任何函数都是不可见的:其它函数可以使用与之相同的参数名字而不会引起冲突。变量 i 与 p 也是这样:power 函数中的 i 与 main 函数中的 i 无关。

我们通常把函数定义中圆括号内列表中出现的变量称为形式参数,而把函数调用中与形式参数对应的值称为实际参数。

power 函数计算所得的结果通过 return 语句返回给 main 函数。关键字 return 的后面可以跟任何表达式,形式为: return 表达式;

函数不一定都有返回值。不带表达式的 return 语句将把控制权返回给调用者,但不返回有用的值。这等同于在到达函数的右终结花括号时,函数就“到达了尽头”。主调函数也可以忽略函数返回的值。

读者可能已经注意到,main 函数的末尾有一个 return 语句。由于 main 本身也是函数,因此也可以向其调用者返回一个值,该调用者实际上就是程序的执行环境。一般来说,返回值为 0 表示正常终止,返回值为非 0 表示出现异常情况或出错结束条件。为简洁起见,前面的 main 函数都省略了 return 语句,但我们将在以后的 main 函数中包含 return 语句,以提醒大家注意,程序还要向其执行环境返回状态。

出现在 main 函数之前的声明语句 int power(int m, int n); 表明 power 函数有两个 int 类型的参数,并返回一个 int 类型的值。这种声明称为函数原型,它必须与 power 函数的定义和用法一致。如果函数的定义、用法与函数原型不一致,将出现错误。

函数原型与函数声明中参数名不要求相同。事实上,函数原型中的参数名是可选的,这样上面的函数原型也可以写成以下形式: int power(int, int);

但是,合适的参数名能够起到很好的说明性作用,因此我们在函数原型中总是指明参数名。

回顾一下,ANSI C 同较早版本 C 语言之间的最大区别在于函数的声明与定义方式的不同。按照 C 语言的最初定义,power 函数应该写成下列形式:

/* power: raise base to n-th power; n >= 0 */
/* (old-style version) */
power(base, n)
int base, n;
{
	int i, p;
	p = 1;
	for (i = 1; i <= n; ++i)
	p = p * base;
	return p;
}

其中,参数名在圆括号内指定,参数类型在左花括号之前声明。如果没有声明某个参数的类型,则默认为 int 类型。函数体与 ANSI C 中形式相同。

在 C 语言的最初定义中,可以在程序的开头按照下面这种形式声明 power 函数:int power();

函数声明中不允许包含参数列表,这样编译器就无法在此时检查 power 函数调用的合法性。事实上,power 函数在默认情况下将被假定返回 int 类型的值,因此整个函数的声明可以全部省略。

在 ANSI C 中定义的函数原型语法中,编译器可以很容易检测出函数调用中参数数目和类型方面的错误。ANSI C 仍然支持旧式的函数声明与定义,这样至少可以有一个过渡阶段。但我们还是强烈建议读者:在使用新式的编译器时,最好使用新式的函数原型声明方式。

下面给出MFC上的实现:

void CNowaMagic_MFCDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnOK();
	//获得EDIT 
	CEdit* base;
	CEdit* n;
	base = (CEdit*) GetDlgItem(IDC_EDIT1);
	n = (CEdit*) GetDlgItem(IDC_EDIT2);

	CString str1;
	CString str2;
	CString showStr;

	char tmp[10] = "";
	base -> GetWindowText(str1);
	n -> GetWindowText(str2);

	//char* pstr = (LPTSTR)LPCTSTR(str1); 
	int my_base = _ttoi(str1); 
	int my_n = _ttoi(str2);

	int result = power(my_base, my_n);
	
	showStr = itoa(result,tmp,10);

	CString str = _T("乘方运算结果为:");

	MessageBox(str + showStr,_T("程序运行结果"),MB_OK);
	str.ReleaseBuffer();
}

int power(int base, int n)
{
	int i, p;
	p = 1;
	for (i = 1; i <= n; ++i)
		p = p * base;
	return p;
}

程序运行结果:

  • CString转int可以使用 int my_base = _ttoi(str1);
  • 函数声明注意要写到头函数中。

Creative Commons License

本文仅供自己学习与收藏之用,请勿转载,请勿用作其它用途(如商业目的等)。 原文链接:http://www.nowamagic.net/librarys/posts/c/187