【初阶C语言】认识和使用函数

这篇具有很好参考价值的文章主要介绍了【初阶C语言】认识和使用函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 函数是什么
2. 库函数
3. 自定义函数
4. 函数参数
5. 函数调用
6. 函数的嵌套调用和链式访问
7. 函数的声明和定义
8. 函数递归

一、什么是函数

在数学中有函数,在C语言中也有函数,我们直接先给出一个定义:

在基维百科中函数被定义为子程序:

         在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method,
subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组
成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。
一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。

例如:main函数、printf打印函数等等,都是C语言中的函数。

我们可以把函数比作一个工厂,把东西送进去加工,出来就会变成你想要的产品。

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 函数的基本构成:函数名、返回类型、函数参数和函数体


在C语言中,函数有两大类,库函数和自定义函数,下面一一介绍。

二、库函数

1.来源:C语言的基础库中提供了一系列库函数

2.库函数:

         将函数比作加工厂,那么库函数就是已经搭建好的有专属名字的工厂。我们只需要把原材料(数据)送入该工厂,然后接收产品(结果)即可。我们举个例子:

  • 计算字符串的长度:
char arr[]="love";//用数组来存放字符串
#include<stdio.h>
#include<string.h>
int main()
{
  char arr[]="love";//定义的数组(原材料)
  int ret=0;//定义一个变量记录字符串的长度(接收产品)
  ret strlen(arr);//送入工厂
  printf("%d\n",ret);//printf也是库函数
  return 0;
}

我们很清楚的看到,只需要把数组名字arr放入strlen函数中,再用变量ret接收产品就可以。

  • 数组名就是首元素的地址,通过首地址就可以找到整个字符串的内容,所以只需要把arr送入函数里面就可以。

注:
    但是库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件。所以为什么会有#include<stdio.h>(main函数、printf函数等函数需要包含的)、#include<string.h>(strlen函数需要包含)这些东西。下面我们通过库函数的分类大概确定每种库函数需要使用头文件的类别

3.库函数分类

     一系列功能相近的函数

  • IO函数

        输入输出函数---<stdio.h>

  • 字符串操作函数

         strlen strcpy

  • 字符操作函数

        判断字母大小写、转换等等

  • 内存操作函数
  • 时间/日期函数
  • 数学函数

        <math.h>,如:Pow

  • 其他库函数

4.库函数举例 

     pow函数:用来计算次方,如:2^3=8

函数原型

double pow (double base, double exponent);//函数原型

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 参数类型:该函数可以计算小数的幂,精度更高,所以也可以计算整形的变量。所以得出来的结果最高可以为小数,所以返回值是double类型。

函数参数:因为可以计算小数,所以参数的类型也可以是double类型。

第一个参数(double base)是底数,第二个参数(double exponent)是幂。

所以我们只需要把原材料(要计算的数)送到函数里面(工厂)就可以得出结果(产品)

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 用法:我们现在要计算2^3的结果,只需要送进函数里面就行。

#include<tsdio.h>
#include<math.h>//pow函数需要包含的头文件
int main()
{
  int n=0;//创建一个变量用于接收计算的结果
  //n=pow(2,3);这样也可以,不过编译器会有警告
  n=(int)pow(2,3);
  printf("%d\n",n);
  return 0;
}

(int)为强制转换类型,转换为整形

总结:pow是一个可以计算次方的库函数,需要的头文件是#include<math,h>

strcpy函数:把A中的字符串复制到B中

函数原型:

char * strcpy ( char * destination, const char * source );//函数原型

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 返回值类型:返回目标的地址,所以需要用指针接收,又因为是字符串操作函数,所以char

函数参数:第一个参数(destination)是目的地指针(收获地址),就是被复制进去的

                  第二个参数(source)是源头指针(发货的地方),要复制的值

注意:复制的时候会自带一个\0(字符串结束的标志),但是原数组的\0后面的内容还存在,只是不打印。

用法:

#include<stdio.h>

int main()
{
	char A[] = "#############";
	char B[] = "love you";
	printf("交换前A:%s\n", A);
	printf("交换前B:%s\n", A);
	strcpy(A, B);//过程是从B到A
	printf("交换后B:%s\n",A);
	return 0;
}

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 因为数组名就是首地址,所以不需要传地址。

