C语言基础-函数

函数

1、函数的概念

  • 我们对函数进行了简单的解释,函数(Function)是一段可以重复使用的代码,这是从整体上对函数的认识。

  • C语言本身带了很多库函数,并分门别类地放在了不同的头文件中,使用时只要引入对应的头文件即可。

  • 除了C语言自带的函数,我们也可以编写自己的函数,称为自定义函数(User-Defined
    Function)。自定义函数和库函数没有本质的区别,表现形式和使用方法一样,只是开发者不同而已。

2、如何编写和使用自己的函数。

2.1参数

函数的一个明显特征就是使用时带括号( ),必要的话,括号中还要包含数据或变量,称为参数(Parameter)。参数是函数需要处理的数据,
例如:

strlen(str1)用来计算字符串的长度,str1就是参数。

puts("hello")用来输出字符串," hello "就是参数。

2.2返回值

既然函数可以处理数据,那就有必要将处理结果告诉我们,所以很多函数都有返回值(Return Value)。所谓返回值,就是函数的执行结果。
例如:

char str1[] = "C Language";
int len = strlen(str1);

strlen() 的处理结果是字符串 str1 的长度,是一个整数,我们通过 len 变量来接收。
函数返回值有固定的数据类型(int、char、float等),用来接收返回值的变量类型要一致。

3、自定义函数

函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。
无参函数的定义
如果函数不接收用户传递的数据,那么定义时可以不带参数。如下所示:

返回值类型  函数名()
{

	函数体

}

说明:

*返回值类型可以是C语言中的任意数据类型,例如 int、float、char 等。
函数名是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
函数体是函数需要执行的代码。即使只有一个语句,也要由{ }包围。
在函数体中使用return语句返回数据。

*例如,定义一个函数,计算1加到100的结果:

int sum()
{
 int i, sum=0;
for(i=1; i<=100; i++)
{
    sum+=i;
}
return sum;
}

计算结果保存在变量sum中,通过return语句返回。sum为int型,所以返回值类型也必须为int,要一一对应。
return是C语言中的一个关键字,只能用在函数中,用来返回处理结果。
函数不能嵌套定义,main 也是一个函数定义,要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 只能在 main 前面。

注意:
main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。

无返回值函数

有的函数不需要有返回值,或者返回值类型不确定(很少见),那么用void表示,例如:

void hello()	
{
printf ("Hello,world\n");
 //没有返回值就不需要 return 语句
}

void是C语言中的一个关键字,表示空类型或无类型,绝大部分情况下也就意味着没有 return 语句。

有参函数的定义

如果函数需要接收用户传递的数据,那么定义时就要带参数。如下所示:

返回值类型  函数名(参数列表)
{
	函数体
}

用户数据通过“参数列表”传递给函数,供函数处理。
例如,定义一个函数求两个数中的最大值:

int max(int a, int b)
{
if (a>b)
{
    return a;
}
else
{
    return b;
}
}
  • 参数(Parameter)本质上也是变量,定义时要指明参数类型和参数名称。
  • 参数列表中可以定义一个或多个参数,多个参数之间用逗号,分隔。
  • 参数列表中给出的参数可以在函数体中使用。

调用 max() 函数时可以直接传递整数:

int n = max(10, 20);

也可以传递变量:

int a = 10, b = 20;

int n = max(a, b);

也可以整数和变量一起传递:

int a = 10;
int n = max(a, 20);

变量 n 得到的值都是20。

函数定义时给出的参数称为形式参数,简称形参
函数调用时给出的参数(传递的数据)称为实际参数,简称实参
函数调用时,将实参的值传递给形参,相当于一次赋值操作。
注意:实参和形参的类型、数目必须一致。

定义max时,变量a、b的值都是未知的;
调用max时,分别将num1、num2的值传递给a、b,类似于:

a=num1;
b=num2;
  1. return 语句可以有多个,可以在函数体的任意位置。
  2. 在max中,根据 if 的判断结果来执行不同的 return 语句。
  3. 函数一旦遇到 return 语句就返回(停止执行),后面的所有语句都不会被执行到,

例如:

int max(int a, int b)
{
	int n = (a>b) ? a : b;
	return n;
	printf("Function is performed\n");
}

第4行代码是多余的,永远没有执行的机会。

4、函数的参数与返回值

斜体样式如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;函数的作用就是根据不同的参数产生不同的返回值。

函数的参数
形参:
在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参
实参:
函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参

