C语言之函数进击

C语言之函数进击

一、函数是啥

在计算机科学中,函数就是一个大型程序中的某部分代码,由一个或多个语句块组成,负责完成牟星特定任务,具备相对的独立性,各个函数的存在使得代码变得井井有条,可读性较高。

二、库函数

为了支持可移植性和提高程序的效率,一些程序员都可能用得到的基础功能就会被C语言的基础库中一系列类似的库函数所提供,方便进行软件开发。倘若没有库函数,那每个程序员都要整一套自己的基础功能函数,会加快秃头速度👱👱‍♀

想要了解库函数,必要的软件少不了,在这里博主向大家强烈推荐以下网站或者软件

www.cplusplus.com

http://en.cppreference.com (如果想要将该英文网站改成中文的模式,将en改成zh即可)

以及MSDN(Microsoft Developer Network)

话不多说,咱来了解库函数先,简单总结,库函数的类型大致分为这几种

  • IO函数(即输入输出函数) printf scanf getchar putchar
  • 字符串操作函数 strcmp strlen
  • 字符操作函数 toupper
  • 内存操作函数 memcpy memcmp memset
  • 时间/日期函数 time
  • 数学函数 sqrt pow
  • 其他库函数 …

注:库函数的使用必须包含#include对应的头文件,毕竟用了别人的库函数总得要打声招呼先

举个栗子✒️

strcpy (字符串复制函数)

在这里插入图片描述

代码举例:

#include <stdio.h>
#include <string.h>//strcpy函数的头文件
int main()
{
    char arr1[20] = { 0 };
    char arr2[20] = "Fighting!";
    strcpy(arr1,arr2);//将arr2里的内容复制到arr1当中
    printf("arr1:%s\n",arr1);//打印arr1
    printf("arr2:%s\n",arr2);//打印arr2
    return 0;
}

代码效果:

在这里插入图片描述

memset (内存初始化函数)

在这里插入图片描述

代码举例:

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[] = "Fighting!";
    printf("arr:%s\n",arr);//原来的arr打印
    memset(arr,'*',5);//将arr前五个字节替换为'*'
    printf("arr:%s\n",arr);//后来的arr打印
    return 0;
}

代码效果:

在这里插入图片描述

三、自定义函数

但是库函数无法解决所有问题,因为这要是啥都能干,程序员就要失业了

因此在这里更加重要的是自定义函数

自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设 计,这给程序员一个很大的发挥空间。

函数语法:
ret_type fun_name(para1, * )
{
 statement;//语句项,也就是函数的主体
}
ret_type 返回类型
fun_name 函数名
para1    函数参数,可以是多个,用,隔开,在这里我用*代表其他参数

举个栗子✒️

写一个函数可以找出俩个整数中的最大值

int get_max(int x, int y)
    //x和y是形式参数
{
	return (x > y)?(x):(y);
    //这里用到了条件操作符,x大于y吗,如果是真的返回x,假的返回y
}
int main()
{
	int a = 10;
	int b = 20;
	//函数的调用
	int max = get_max(a,b);//a和b是实参
	printf("max = %d\n", max);
	return 0;
}

代码效果:

在这里插入图片描述

实参?形参?

实际参数:真实传给函数的参数叫做实参(就比如本题目中的a,b),其类型包括常量、变量、表达式、函数等。不管是哪种类型的,在进行函数调用时,它们必须有确定的值,一遍吧这些值传送给形参

形式参数:函数名后括号中的变量就叫做形参(就比如本题目中的x,y),形参在函数被调用的过程中才会分配内存单元,当函数调用完成后就会自动销毁了,所以形参只在函数中有效

写一个函数可以交换俩整型变量的内容

传值调用?传址调用?

