文章目录

      • 前言
    • 函数是什么?
  • 为什么要有函数?
  • C语言中函数的分类:
  • 自定义函数
  • 函数的参数
    • 实际参数(实参)
    • 形式参数(形参)
  • 函数的调用:
    • .函数的嵌套调用和链式访问
      • 嵌套调用
      • 链式访问
  • 函数的声明和定义
    • 函数声明:
    • 函数定义:
  • 函数递归
  • 结束语
前言

在数学里面我们学过很多种函数,像什么对数函数,指数函数等等,这些让俺看到就脑阔痛的,现在都还记得我高中数学老师意气风发的把整个黑板写满,擦了又写写了擦,我只能在下面像个傻x一样白瞪眼看着他,哈哈。不过C语言中的函数是非常友善,没有数学中函数那般复杂,非常容易上手,接下来,就来学习学习C中的函数。

函数是什么?

维基百科中对函数的定义:子程序

  • 在计算机科学中,子程序(英语:Subroutine, procedure, function, routine, method, subprogram, callable unit),是一个大型程序中的某部分代码, 由一个或多个语句块组 成。它负责完成某项特定任务,而且相较于其他代 码,具备相对的独立性。
  • 一般会有输入参数并有返回值,提供对过程的封装和细节的隐藏。这些代码通常被集成为软件库。
  • 大白话:之前我们写一个加法功能是写在main函数里面的现在,把它拿出来单独写在main函数外面,就成了一个加法函数。

为什么要有函数?

随着程序的开发,所需要的功能越来越多,其中有些功能是需要重复使用,如果将代码只放在一个函数,会变得越来越复杂,不方便维护进一步开发所以将不同的功能分为各个函数,即降低复杂度又可以将单一功能重复调用不需要重复编写。

C语言中函数的分类:

  1. 库函数
  2. 自定义函数

为什么要有库函数?

C语言设计之初,只设计出语法并没有函数,随着C语言被应用于开发中,有一个A程序员要打印某个东西,他就自己写了个程序,B程序员也需要打印某句话,他自己也写个程序,然后就导致同一个项目中打印的程序就有很多个,每个人写的代码还可能不样,导致项目代码冗余,开发效率低下,也不够标椎因为每个人写的打印程序都不一样,基于以上原因C语言就把一些常用的功能实现成函数,集成库,就有库函数了。

简单的总结,C语言常用的库函数都有:

  • IO函数

  • 字符串操作函数

  • 字符操作函数

  • 内存操作函数

  • 时间/日期函数

  • 数学函数

  • 其他库函数

接下来就来学习两个库函数

#include <stdio.h>
#include<string.h>
//strcpy();函数的使用
int main()
{char arr[] = "abcdefg";//abcdefg\0char arr2[20] = { "xxxxxxxxx"};//将arr中的字符串拷贝到arr2中\0的ascall的值为0strcpy(arr2, arr);printf("%s", arr2);return 0;
}
//  memset();
int main()
{char arr [] = { "hello bit"};memset(arr,'X', 3);//替换hello前三个字符串//1.设置内存的时候都是以字节为单位//2.每个字节的内容都是一样valueprintf("%s",arr);return 0;
}

注: 但是库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件。 这里对照文档来学习上面几个库函数,目的是掌握库函数的使用方法。

如何学习库函数

需要学会查询工具/网址的使用:

MSDN工具

自定义函数

顾名思义就是程序员自己根据需求定义一个函数,之所以有自定义函数是因为库函数万能的,它只是有常用的功能不可能包含所有的功能,因为时代在进步它不可能一开始就知道我们这个时代的需求,一切都时动态变化的,所以我们需要学会自定义函数,去解决不同的需求,说白点库函数也是人自定义的,所有更加重要的是自定义函数。 自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。 函数的组成:

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

举一个加法函数的例子

//get_max函数的设计
int get_max(int x, int y) //xy为形参
{return (x > y) ? (x) : (y);//返回值求出来的最值
}int main()
{int num1 = 10;int num2 = 20;int max = get_max(num1, num2);//num1 ,num2为实参,声明一个max的变量来接收返回值printf("max = %d\n", max);return 0;
}

在来举一个例子写一个函数可以交换两个整形变量的内容。

