详解C语言初阶之函数

目录
  • 1.main函数
  • 2.自定义函数
    • 2.1  函数的的封装和面向过程的思维
  • 3.函数的组成
    • 3.1函数的命名法
    • 3.2函数的返回值
      • 3.2.1void类型
    • 补充:
    • 3.3形参与实参
  • 总结

1.main函数

第一个函数是我们的main函数,它无处不在,main函数被称之为我们的入口函数,程序在运行时,从main函数进入,从main函数出来,main函数其实就是整个程序功能的集合,所有的功能必须被包含在main里面才可以被运行(预处理命令,宏定义,全局变量什么的当然要优先处理,再次不讨论这些)。我们看个例子吧

上图中,一个很简单的打印,却发现main函数之外的打印出现了错误,由此说明main的重要型。

说白了,函数就是一个个功能的集合,内部也是一串串代码组成的程序,是程序的基本单元,又被叫作子程序,我们将函数分为库函数和自定义函数,再次我们主要了解自定义函数。

2.自定义函数

所谓自定义函数,就是我们自己写的函数,我们自己设置了他们的功能,将他们进行封装,在某些时候进行调用。如:

在这里,我们把一个简单地加法运算进行了封装。只要在main函数里调用这个定义函数,我们即可实现加法的功能。

那么,有人问了,我们为什么非要写一个函数呢,看起来就很麻烦,直接写到main函数里不就行了吗?

2.1  函数的的封装和面向过程的思维

实际上,我们在应用中不可能写如此简单的小程序,我们会写很长的代码(比如我们在刚刚的程序中加上减法、除法、乘法、求余、求次方等等),很多的功能,如果我们全写在main函数里,代码的可读性就会变得极差,而且main函数不仅会变得十分冗长,对于代码的调试和修改以及后期维护都难以进行。因此,我们把所有功能都进行封装打包,扔到我们自己的一个函数里,每一个函数都有想对应的功能(一般来说,我们要尽量加大自定义函数的独立性,方便函数的封装和后期维护),如此一来,我们就有了业务逻辑(想要程序实现的功能,如加法,就在main函数里面调用Add)和功能逻辑(再对Add进行定义),main函数就变得十分简洁明了,只需要用到哪些功能时,直接调用就行了,我们将功能逻辑的功能称之为解耦。在编写代码时,我们要首先知道我们想要实现什么功能,在主函数里对某一个可以实现该功能的函数先进行调用,等主函数完备后,再讲我们封装的功能进行定义,以配合我们的调用。我们把这种编程思维,称之为面向过程,即先明白要实现什么功能(对象)后,还需要对每一个功能进行具体构建(对象的构建),而不是直接调用该功能,比如我们要木材,就必须要自己种木头,浇花施肥,然后再取用,而不能直接去木材市场买,我们需要过程。

3.函数的组成

函数需要有定义之后才能调用,某些时候还需要声明(我们先不谈声明)

函数的定义由四部分组成:返回值(也叫函数类型)、函数名 、函数体 、形参

函数的调用由三部分组成:返回值、函数名、形参

3.1函数的命名法

为了增加可读性,和减少维护成本,我们通常把函数的命名方法定为见名知意,将名字按照大驼峰法进行命名(如加法及 Add,我的打印及 MyPrint)函数名以英文单词或者英文单词的简写构成,每个单词的第一个字母大写。

3.2函数的返回值

函数的返回值类型有int、char、double等各种类型,具体看你需要的功能。

如在刚刚的Add中,我们需要Add函数返回x和y的和(即返回一个整型,便于函数值的接收),因此我们需要在Add前面加int,如此我们便可以用int ret来接收函数值。

3.2.1void类型

在各种函数的返回值中,有一个奇怪却又常用的类型,叫作void(也就是空的意思),其实,它就是个占位子的,啥都不返回(我就站这儿,告诉别人这里这个座有人了)

如图所示,我们把printf放在了Add里面,如此来,我们就不需要接收Add的返回值来进行打印了,这个函数本身就有了打印的功能,因此我们把返回值(也就是函数类型写为void),也就是没有返回值。比如main函数也可以直接void main。

补充:

1.通常情况下,我们并不建议这么写,因为我们需要函数功能的独立性,减少多余的联系,后面大家会慢慢理解

2.main 函数建议以int作为返回值,代码规范是一个优秀程序员的基本素养。特立独行并不会让你变得优秀,优秀的代码是大多数人都能明白的代码

3.既然返回值已经为空,那我直接不写不行吗,为什么还要写一个void呢?

注意:函数默认是有返回值,不写的话会进行强制返回(强制类型转换为整型),默认返回值为int,有了void,就不会有其他返回值类型来占座

3.3形参与实参

函数调用括号里的参数叫作实参,函数定义括号里的参数叫作形参。