总结:strcpy是字符串复制函数,第一个参数是被复制参数,第二个是复制参数

menset函数:初始化函数,用于内存设置

void * memset ( void * ptr, int value, size_t num );//函数原型

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 函数参数:第一个参数(ptr)是操作目标;第二个参数(value)是初始化的内容,第三个参数(num)是操作数目

用法:

#include<stdio.h>
int main()
{
	char arr[] = "love you";//原数组
	printf("%s\n", arr);
	memset(arr,'6',3);操作之后
	printf("%s\n",arr);
	return 0;
}

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

三、自定义函数

前言:将函数比如工厂,库函数就是官方已经制作好的工厂,那么自定义函数则需要我们自己去构造工厂然后自己使用,因为工厂还没有制作好,所以名字我们可以自己起。

1.自定义函数的组成

函数名字+返回值类型+函数参数+函数体

对比库函数来看,自定义函数比库函数多了函数体部分,该部分就是工厂的功能,需要我们自己实现。

ret_type fun_name(para1, * )
{
       statement;//语句项
}
ret_type 返回类型
fun_name 函数名
para1 函数参数

这里的语句项就是函数体

2.自定义函数举例

(1)写一个函数实现两个数找最大值(传值)

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
	return (x > y) ? (x) : (y);
}
int main()
{
	int num1 = 10;
	int num2 = 20;
	int max = get_max(num1, num2);
	printf("max = %d\n", max);
}

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

(2)写一个函数把两个整数的值交换 

我们先看错误的写法【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 原因:把num1和num2的值传给形参x和y,所以x和y只是复制了一份数据。我们在复印件上面修改数据,是不会影响原件的。

我们看正确写法:

#include <stdio.h>
//正确的版本
void Swap2(int* px, int* py)//接收实参的时候,形参是指针变量
{
	int tmp = 0;
	tmp = *px;
	*px = *py;
	*py = tmp;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	Swap2(&num1, &num2);//注意这里是&num1,&num2
	printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
	return 0;
}

结果:【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 原因:把变量num1和num2的地址传递给形参,形参通过地址就可以找到源头,进而直接交换成功。这个称为传址调用

        可以这么理解1:我们把户口的网址传递给别人,别人可以通过登录该网址找到我们的户口,而直接修改;然后是我们把户口复印件给别人,别人在复印件上面修改对我们的户口是没有影响的。

       实质理解2:通过变量的地址可以找到该变量在内存中存放的位置,该位置就是变量数据所在地,直接在所在的修改数据从而达到修改的效果。

四、函数参数和函数调用

1.函数参数:实际参数(实参)和形似参数(形参)

实际参数:

   真实传递给函数的参数,叫实参。可以是变量、表达式、常量和函数,但是必须有确定的值。

举例:

Max(520,num1)//520是常量,num1是变量
Max(3+5,&num1)//3+5是表达式,&num1是变量
Max(printf("%d",num1))//函数形式

形式参数:

    用来接收实参。是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元)。只存在于函数中,出函数范围自动销毁。

举例:

   【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

2.实参和形参的内存

注:实参和形参所在的内存单元不一样,各自独立 

   我们用代码配图说明:【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

我们在编译器上面查看:【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言 所以,形参是在函数体中创造的,只存在于函数中,出了函数自动销毁

3.函数调用

     传值调用和传址调用

  • 传值调用:函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参
  • 传址调用:传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。

传值调用:

#include <stdio.h>
//get_max函数的设计
int get_max(int x, int y)
{
	return (x > y) ? (x) : (y);
}
int main()
{
	int num1 = 10;
	int num2 = 20;
	int max = get_max(num1, num2);//传值调用
	printf("max = %d\n", max);
}

传址调用:

#include <stdio.h>
//正确的版本
void Swap2(int* px, int* py)
{
	int tmp = 0;
	tmp = *px;
	*px = *py;

	*py = tmp;
}
int main()
{
	int num1 = 1;
	int num2 = 2;
	Swap2(&num1, &num2);//传址调用
	printf("Swap2::num1 = %d num2 = %d\n", num1, num2);
	return 0;
}