//错误的Swap1
void Swap1(int x, int y)//形参x,外在内存中开辟空间,去分别存储传过来的num1和num2 空间3和空间4
{int tmp = 0;//开辟空间5存储0tmp = x;x = y;y = tmp;//这段代码就换的是以tmp为中间变量,来达到空间3和空间4的值互相交换,并没有把空间1和空间2中的值交换
}
//正确的版本
void Swap2(int* px, int* py)//px和py为指针变量,储存的就是地址,指针即地址
{int tmp = 0;//开辟空间存储0tmp = *px;*px = *py;*py = tmp;
}
int main()
{int num1 = 1;//声明num1开辟空间存储1  空间1int num2 = 2;//声明num1开辟空间存储2    空间2Swap1(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 和 Swap2 函数中的参数 x,y,px,py 都是形式参数。在main函数中传给 Swap1 的 num1 , num2 和传 给 Swap2 函数的 &num1 , &num2 是实际参数。 这里我们对函数的实参和形参进行分析:

内存解析

这里可以看到 Swap1 函数在调用的时候, x , y 拥有自己的空间,同时拥有了和实参一模一样的内容。 所以我们可以简单的认为:形参实例化之后其实相当于实参的一份临时拷贝。

函数的调用:

  1. 传值调用
  2. 传址调用
  • 传值调用 函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参。

  • 传址调用 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操 作函数外部的变量。(交换两个变量的例子)

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

函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的。

嵌套调用

#include <stdio.h>
void new_line()
{printf("hehe\n");
}
void three_line()
{int i = 0;for(i=0; i<3; i++){new_line();}
}
int main()
{three_line();return 0;
}

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

链式访问

链式访问 把一个函数的返回值作为另外一个函数的参数

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

函数的声明和定义

函数声明:

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

函数定义:

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

test.h的内容 放置函数的声明

int Add(int x, int y);

test.c的内容 放置函数的实现

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

Demo.c调用函数

#include "Add.h"//引用头文件
int main()
{int num1 = 0;int num2;scanf("%d %d", &num1, &num2);int sum = Add(num1, num2);printf("%d", sum);return 0;
}

还可以直接写到一个文件里去

int Add(int x, int y) {return x + y;
}//Add函数需要写到前面,不然就得先声明
int main()
{int num1 = 0;int num2;scanf("%d %d", &num1, &num2);int sum = Add(num1, num2);printf("%d", sum);return 0;
}

建议分文件写

函数递归

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

递归的两个必要条件

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续。

  • 每次递归调用之后越来越接近这个限制条件。

史上最简单的递归

int main()
{printf("你是猪!\n");main();return 0;
}//死递归死循环,栈溢出

递归实现接受一个整型值(无符号),按照顺序打印它的每一位。

void print(int n)
{if (n > 9){print(n / 10);//反复调用自己}printf("%d ", n % 10);
}
int main()
{int num = 0;scanf("%d", &num);//1234print(num);return 0;
}

图解

递归:就是自己调自己(递推),调用函数需要返回,在哪里调用就返回到哪里(回归)

结束语

有时候,你也许得为了某个特定的事物生活,这样才能克服生活中其他的一切。 – 弗雷德里克·巴克曼 《熊镇2》

最简单的函数,看看就会了相关推荐

  1. R语言笔记6:在R中写一些简单的函数、functions基础和作用域

    R语言基础系列: 1数据类型(向量.数组.矩阵. 列表和数据框) 2读写数据所需的主要函数.与外部环境交互 3数据筛选--提取对象的子集 4向量.矩阵的数学运算 5控制结构 Your first R ...

  2. 开源纯C日志函数库iLOG3快速入门(八、如果你喜欢简单日志函数甚于日志函数库)...

    2019独角兽企业重金招聘Python工程师标准>>> 开源纯C日志函数库iLOG3快速入门(八.如果你喜欢简单日志函数甚于日志函数库) 很多网友来信坚持表达了在项目中应使用简单日志 ...

  3. 初学__Python——Python 最简单的函数—用 lambda 声明函数

    用 lambda 表达式来声明函数,是Python中一类比较特殊的声明函数的方式,lambda 来源于 LISP 语言,使用 lambda 可以声明一个匿名函数.所谓匿名函数是指所声明的函数没有函数名 ...

  4. LOJ6053简单的函数(min_25筛)

    LOJ6053简单的函数 https://loj.ac/p/6053 min_25筛模板题,但是要注意质数点有2比较特殊,需要在y==0的时候特判质数包含2的情况. #include<bits/ ...

  5. vue函数如何调用其他函数?_编程|如何简单理解函数的传参、返回、调用

    1 函数内部变量的局部性 在一个函数中定义的变量(包括实参),其作用域仅限于定义它的函数中,在其它的函数不能使用,这种变量称为"局部变量". 局部变量的作用域:函数内部声明和定义的 ...

  6. ibm ilog mysql_开源纯C日志函数库iLOG3快速入门(八、如果你喜欢简单日志函数甚于日志函数库)...

    开源纯C日志函数库iLOG3快速入门(八.如果你喜欢简单日志函数甚于日志函数库) 很多网友来信坚持表达了在项目中应使用简单日志函数,而不喜欢日志函数库,我与之反复争论无果,不过话说回来,我也喜欢短小轻 ...

  7. Min_25筛(LibreOJ #6053: 简单的函数)

    一个简单的问题:求 (i为质数) 设小于的质数有t个,其中表示第i个质数 再设  (i为质数或者i的最小质因子不小于) 那么有             其中 ,  就是答案 因为每次S(x, y)都是 ...

  8. SQL语句--简单的函数书写举例(3)

    SQL语句–简单的函数书写举例(3) 在前两篇中,案例只涉及到简单的数值,这样的函数称为[标量函数] 这里的函数,可以简单的理解为它是一个可以进行计算的工具 标量函数:是简单的数值,eg:int.ch ...

  9. SQL语句--简单的函数书写举例(1)

    SQL语句–简单的函数书写举例(1) 在数据库下的[可编程性]–[函数]下可看到有4类函数,平时用的函数大部分为[系统函数]下的,当这些函数不能满足实际需求时,我们要自己创建函数. eg:计算 A+B ...

  10. CRC校验原理及CRC-8简单校验函数设计

    CRC校验原理及CRC-8简单校验函数设计 CRC为循环冗余校验码,是一种常用的.具有检错.纠错能力的校验码.通常发送方在发送的数据之后,附上其CRC校验码.接收方收到数据后,也做同样的CRC校验,得 ...

最新文章

  1. python多大储存空间不足怎么办_Python存储空间不足
  2. CF1305D Kuroni and the Celebration
  3. 【ES10(2019)】String 扩展 trimStart / trimEnd
  4. Flink入门训练--以New York City Taxi为例
  5. shell判断文件与字符串
  6. 数据类型 --生成器
  7. mac / Ubuntu 终端下添加tree命令显示文件目录结构
  8. Opencv学习笔记 - 使用opencvsharp和支持向量机
  9. Microsoft Excel 教程:如何在 Excel 中创建自定义数字格式?
  10. 云安全七大核心要素解析
  11. 主数据管理之二:主数据管理系统的功能组件
  12. 如何注册谷歌账号、邮箱(22.8.23亲测可用)
  13. Chrome 出现内存 不足
  14. 超详细dns劫持解决办法分享
  15. Adobe PS常用快捷键
  16. 电脑连接手机热点后无法上网或提示找不到服务器IP地址(DNS错误)
  17. 天马G6二期、腾龙光谷数据中心 落户武汉东湖高新区
  18. JS实现表格增、删、排序
  19. 来了老弟,表格的渲染
  20. MY-I.MX6-DEMO Android4.4.2环境搭建

热门文章

  1. jieba分词TFIDF算法2
  2. google maps
  3. matlab对矩阵的排列顺序,matlab数组按照指定顺序重排
  4. vim 全局替换_有一说一,Intellij IDEA 自带的 Vim 插件真心不错!
  5. java中的for语句格式_Java中foreach循环语句的格式可以写成(        )。
  6. 【SIGIR22】使用反事实生成器来消除知识感知推荐中的虚假联系
  7. 论文笔记30 -- (视频压缩)【CVPR2021】FVC: A New Framework towards Deep Video Compression in Feature Space
  8. php短信炸弹,php发送短信炸弹 - rookier的个人页面 - OSCHINA - 中文开源技术交流社区...
  9. Java JVM参数调优配置
  10. 前进永无止境!Pipeline更新又双叒叕来了!