再识C语言 DAY12 【再识函数(上)】


前言

本文章总结于此文章


一、函数是什么?

函数的本质是一段可以重复使用的代码,这段代码被提前编写好了,放到了指定的文件中,使用时直接调取即可。
例如,strcmp() 是一个用来比较字符串大小的函数,它的用法如下:

#include <stdio.h>
#include <string.h>
int main()
{
    char str1[] = "http://c.biancheng.net";
    char str2[] = "http://www.baidu.com";
    //比较两个字符串大小
    int result = strcmp(str1, str2);
    printf("str1  - str2 = %d\n", result);
    return 0;
}

str1 和 str2 是传递给 strcmp() 的参数,strcmp() 的处理结果赋值给了变量 result

int result = strcmp(str1, str2);

比较字符串大小是常用的功能,一个程序可能会用到很多次,如果每次都写这样一段重复的代码,不但费时费力、容易出错,而且交给别人时也很麻烦,所以C语言提供了一个功能,允许我们将常用的代码以固定的格式封装(包装)成一个独立的模块,只要知道这个模块的名字就可以重复使用它,这个模块就叫做函数(Function)

函数的本质是一段可以重复使用的代码,这段代码被提前编写好了,放到了指定的文件中,使用时直接调取即可。下面我们就来演示一下如何封装 strcmp() 这个函数。

二、自定义函数

  • 函数组成部分
int main()
{
reuturn 0;
}

int :返回值类型
main: 函数名 ==> 标识符 (只是一个名字,随便起)
()= 描述参数
return 0 函数返回值
函数定义的格式
函数返回值类型 函数名(形参)
{
函数体
return 返回值
}

参数

函数的一个明显特征就是使用时带括号( ),有必要的话,括号中还要包含数据或变量,称为参数(Parameter)。参数是函数需要处理的数据,例如:
strlen(str1)用来计算字符串的长度,str1就是参数。
puts(“C语言中文网”)用来输出字符串,"C语言中文网"就是参数。

返回值

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

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

strlen() 的处理结果是字符串 str1 的长度,是一个整数,我们通过 len 变量来接收。

函数返回值有固定的数据类型(int、char、float等),用来接收返回值的变量类型要一致。

所以到底什么是返回值,如果你感到很懵,先别急,后面会详细讲。

先举一个例子:

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

运行结果: The sum is 5050

我们发现了一个 return sum;字面意思就是返回了 sum 的值,既然她返回了一个值,他去了哪里呢?为什么 int sum() 不和 int main() 一样是return 0;呢?

我们发现把return sum;改为 return 0; 时。运行结果: 0.
把return sum;改为 return 3; 时。运行结果: 3.

不难发现 return sum; 的确返回了 sum函数的值

我们知道函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。

上面的例子明显接收用户传递的数据 sum.

所以说,返回值返回的是变量的值

再来一个例子:

把一个数组中最大的值找出来

#include <stdio.h>
int FindMAX(int *array,int Count)
{
	int i;
	int max = array[0];
	for (i = 0; i <Count ; i++)//count函数可以用来统计字符串中某个字符的个数,或数组中某个元素的数量
	{
		if (array[i] > max)
		{
			max = array[i];
		}
	}
	return max;
 }
int main(void)
{
	int MAX;
	int a[] = { 12,6,9,34,21,7 };
	MAX = FindMAX(a,6);
	printf("MAX=%d\n", MAX);
   	return 0;
}

注:count函数可以用来统计字符串中某个字符的个数,或数组中某个元素的数量

这里是引用

void修饰函数的返回值和参数

1.void用来作为函数返回值

代码示例1:

#include <stdio.h>
#include <windows.h>
void show()
{
printf("no return value!\n");
}
int main()
{
show();
system("pause");
return 0;
}

输出结果:
在这里插入图片描述
示例2:
在这里插入图片描述
直接返回return 1也是可以通过编译的,且不会有警告

return 0指程序运行结束;
return 1指返回主调函数,程序继续运行。

但如果有变量去接收则会报错
在这里插入图片描述
2.void作为函数参数

如果一个函数没有参数,我们可以不写, 如test1()

代码示例:

//如果一个函数没有参数,我们可以不写, 如test1()
#include <stdio.h>
#include <windows.h>
int test1() //函数默认不需要参数
{
return 1;
}
int test2(void) //明确函数不需要参数
{
return 1;
}
int main()
{
printf("%d\n", test1(10)); //依旧传入参数,编译器不会告警或者报错
printf("%d\n", test2(10)); //依旧传入参数,编译器会告警(vs)或者报错(gcc)
system("pause");
return 0;
}

函数不能嵌套定义

强调一点,C语言不允许函数嵌套定义;也就是说,不能在一个函数中定义另外一个函数,必须在所有函数之外定义另外一个函数。main() 也是一个函数定义,也不能在 main() 函数内部定义新函数。

下面的例子是错误的:

#include <stdio.h>
void func1()
{
    printf("http://c.biancheng.net");
    void func2()
    {
        printf("C语言小白变怪兽");
    }
}
int main()
{
    func1();
    return 0;
}

有些初学者认为,在 func1() 内部定义 func2(),那么调用 func1() 时也就调用了 func2(),这是错误的。

正确的写法应该是这样的:

#include <stdio.h>
void func2() 
{
    printf("\nC语言小白变怪兽");
}
void func1() 
{
    printf("http://c.biancheng.net");
    func2();
}
int main() {
    func1();
    return 0;
}

要想达到「调用 func1() 时也调用 func2()」的目的,必须将 func2() 定义在 func1() 外面,并在 func1() 内部调用 func2()。

形参和实参的区别

形参(形式参数)

在函数定义中出现的 参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数 简称形参。

实参(实际参数)

函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数, 简称实参。

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

补充
占位符就是先占住一个固定的位置,等着你再往里面添加内容的符号,广泛用于计算机中各类文档的编辑

请看下面的例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//计算从m加到n的值
int sum(int m, int n)
 {
    int i;
    for (i = m+1; i <= n; ++i) 
    {
        m += i;
    }
    return m;
}
int main() 
{
    int a, b, total;
    printf("Input two numbers: ");
    scanf("%d %d", &a, &b);
    total = sum(a, b);
    printf("a=%d, b=%d\n", a, b);
    printf("total=%d\n", total);
    return 0;
}

在这里插入图片描述

++i先自增1再赋值。 i++先赋值再自增1 在这里用两个都可以。

在这段代码中,函数定义处m、n 是形参 , 函数调用处a、b 是实参。通过 scanf() 可以读取用户输入的数据,并赋值给 a、b,在调用 sum() 函数时这份数据会传递给形参 m、n。

从运行情况看,输入 a 值为 1,即实参 a 的值为 1,把这个值传递给函数 sum() 后,形参 m 的初始值也为 1,在函数执行过程中,形参 m 的值变为 5050。函数运行结束后,输出实参 a 的值仍为 1,可见实参的值不会随形参的变化而变化。

以上调用 sum() 时是将变量作为函数实参,除此以外,你也可以将常量、表达式、函数返回值作为实参,如下所示:

total = sum(10, 98);  //将常量作为实参
total = sum(a+10, b-3);  //将表达式作为实参
total = sum( pow(2,2), abs(-100) );  //将函数返回值作为实参

形参和实参可以同名,因为他们相互独立,互不影响。因为实参在函数外有效,形参在函数内有效。

请看下面的例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//计算从m加到n的值
int yuo(int a, int b)
{
	int i;
	for (i=1+a ;i<=b;i++)
	{
		a += i ;
		  }
	return a ;
}
 int main()
{
	int a, b,sum;
	printf("请输入两个数字:\n");
	scanf("%d %d", &a, &b);
	printf("%d  %d", a, b);
	sum = yuo(a, b);
	printf("\ntotal: %d", sum);
		return 0;
}

运行:
在这里插入图片描述
调用 yuo() 函数后,函数内部的形参 m 的值已经发生了变化,而函数外部的实参 m 的值依然保持不变,可见它们是相互独立的两个变量,除了传递参数的一瞬间,其它时候是没有瓜葛的。

错误示范:

这种情况下,a<=b表达的意思就和我们的想法有误了(a的值并不是每次加一),所以要引进变量 i ,让 i 的值做到每次加一

	for (a ;a<=b;a++)
	{
		a += a + 1;
		  }
	return a ;
}

return的用法

函数的返回值是指函数被调用之后,执行函数体中的代码所得到的结果,这个结果通过 return 语句返回。

对C语言返回值的说明:

  1. 没有返回值的函数为空类型,用void表示。例如:
void func()
{
    printf("http://c.biancheng.net\n");
}

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

int a = func();

但我们可以这样用:

#include <stdio.h>
void func()
{
    printf("http://c.biancheng.net\n");
}
int main ()
{
func();
return 0;
}

是可以输出的:

在这里插入图片描述

函数一旦遇到 return 语句就立即返回,后面的所有语句都不会被执行到了。从这个角度看,return语句还有强制结束函数执行的作用

下面我们举个例子,还是以判断素数为题,并且要使用函数和 void,return:

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
void PUA(int a)
{
	int i;
	bool flog = 1;
	if (a < 0)
	{
		printf("%d其不是素数",a);
		return;
		  }
	for (i = 2;i < a;i++)
	{
		if (a % i == 0)
		{
			flog = 0;
			break;
		}
	}
	   if(flog)
	   {
		   printf("\n%d其是素数",a);
		  }
	   else
	   {
		   printf("\n%d其不是素数",a);
	   }
	 }
  int main()
{
	int num;
	printf("输入一个数字:");
	scanf("%d", &num);
	PUA(num);
    return 0;
}

运行没问题:

在这里插入图片描述
注:if(x) 当x = 0时 表达式为假,不输出,x 不为0时,表达式为真,可以输出。

补充if……else if……else……的用法

格式:

            if(1)

                    A;        // 如果1成立,执行A

            else if(2)

                    B;        //  如果1不成立,2成立,执行B

            else if(3)

                    C;        // 如果1、2不成立,3成立,执行C

            ……

            else

                    D;        // 如果1、2、3均不成立,执行D

————————————————

                        版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_54110690/article/details/122519943

所以 return 语句是提前结束函数的唯一办法

后面会讲解“函数调用,函数声明以及函数原型,块级变量,归函数”等等内容

如果您发现文章有错误请与我留言,感谢

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

马职音人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值