五、函数链式访问和嵌套使用

1.嵌套调用

#include <stdio.h>
void new_line()
{
   printf("hehe\n");//在new_line函数内部又调用了printf函数
                    //称为嵌套调用
}
void three_line()
{
   int i = 0;
   for(i=0; i<3; i++)
   {
    new_line();//在three_line函数内又嵌套调用new_line
   }
}
int main()
{
    three_line();
    return 0;
}

函数可以嵌套调用,互相调用,但是不能嵌套定义

void test()
{
  //int Add(int x,int y);//在函数内部嵌套定义
   Add(x,y)//这样子就可以
}
int main()
{
   test();
   return 0;
}

2.链式访问

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

#include <stdio.h>
#include <string.h>
int main()
{
   char arr[20] = "hello";
   int ret = strlen(strcat(arr,"bit"));//strcat的返回值作为strlen的参数
   printf("%d\n", ret);
   return 0;
}
#include <stdio.h>
int main()
{
   printf("%d", printf("%d", printf("%d", 43)));//结果4321
   //注:printf函数的返回值是打印在屏幕上字符的个数,打印几个,返回几
return 0;
}

六、函数的声明和定义

1.函数声明

  •      告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。
  • 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
  • 函数的声明一般要放在头文件中的。
  • 声明!=定义

举例:正常写法


#include<stdio.h>
int Add(int x,int y)//该函数的位置在mian函数前面
{
	return x + y;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d",&a,&b);
	int sum = Add(a, b);
	printf("%d\n",sum);
}

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

警告编译写法:

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

原因:因为编译器自上往下阅读,当调用Add函数的时候,前面没有遇到过Add函数,所以会有警告,当运行到后面才发现该函数。 

正确做法:在调用该函数前面先声明

int Add(int x,int y);//声明函数写法

【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 2.函数定义

    函数的定义是指函数的具体实现,交待函数的功能实现。(函数体)

注:函数的定义是一种特殊的声明。

举例:

int Add(int x, int y)
{
	return x + y;
}

这一整部分就是函数的定义

七、函数递归

前言:函数递归是函数部分较难点,用较少的代码表示庞大的过程。

1.我们看官方的定义;

      程序调用自身的编程技巧称为递归( recursion)。
递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接
调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

总结:自己调用自己,把大事化小。
 

2.递归的两个条件

   因为递归的思想是先把大块的事情不断分成小块的事情,当分到不能再分的时候(条件1),开始从最小块的事情往大块的事情执行,没执行一次,就会更加接近这个条件(条件2)

官方:

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续
  • 每次递归调用之后越来越接近这个限制条件

3.举例

 题目:接受一个整型值(无符号),按照顺序打印它的每一位。

           例如:输入1234          打印结果1 2 3 4

我们先给一个知识点:一个整数n/10=去掉个位剩下的数,如:1234/10=123

一个整数n%10=个位,如:123%10=3

分析:我们发现,要求打印1 2 3 4,不能使用常规方法;如果是打印4 3 2 1的话,就可以写一个循环,对1234连续取模(%)4次就可以了,但是现在顺序反了不可以。

要打印1,需要1%10=1,打印2,12%10=2,打印3,123%10=3,打印4,1234%10=4

我们可以发现:输入1234,需要拆成1,12,123和1234从小的开始计算。

   换个思想就是:打印1 2 3 4就可以拆成这样子:打印(1 2 3)和4,然后打印1 2 3又可以拆成打印(1 2)和3,打印1 2可以拆成打印1和2;1此时不能再拆,这就是限制条件1。很显然,这种思想就是递归的思想。

思路图:【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 代码实现:

#include <stdio.h>
void print(int n)
{
   if(n>9)//条件1
   {
     print(n/10);//不断调用自身
   }
   printf("%d ", n%10);//条件2
}
int main()
{
   int num = 1234;
   print(num);
   return 0;
}

解析:只要满足n>9的条件就不断调用,直到不满足便开始打印。

代码图解:【初阶C语言】认识和使用函数,初阶C语言,c语言,开发语言

 显而易见:递归把大事化小,用最短的代码表示最复杂的过程


