C 语言函数及示例:递归与内联

C语言中的函数是什么?

C语言中的函数是一段可重用的代码,它使程序更易于理解、测试,并且可以在不更改调用程序的情况下轻松修改。函数划分代码并模块化程序,以获得更好、更有效的结果。简而言之,一个大型程序被划分为多个子程序,这些子程序称为函数。

What is a Function in C

当您将一个大型程序划分为多个函数时,可以轻松地单独管理每个函数。每当程序中出现错误时,您可以轻松地找出有问题的函数并仅纠正这些错误。您可以根据需要轻松调用和使用函数,这会自动节省时间和空间。

库函数与用户定义函数

每个“C”程序至少有一个函数,即main函数,但一个程序可以有任意数量的函数。C语言中的main()函数是程序的起点。

在“C”编程中,函数分为两种类型:

  1. 库函数
  2. 用户定义函数

库函数与C语言中用户定义函数之间的区别在于,我们无需为库函数编写代码。它已包含在我们始终在程序开头包含的头文件中。您只需键入函数名称并使用正确的语法即可。Printf、scanf是库函数的例子。

而用户定义函数是一种函数,我们需要为其编写函数体,并在需要函数执行某些操作时调用该函数。

C语言中的用户定义函数始终由用户编写,但之后它可以成为“C”库的一部分。这是C编程的一大优势。

C编程函数分为三个活动,例如:

  1. 函数声明
  2. 函数定义
  3. 函数调用

函数声明

函数声明意味着编写程序的名称。它是代码中使用函数的强制性部分。在函数声明中,我们只指定将在程序中使用的函数的名称,就像变量声明一样。除非在程序中声明了函数,否则无法使用它。函数声明也称为“函数原型”。

函数声明(称为原型)通常在main()函数上方完成,并采用通用形式:

return_data_type function_name (data_type arguments);
  • return_data_type:是函数返回给调用语句的值的数据类型。
  • function_name:后面跟着括号。
  • 参数的名称及其数据类型声明可选地放在括号内。

我们考虑以下程序,该程序显示如何声明一个立方函数来计算整数变量的立方值。