#include <stdio.h>
void Swap1(int x, int y)
{
 	int tmp = 0;
 	tmp = x;
 	x = y;
 	y = tmp;
}
void Swap2(int *px, int *py)
{
 	int tmp = 0;
	tmp = *px;
 	*px = *py;
 	*py = tmp;
}
int main()
{
 	int num1 = 1;
 	int num2 = 2;
 	Swap1(num1, num2);//传值调用,实参传给形参,其实形参是实参的一份临时拷贝
	printf("Swap1:num1 = %d num2 = %d\n", num1, num2);
	Swap2(&num1, &num2);//传址调用
	printf("Swap2:num1 = %d num2 = %d\n", num1, num2);
    return 0;
}

代码效果:

在这里插入图片描述

从这个结果中,深刻了解到传值调用和传址调用区别还是非常大的

函数解析:

在这里插入图片描述

因此

Swap1函数进行传值函数,只是将num1和num2的值传入了,形参x和y接收了值,通过中间变量tmp交换了x和y的值,然而形参x和y在函数调用结束后就会被销毁,所以num1和num2的值并没有被改变。

Swap2函数进行传址调用,将num1和num2的地址传给了整形指针变量px和py,通过中间变量tmp交换了px和py里的数值,也就是交换了num1和num2的值,所以俩整形变量里的内容交换任务得以实现

四、函数的嵌套调用和链式访问

函数与函数之间是可以有机结合的

嵌套调用

举个栗子✒️

#include <stdio.h>
void new_line()
{
 	printf("加油\n");
    //在new_line()函数中打印加油二字
}
void three_line()
{
    int i = 0;
    for(i=0; i<3; i++)
    {
        new_line();
        //在three_line()函数中嵌套调用new_line()函数
    }
}
int main()
{
 	three_line();
    //在main()函数中嵌套调用three_line()函数
 	return 0;
}

代码效果:

在这里插入图片描述

链式访问

把函数的返回值作为另一个函数的参数

举个栗子✒️

代码1:

#include <stdio.h>
#include <string.h>
int main()
{
    char arr[20] = "Hello";
    int ret = strlen(strcat(arr,"world"));
    //strcat函数调用后,返回arr里的内容"Helloworld"
    //strlen函数调用后,返回字符串的字符个数10
    printf("%d\n",ret);
    return 0;
}

代码效果:

在这里插入图片描述

说明:

strlen函数是计算字符串长度的函数

size_t strlen( const char *string )

从字符串string的某个位置(可以是字符串的开头,中间位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符’\0’为止,然后返回计数器size_t的值(不包括’\0’)

其头文件是#include <string.h>

strcat函数是字符串连接函数

char strcat(char *strDestination , const char*strSource)

strSource所指向的字符串(包括’\0’)复制到strDestination所指向的字符串后面(删除*strDestination原来末尾的’\0’),要保证*strDestination足够的长,以容纳被复制进来的*strSource,返回指向strDestination的指针的内容

其头文件是#include <string.h>

代码2:

#include <stdio.h>
int main()
{
    printf("%d",printf("%d",printf("%d",43)));
    //疯狂套娃之中
    //先输出43
    //因为43的字符个数是2,所以再输出2
    //因为2的字符个数是1,所以再输出1
    return 0;
}

代码效果:

在这里插入图片描述

说明:

printf函数是格式输出函数

int printf(const char *format [, argument]…)

该函数返回一个int类型的数值,代表输出的字符总数

其头文件是#include <stdio.h>

五、函数的声明和定义

函数声明

  • 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。其他具体是不是存在,无关紧要。
  • 函数的声明要满足先声明后使用。
  • 函数的声明一般要放在头文件中。
int Add(int x,int y);

函数定义

函数的定义是指函数的具体实现,交代函数的功能实现

#include "test.h"
//在头文件里声明了Add函数,引用自己的头文件要用""而不是<>
int Add(int x,int y)
{
    //Add函数的实现
    return x + y;
}

六、函数递归

什么是函数递归!请听下回讲解…

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

富春山居_ZYY(已黑化)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值