实参就是试试在在的真是的数据,就如同一张桌子,你砸了它一角,那这张桌子一角就真的没了。

形参本质上是对实参的临时拷贝(程序从主函数中运行到函数的调用时,就会自动在主函数前寻找该函数的定义,若发现定义,就会发生形参实例化,即将实参拷贝到形参里),还是一张桌子,发生形参实例化(临时拷贝)之后,就变成了两张桌子,现在你砸了第二张桌子,那第一张桌子依旧完好无损。而不管第二张桌子是是否损伤,只要出了它所在的代码块,它就会被销毁掉,而不能被其他函数继续使用,所以我们称之为临时拷贝。

上图,我们发现,在函数定义内拷贝参数改变的值并不会影响原值。这种参数传递方式我们叫做传值。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C语言内存操作函数详解

    目录 头文件:#include<memory.h> 2.memmove 3.memcmp 4.memset 总结 头文件:#include<memory.h> 1.memcpy 作用:内存拷贝 函数原型: void *memcpy( void *dest, const void *src, size_t count ); 使用: 使用格式:memcpy(目的地,原,想操作内存大小(单位字节)) 把 "参数2" 起始的 "参数3" 个字节 内容

  • 详解C语言之函数

    目录 函数的调用 函数调用方式 函数嵌套调用 递归调用 内部函数与外部函数 内部函数 外部函数 局部变量与全局变量 局部变量 全局变量 总结 函数的调用 函数调用方式 函数语句调用 函数表达式调用 函数参数调用 sum(); //函数语句调用 result = average * sum(a); //函数表达式调用 此时函数名出现在表达式中,其返回值将作为表达式的算数参与计算. result = sum(sum1(a)); //函数参数调用 此时函数名出现在另一个函数的参数中,其返回值将作为实参

  • C语言中scanf与scanf_s函数的使用详解

    目录 1.scanf_s(是vs提供的函数) 2.scanf(标准的库函数) 3.总结 1.scanf_s(是vs提供的函数) a.代码1 int main() { char a = 0; //scanf_s("%c", &a, 1); scanf_s("%c", &a, sizeof(a)); return 0; } scanf_s有三个参数,最后一个是变量a所占据空间的大小(单位为字节),这里可以写1,也可以写sizeof(a).如果a为整型的话

  • C语言函数指针详解

    目录 Introduction 函数指针 Function Pointers Exercise 1:qsort中的函数指针 Exercise 2: 总结 Introduction 上一个lab的主要内容为__data pointer__(指向数据的指针)可能在Linux系统中造成的__segmentation fault__.本次lab将考虑__function pointer__(指向函数/代码的指针)可能造成的错误:segfault或其他exceptions. 函数指针 Function P

  • C语言函数栈帧详解

    目录 前言 一.函数栈帧是什么? 二.栈帧准备知识 1.内存分区 2.什么是栈? 三.详解栈帧创建与销毁全过程 调用函数之前: 将传入函数的值放入栈中 函数执行: 1.保护当前ebp 2.创建所需调用函数的栈帧空间 3.保存局部变量 4.参数运算 函数返回: 1.存储返回值 2.销毁空间 3.ebp回上一栈帧栈底 4.销毁形参 5.main函数拿到返回值 总结 前言 在c语言中我们会将一些功能单独写成一个函数,以供主函数调用,在表面来看调用的过程就是写出一个函数后,只需要在调用时中通过函数名将实

  • C语言 function recursion函数递归详解

    目录 function recursion(函数递归) 递归的中心思想为: 程序一 递归的两个必要条件 程序一: 程序二: 练习 求n的阶乘 再来道例题 function recursion(函数递归) 函数递归: 是在 一个 过程 或 函数 在其定义或说明中有 直接 或 间接 调用自身 的一种方法 通常把一个 大型复杂的问题 层层 传化 为一个与 原理相似的 ,规模较小 的问题 递归策略 只需 少量的程序 就可以描述出 解题过程 所需的 多次 重复 计算,大大减少了程序的代码量 递归的中心思想

  • 详解C语言初阶之函数

    目录 1.main函数 2.自定义函数 2.1  函数的的封装和面向过程的思维 3.函数的组成 3.1函数的命名法 3.2函数的返回值 3.2.1void类型 补充: 3.3形参与实参 总结 1.main函数 第一个函数是我们的main函数,它无处不在,main函数被称之为我们的入口函数,程序在运行时,从main函数进入,从main函数出来,main函数其实就是整个程序功能的集合,所有的功能必须被包含在main里面才可以被运行(预处理命令,宏定义,全局变量什么的当然要优先处理,再次不讨论这些).

  • 详解C语言初阶基础

    目录 1.什么是c语言 2.初始化: 3.变量和常量 4.作用域与生命周期 简单阐述: 作用域: 生命周期(存在与消失): 作用域与生命周期的区别 作用域: 生命周期: 5.     为什么c中存在了各种数据类型: 6.常量: 7.c语言的字符串: 8.转义字符(\) 注意: 9.注释: 快捷键 总结 1.什么是c语言 c语言是一门通用计算机编程语言,是一种面向对象的编译型语言,广泛用于底层开发.其设计目的是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何环境便能运行的

  • 详解C语言初阶基础(2)

    目录 1.选择语句(if) 2.循环 while循环 for循环 do-while循环 补充 总结 1.选择语句(if) 我们先不讲switch,后面会补充.先来对简单地if进行了解. 我们已经知道,计算机的本质是为了服务于人,我们在日常生活中会遇到各种各样的选择,于情于理计算机都应该有选择语句来对应和我们的生活逻辑. 因此 if语句就是做一个选择,对计算机来说,选择只有真假之分,真就是非0(注意不是1,而是非0),假就是0. if(条件),通过对条件的判断来决定来执行哪一个分支,多分支我们可以

  • 详解C语言初阶之数组

    目录 1.数组 1.1数组的概念 1.2数组的定义 a:完全初始化 b:不完全初始化 c:给定元素个数 d:不给定元素个数 1.3数组的下标访问 总结 1.数组 1.1数组的概念 所谓数组(array),就是具有相同数据类型的集合,存放的数据类型即数组本身的类型. 可以发现存储的都是int型 补充 :调试小技巧 调试窗口 (按F5进行调试,打开菜单栏中的调试-窗口-监视-随便打开一个监视窗口,输入arr,将程序运行过arr的初始化即可观察到arr内部进行的初始化) 1.2数组的定义 a:完全初始

  • 详解R语言caret包trainControl函数

    目录 trainControl参数详解 源码 参数详解 示例 trainControl参数详解 源码 caret::trainControl <- function (method = "boot", number = ifelse(grepl("cv", method), 10, 25), repeats = ifelse(grepl("[d_]cv$", method), 1, NA), p = 0.75, search = "

  • 详解C语言编程中的函数指针以及函数回调

    函数指针: 就是存储函数地址的指针,就是指向函数的指针,就是指针存储的值是函数地址,我们可以通过指针可以调用函数. 我们先来定义一个简单的函数: //定义这样一个函数 void easyFunc() { printf("I'm a easy Function\n"); } //声明一个函数 void easyFunc(); //调用函数 easyFunc(); //定义这样一个函数 void easyFunc() { printf("I'm a easy Function\n

  • 详解易语言DLL以及API函数

    易语言 DLL 详细解释 使用易语言多媒体教程中的例子. .版本 2 //DLL文件 ,需要插入一个窗体.标签.按钮 .程序集 窗口程序集1 .子程序 _按钮1_被单击 窗口1.销毁 () .子程序 自创信息框, , 公开 .参数 标题, 文本型 .参数 内容, 文本型 载入 (窗口1, , 假) // 载入(),必须放在前面,放在后两句的后面则提示窗口无法载入 窗口1.标题 = 标题 窗口1.标签1.标题 = 内容 //编译为自创信息框.dll //当你想调用前面的dll时,必须先插入dll命

  • 详解C语言的mem系列函数

    目录 1.memchr 2.memcmp 4.memmove 5.memset 总结 1.memchr memchr的函数声明: void *memchr(const void *str, int c, size_t n); 作用: memchr函数从str位置后的n个位置开始寻找,寻找第一个和c相同的字符.如果成功,memchr函数返回一个指向该字符位置的指针,如果没有没有找到指定字符,则返回NULL. 实例: #include <stdio.h> #include <string.h

  • 详解C语言对字符串处理函数的实现方法

    目录 strlen: 1.计数器版本: 2.递归的版本 3.指针-指针版本 strcat: strcmp: 总结 strlen: 1.计数器版本: #include<stdio.h> #include<string.h> #include<assert.h> int my_strlen(const char *str) { int count =0; assert(str!=NULL); while(*str!='\0') { count++; str++; } ret

  • 详解Go语言如何利用高阶函数写出优雅的代码

    目录 前言 问题 白银 黄金 王者 总结 前言 go项目中经常需要查询db,按照以前java开发经验,会根据查询条件写很多方法,如: GetUserByUserID GetUsersByName GetUsersByAge 每一种查询条件写一个方法,这种方式对外是挺好的,对外遵循严格原则,让每个对外的方法接口是明确的.但是对内的话,应该尽可能的通用,做到代码复用,少写代码,让代码看起来更优雅.整洁. 问题 在review代码的时候,针对上面3个方法,一般写法是 func GetUserByUse

随机推荐