一、函数的定义C语言中的函数就是实现一个完成某项特定的任务的一小段代码。这一段代码有着特殊的写法与调用方法。在C语言中我们一般会见到两种函数a、库函数b、自定义函数1库函数C语言标准中规定了C语言的各种风格语法标准C语言不提供库函数C语言的国际标准ANSI规定了一些常用的函数的标准那不同的编译器厂商提供ANSI提供的C语言标准就给出一系列函数的实现这些函数就称之为库函数。2自定义函数理解了库函数之后我们更多的关注就聚焦在自定义函数之上自定义函数更加的重要可以为程序员写代码创造更多的价值。自定义函数的形式如下接下来我们举出一个例子我们在这里写一个加法函数a、实际参数在上面的代码中上面的哪一行就是Add函数的定义有了函数之后在下面调用Add函数传递给函数的参数a与b称之为实际参数简称为形参实际参数就是真实传递给函数的参数。b、形式参数在上面的代码中上面代码定义函数的时候在函数名Add后的括号中写的是x与y称之为形式参数为啥叫做形式参数实际上如果我们仅仅只是定义Add函数而不去调用的话Add函数的参数x与y只是形式上存在的不会在内存中申请空间不会真实存在的所以叫做形式参数。形式参数只有在函数被调用的过程中为了存放实际参数传递过来的值才会向内存申请空间这个过程就叫做形参的实例化。其实变量在创建的时候是要在内存中创建空间的形式参数与实际参数是不同的内存空间当实际参数传递给形式参数的时候形式参数会创建自己的空间来保存实参对形式参数的修改不会影响实际参数。二、return语句函数中有可能有return语句也有可能没有在函数的设计中函数经常会出现return语句下面就是return语句的注意事项1return后面可能是一个数值或者是表达式如果是表达式则会先执行表达式再返回。下面就是对应的例子2return后面可以啥都没有直接写return即可在一个函数执行过程中需要提前返回但是不需要带回任何值就需要提前返回这种情况适用于返回类型是void的情况。下面就是对应的例子在上述的例子中当我们执行到retrurn的时候函数就会立即结束说明这个函数不会返回值所以return的意思就是提前结束函数。3return语句执行之后后面的代码就不再执行了。这段函数在调用结束之后运行的结果为hello但是后面的world就不会打印了所以这里你可以将return理解为这个函数到这里就结束了。4return返回的值与函数返回的类型不一致系统就会自动将返回的值隐式转换为函数的返回类型所以函数的返回类型与返回的值的类型要一致。这里函数要求返回的是int但是3.14是double所以编译器就是进行类型转换所以这里3.14转换为int类型就会变为3所以最终的返回类型就是3所以这里我们最好遵循返回的是啥类型的数据函数前面就尽量写对应的返回类型。5如果函数中有if等分支语句就要保证每一种情况下都有return返回否则就会有编译错误。例如上述的这个写法就是有问题的但是如果x0确实就会返回1但是如果x0程序此时就走不到任何return所以正确的写法是这样无论是大于0还是小于0此时函数都一定会有返回值。6函数的返回类型如果不写的话编译器会默认函数的返回类型是int对于上述的代码老式C中可能会默认当做int但是在现代C中应该明确写上int否则现代编译器通常会警告甚至报错所以这一条可以理解为这是历史上的就规矩但是写代码的时候一定要明确的写上返回类型。7函数写了返回类型但是函数中没有使用return返回值那么函数的返回值就是未知的。三、数组做函数参数在使用函数解决问题的时候难免会将数组作为参数传递给函数在函数的内部对数组进行操作。变量、数组、函数等名字都叫做标识符。标识符的命名规则a、可以是数字字母下划线组成b、但是不可以以数字开头下面的代码就是对于数组传参的简单运用数组在作为参数进行传递的时候上面的两个函数是如何设计的这里我们需要知道数组传参的几个重要的知识点首先我们需要记住一个核心点数组传参的时候数组名通常会转换为指向首元素的指针。因此函数形参虽然写成数组形式但它实际上接受的是指针而不是创建一个新的数组。1函数的形式参数要与函数的实参个数相互匹配。这里定义了两个形参a与b调用的时候传入两个实参因此调用时实参的数量必须与函数定义的形参数量是相互匹配的。这里讨论的是普通的、具有原型是声明的函数调用。2函数的实参是数组形参也是可以写成数组形式的。这里a是一个实参它是一个数组int arr[]是形参它采用数组形式书写调用时test(a)会将数组表达式a转换为指向首元素的指针传递给函数下面需要注意也就是说虽然写的是arr[]但是函数形参实际上是指针不是一个新的数组。3形参如果是一维数组数组的大小是可以省略不写的。这三种写法在普通函数形参中调整后的类型是int*。4形参如果是二维数组的话此时行是可以省略的但是列是不可以省略的。下面的这三种写法就是正确的方式这三种写法在普通函数形参中调整之后的类型都是int(*)[5]也就是指向含有5个int元素的数组的指针。5形参操作的数组与实参操作的数组是同一个数组。四、嵌套调用与链式访问1嵌套调用函数中调用其他的函数下面我们举一个经典的例子计算某年某月有多少天上面的代码就是一个经典的函数嵌套主要的任务就是返回这一年的这一个月有多少天。2链式访问所谓的链式访问其实就是将一个函数的返回值作为另外一个函数的参数像链条一样将函数串起来进行访问上面的这一段代码就是对于链式访问的实际运用这里还有一个比较有趣的代码在对于这段代码得物返回值进行猜测之前我们首先需要知道printf函数返回值是啥这里我们需要补充的是printf返回的类型是本次成功输出的字符个数不包括字符串结束符\0所以首先最里面打印43这是两个字符所以第二层返回的就是字符的个数2最后最外层的就是返回1所以最终的打印结果就是4321。五、函数的声明与定义1单个文件注意函数的使用一般需要满足先声明再使用。2多个文件一般在企业中我们写代码的时候代码可能是比较多的不会将所有的代码都写在一个文件中我们往往会根据程序的功能将代码拆分在多个文件中。头文件一般会防止函数的声明或者类型的声明函数的定义会放置在.c文件中。六、static与extern这二者都是C语言中的关键字在了解这两个关键字的时候我们首先需要了解一下作用域与生命周期a、作用域是程序的设计概念通常来说一段程序代码中所用的名字并不是有效的而限定这个名字的可用性的代码范围就是这个名字的作用域。b、生命周期指的是变量的创建申请空间到变量的销毁收回内存之间的一个时间段1、局部变量的生命周期是进入作用域变量创建生命周期开始出作用域生命周期结束。2、全局变量的生命周期是整个程序的生命周期。程序的生命周期main函数的生命周期。1static是静态的意思可以用来a、修饰局部变量这里运行结果就是三个1因为每一次调用test函数的时候吗普通局部变量a都会初始化为0然后执行a所以每次输出1。下面将int改为static此时我们就会发现运行的结果为1 2 3为什么这里结果会变因为static修饰的局部变量具有静态存储期整个程序运行期间它一直存在而且只初始化一次。结论static此时局部变量的时候改变了变量的生命周期生命周期改变的本质是改变了变量的存储类型本来一个局部变量是存储的内存中的栈区的但是被static修饰之后存储在静态区存储在静态区的变量与全局变量是一致的生命周期与程序的生命周期是一样的只有程序结束之后内存才会回收但是作用域是不变的。我们就以上面这张图作为理解即可。b、修饰全局变量一个全局变量被static修饰使得这个全局变量只可以在本源文件中使用本质原因在于全局变量默认是具有外部链接属性的在外部的文件中想要使用只要适当的声明即可但是当全局变量被static修饰之后外部链接属性就变为了内部链接属性只能在自己的源文件内部进行使用其他源文件即使声明了也是无法正常使用的。c、修饰函数使用建议未来一个变量出了函数之后我们还想继续保留值等下一次进入函数继续使用就可以使用static进行修饰。2extern是用来声明外部符号的我们可以将extern理解为一句话extern的作用是“声明一个变量或者函数在别的地方已经有定义了我这里只是拿来用”它最常用的方式即使在.c文件之间共享全局变量或者函数。
阅读完成 · 觉得有帮助?