函数递归是一个重难点,需要加大练习。后续会持续补充递归的内容;有时候递归太复杂,可以拆成非递归,也就是迭代。文章来源地址https://www.toymoban.com/news/detail-611853.html

到了这里,关于【初阶C语言】认识和使用函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 初阶C语言-函数(下)

    “追光的人,终会光芒万丈!” 今天我们继续一起来学习一下函数的相关知识点。 函数和函数之间可以根据实际的需求来进行组合的,也就是互相调用。 注:函数可以嵌套调用,但是不能嵌套定义! 把一个函数的返回值作为另一个函数的参数。 注: sizeof 就是一个计算数据

    2024年02月14日
    浏览(37)
  • 初阶c语言:超长详解“函数”。

    目录 一.在C语言中可将函数分为两大类: (1)库函数 (2)自定义函数  函数的使用  三.函数的参数 形参 实参  四.函数的调用 (1)传值调用  (2)传址调用 (3)那么我们如何判断是使用传值调用还是传址调用呢? 五.函数的嵌套调用和链式访问 (1)嵌套调用 (2)链式访问 函数定义:

    2024年02月12日
    浏览(33)
  • C语言初阶—9函数

    函数的声明 (main函数前)----告诉有一个函数 格式:  类型 函数名(参数); 函数的声明 放到头文件add.c 函数的定义 ----创建函数----放到add.c 格式:类型 函数名(参数) { 语句项; } 在文件中包含头文件 #include \\\"add.h\\\" 包含头文件-实质上就拷贝头文件的声明 到文件 导入静态库

    2024年04月08日
    浏览(34)
  • 『C语言初阶』第四章-函数

    🔥 博客主页 : 小羊失眠啦. 🔖 系列专栏 : C语言 🌥️ 每日语录 : 世上无难事,只怕有心人。 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 各位小伙伴们,时隔多日,小羊今天又来和大家一起学习C语言新的知识:函数,好的,废话不多说,咱们直接进入主题! 通常大家第一眼

    2024年02月14日
    浏览(29)
  • 初阶C语言——特别详细地介绍函数

     💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        从标题也能看出来,我们有要进行 超详细

    2024年02月14日
    浏览(35)
  • 【初阶C语言3】特别详细地介绍函数以及在初阶中重要的算法——递归

     💓作者简介: 加油,旭杏,目前大二,正在学习 C++ , 数据结构 等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏👀 🚚代码仓库:旭日东升 1👀 🌹欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖        从标题也能看出来,我们有要进行 超详细

    2024年02月08日
    浏览(47)
  • 【初阶C语言】关于scanf函数的超详细介绍和多组输入

    感谢各位可以光临娥子的作品   我们学习一个函数,要围绕三个点 :1.函数是什么  2.函数的用法   3.注意的细节 认识一个 函数,我们需要了解他的功能、返回值、接收的参数三个方面 函数原型  (1)功能介绍          scanf函数是一个输入函数 ,所以接收的参数类型需

    2024年02月08日
    浏览(54)
  • 【C++初阶】string 类的认识与学习

      在学习string类之前,先在这里推荐2个好用的网站,可以用来查阅C++的相关知识 https://cplusplus.com https://en.cppreference.com/w/ 上面的是非官方的,下面的官方的,但是个人感觉还是上面的好用。 简单来说, string 是C++中用来管理字符串的类。 他有很多接口,大致分为: 1.string类

    2024年02月09日
    浏览(49)
  • 【JavaEE初阶】 认识文件与Java中操作文件

    我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般。 文件除了有数据内容之外,

    2024年02月07日
    浏览(44)
  • C/C++|物联网开发入门+项目实战|函数输入与输出|值传递|地址传递|连续空间的传递|嵌入式C语言高级|C语言函数的使用-学习笔记(11)

    参考: 麦子学院-嵌入式C语言高级-C语言函数的使用 一堆代码的集合,用一个标签去描述它 复用化,降低冗余度 标签 ------ 函数名 函数和数组都属于内存空间,函数具备3要素: int *p; int a[100]; 1、函数名(地址) 2、输入参数 3、返回值 在定义函数时,必须将3要素告知编译器

    2023年04月20日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包