形参和实参的功能是作数据传送,发生函数调用时,实参的值会传送给形参。

形参和实参有以下几个特点:

  1. 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

  2. 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

  3. 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。

    函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。
    因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

【示例】计算 1+2+3+…+(n-1)+n 的值。

#include <stdio.h>
int sum(int n)
{
int i;
for(i=n-1; i>=1; i--)
{
    n+=i;
}
printf("The inner n =%d\n",n);
return n;
}

int main()
{
int m, total;
printf("Input anumber: ");
scanf("%d",&m);
total = sum(m);
printf("The outer m =%d \n", m);
printf("1+2+3+...+%d+%d = %d\n", m-1, m, total);
return 0;
}

运行结果:

Input a number: 100↙

The inner n = 5050

The outer m = 100

1+2+3+…+99+100 = 5050

通过 scanf 输入 m 的值,作为实参,在调用 sum 时传送给形参 n。
从运行情况看,输入 m 值为100,即实参 m 的值为100,把这个值传给函数 sum 时,形参 n 的初值也为100,在函数执行过程中,形参 n 的值变为 5050。函数运行结束后,输出实参 m 的值仍为100,可见实参的值不随形参的变化而变化。

函数的返回值

函数的返回值是指函数被调用之后,执行函数体中的程序段所取得的值,可以通过return语句返回。

return语句的一般形式为:
return 表达式;
或者:
return (表达式);

例如:

return max;

return a+b;

return (100+200);

函数中可以有多个 return 语句,但每次调用只能有一个return 语句被执行,所以只有一个返回值。

一旦遇到 return 语句,不管后面有没有代码,函数立即运行结束,将值返回。例如:

int func()
{
int a=100, b=200, c;
return a+b;
return a*b;
return b/a;
}

返回值始终 a+b 的值,也就是300。

没有返回值的函数为空类型,用void进行说明。例如:

void func()
{
printf("Hello world!\n");
}

一旦函数的返回值类型被定义为 void,就不能再接收它的值了。例如,下面的语句是错误的:

int a = func();

为了使程序有良好的可读性并减少出错,
凡不要求返回值的函数都应定义为 void 类型。

5、函数的声明与原型

C语言代码由上到下依次执行,原则上函数定义要出现在函数调用之前,否则就会报错。但在实际开发中,经常会在函数定义之前使用它们,这个时候就需要提前声明。

所谓声明(Declaration),就是告诉编译器我要使用这个函数,你现在没有找到它的定义不要紧,请不要报错,稍后我会把定义补上。

函数声明的格式非常简单,相当于去掉函数定义中的函数体再加上分号;,如下所示:

返回值类型  函数名( 类型 形参, 类型形参… );

也可以不写形参,只写数据类型:

返回值类型  函数名( 类型, 类型…);

函数声明给出了函数名、返回值类型、参数列表(参数类型)等与该函数有关的信息,称为函数原型(Function Prototype)。

函数原型的作用是告诉编译器与该函数有关的信息,让编译器知道函数的存在,以及存在的形式,即使函数暂时没有定义,编译器也知道如何使用它。

有了函数声明,函数定义就可以出现在任何地方了,甚至是其他文件、静态链接库、动态链接库等。

上节给出了计算sum = 1! + 2! + 3! + … + (n-1)! + n!的代码,这节我们稍作修改,将 factorial() 和 sum() 函数的定义放到 main() 函数后面,请看下面的代码:

#include <stdio.h>
// 函数声明
long factorial(int n);  //也可以写作 long factorial(int);
long sum(long n);  //也可以写作 long sum(long);

int main()
{  
	printf("1!+2!+...+9!+10! = %ld\n", sum(10));
	return 0;
}

//求阶乘

long factorial(int n)
{
	int i;
	long result=1;
	for(i=1; i<=n; i++)
	{
    	result *= i;
    	}
    return result;
}

// 求累加的和

long sum(long n)
{
int i;
long result = 0;
for(i=1; i<=n; i++)
{ 
    //嵌套调用
    result +=factorial(i);
}
return result;
}

运行结果:

1!+2!+…+9!+10! = 4037913

我们知道,使用 printf()、puts()、scanf()、getchar() 等函数要引入 stdio.h 这个头文件,很多初学者认为 stdio.h 中包含了函数定义(也就是函数体),只要有了头文件程序就能运行。其实不然,头文件中包含的都是函数声明,而不是函数定义,函数定义都在系统库中,只有头文件没有系统库在链接时就会报错,程序根本不能运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C君莫笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值