#include <stdio.h>
/*Function declaration*/
int add(int a,b);
/*End of Function declaration*/
int main() {

请记住,函数不一定返回一个值。在这种情况下,使用关键字void。

例如,output_message函数声明表示该函数不返回值:void output_message();

函数定义

函数定义仅仅是编写函数体。函数体由将执行特定任务的语句组成。函数体由单个语句或语句块组成。它也是函数的一个强制性部分。

int add(int a,int b)	//function body	
{
	int c;
	c=a+b;
	return c;
}

函数调用

函数调用是指在程序中需要时调用函数。每当我们调用一个函数时,它就会执行其设计的功能。函数调用是程序的可选部分。

  result = add(4,5);

这是完整的代码:

#include <stdio.h>
int add(int a, int b);	//function declaration
int main()
{
	int a=10,b=20;
	int c=add(10,20); 	//function call
	printf("Addition:%d\n",c);
	getch();
}
int add(int a,int b)	//function body
{
	int c;
	c=a+b;
	return c;
}

输出

Addition:30

函数参数

函数的参数用于接收函数调用所需的必要值。它们按位置匹配;第一个参数传递给第一个参数,第二个参数传递给第二个参数,依此类推。

默认情况下,参数按值传递,即将数据的副本传递给被调用函数。实际传递的变量不会改变。

我们考虑以下程序,它演示了按值传递的参数。

int add (int x, int y); 
int main() {
  int a, b, result;
  a = 5;
  b = 10;
  result = add(a, b);
  printf("%d + %d\ = %d\n", a, b, result);
return 0;}
int add (int x, int y) { 
x += y;
  return(x);}

程序输出为:

5 + 10 = 15

请记住,传递给add函数的a和b的值没有改变,因为只有它的值传递给了参数x。

变量作用域

变量作用域是指变量在程序代码中的可见性。

在C语言中,在函数内声明的变量仅限于该代码块,不能在函数外部引用。但是,在所有函数外部声明的变量是全局变量,可以从整个程序访问。在程序顶部使用#define声明的常量可以从整个程序访问。我们考虑以下程序,该程序从main函数和用户定义函数中打印全局变量的值。

#include <stdio.h>
int global = 1348;
void test();
int main() {
  printf("from the main function : global =%d \n", global);
  test () ;
return 0;}

void test (){
printf("from user defined function : global =%d \n", global);}

结果

from the main function : global =1348
from user defined function : global =1348

我们讨论程序的细节:

Variable Scope

  1. 我们声明一个整数全局变量,初始值为1348。
  2. 我们声明并定义一个test()函数,该函数既不接受参数也不返回值。此函数仅打印全局变量的值,以演示全局变量可以在程序的任何位置访问。
  3. 我们在main函数中打印全局变量。
  4. 我们调用test函数以打印全局变量的值。

在C语言中,当参数传递给函数参数时,参数充当局部变量,这些局部变量在退出函数时将被销毁。

当您使用全局变量时,请谨慎使用它们,因为它们可能导致错误,并且它们可以在程序中的任何位置更改。它们在使用前应进行初始化。

静态变量

静态变量具有局部作用域。但是,它们在退出函数时不会被销毁。因此,静态变量将永远保留其值,并且可以在重新进入函数时访问。静态变量在声明时进行初始化,并且需要前缀static。

以下程序使用静态变量:

#include <stdio.h>
void say_hi();
int main() {    
  int i;
  for (i = 0; i < 5; i++) { say_hi();}
   return 0;}
void say_hi() {
  static int calls_number = 1;
  printf("Hi number %d\n", calls_number);
  calls_number ++; }

程序显示:

Hi number 1
Hi number 2
Hi number 3
Hi number 4
Hi number 5

递归函数

考虑一个数字的阶乘,其计算方式如下:6! = 6 * 5 * 4 * 3 * 2 * 1。

此计算是通过重复计算fact * (fact -1)直到fact等于1来完成的。

递归函数是调用自身的函数,并且包含退出条件以结束递归调用。对于阶乘数计算,退出条件是fact等于1。递归通过“堆叠”调用直到满足退出条件来工作。

例如

#include <stdio.h>
int factorial(int number);
int main() {    
  int x = 6;
  printf("The factorial of %d is %d\n", x, factorial(x)); 
  return 0;}
int factorial(int number) {
 if (number == 1)    return (1); /* exiting condition */
  else
    return (number * factorial(number - 1));
}

程序显示:

 The factorial of 6 is 720

在此,我们讨论程序的细节:

Recursive Functions

  1. 我们声明我们的递归阶乘函数,该函数接受一个整数参数并返回该参数的阶乘。此函数将调用自身并减少数字,直到达到退出条件或基本条件。当条件为真时,先前生成的值将相互乘,并返回最终的阶乘值。
  2. 我们声明并初始化一个整数变量,值为“6”,然后通过调用我们的阶乘函数来打印其阶乘值。

请考虑以下图表,以更深入地理解递归机制,该机制包括调用函数本身,直到达到基本情况或停止条件,然后我们收集先前的值。

Recursive Functions

内联函数

C语言编程中的函数用于存储最常用的指令。它用于模块化程序。

每当调用一个函数时,指令指针就会跳转到函数定义。在执行完函数后,指令指针会跳回到跳转到函数定义的位置。

当我们使用函数时,我们需要一个额外的指针头来跳转到函数定义并返回到语句。为了消除这种指针头的需要,我们使用内联函数。

在内联函数中,函数调用直接被实际程序代码替换。它不会跳转到任何块,因为所有操作都在内联函数内部执行。

内联函数主要用于小型计算。它们不适合涉及大量计算的情况。

内联函数与普通函数类似,不同之处在于关键字inline放置在函数名称之前。内联函数使用以下语法创建:

inline function_name ()
{
    //function definition
}

让我们编写一个程序来实现内联函数。

inline int add(int a, int b)		//inline function declaration
{
	return(a+b);
}
int main()
{
	int c=add(10,20);
	printf("Addition:%d\n",c);
	getch();
}

输出

Addition: 30

上面的程序演示了内联函数用于两个数字的加法。如我们所见,我们在内联函数中仅返回两个数字的加法,而无需编写任何额外的行。在函数调用期间,我们只传递了需要执行加法的数值。

摘要

  • 函数是小程序或子程序。
  • 函数用于模块化程序。
  • 库函数和用户定义函数是两种类型的函数。
  • 函数由声明、函数体和函数调用部分组成。
  • 函数声明和函数体是强制性的。
  • 函数调用在程序中可以是可选的。
  • C程序至少有一个函数;它是main()函数。
  • 每个函数都有一个名称、返回值的数据类型或void,以及参数。
  • 每个函数都必须在您的C程序中定义和声明。
  • 请记住,C函数中的普通变量在退出函数调用后即被销毁
  • 传递给函数的参数不会改变,因为它们是按值传递的,而不是按地址传递的。
  • 变量作用域是指程序中变量的可见性。
  • C编程中有全局变量和局部变量。