【零基础学习iOS开发】【02-C语言】10-函数
前面已经讲完了C语言中的基本语句和基本运算了,这讲呢,介绍C语言中的重头戏---函数。其实函数这个概念,在大部分高级语言中都是非常重要的,我也已经在《第一个C语言程序》一讲中对函数作了一个简单介绍。
一、基本概念
1.什么是函数
任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”。所以,你可以说C语言程序是由函数构成的。
比如你用C语言编写了一个MP3播放器程序,那么它的程序结构如下图所示:
- 从上图可以看出:函数就是用来实现某个功能的程序段,每一个函数都有自己的功能。因此,你应该把实现某个功能所需的代码都写在函数中。比如,有个函数的功能是播放MP3,那么播放MP3的代码都应该写到这个函数中。
- 当调用(执行)一个函数时,计算机就会按顺序执行函数中的所有代码,从而展示函数所实现的功能。
2.函数名
一般来说,我们会将不同的功能交给不同的函数去实现。比如,将暂停播放MP3的代码写到一个函数中,将停止播放MP3的代码写到另一个函数中。因此,一个C程序中可能会有很多的函数。为了方便调用和区分这些函数,我们需要为每一个函数都起一个唯一的名称,函数的命名必须按照标识符命名规则。利用函数名就可以调用到对应的函数。
二、函数的定义
1.任何一个函数在使用之前都必须进行定义
定义函数的目的就是为了写清楚你这个函数是干啥用的,里面包含了哪些代码。函数的定义格式如下:
1 返回值类型 函数名(形式参数列表)
2 {
3 函数体
4 }
2.举例
比如定义一个函数用来计算两个整数的和。那么可以写成下面这样:

1 #include <stdio.h>
2
3 int sum(int a, int b)
4 {
5 int c = a + b;
6 return c;
7 }
8
9 int main()
10 {
11 int d = sum(10, 11);
12
13 printf("d is %d", d);
14 return 0;
15 }

- 分别在第3行、第9行定义了sum函数、main函数,其中sum函数的作用是计算两个整数的和。
- 函数定义好后,并不会马上执行函数内部的代码,要有人调用它才会执行内部的代码。就好像你的手机虽然有打电话的功能,但是只有按了拨号键,才会执行打电话的功能。
- 程序运行时就会先调用main函数,按顺序执行第11~14行代码,因为main函数是程序的入口
- 第11行的sum(10, 11)是调用sum函数,sum函数被调用了,就会分配存储空间给形式参数列表中的所有参数,也就是第3行中的变量a和变量b,它们都是“形式参数”
- 第11行中的10、11称为“实际参数”,它们将分别赋值给变量a、变量b,也就是相当于
1 int a = 10;
2 int b = 11;
- 既然调用了sum函数,就会按顺序执行sum函数中的代码,也就是第5~6行代码。
- 第5行将a+b的值21赋值给了变量c,第6行使用return关键字将变量c返回给了函数调用者,也是说,第11行sum(10, 11)的值是21。那么变量d的值就是21。
- 第13行的输出结果为:
d is 21
- 第3~7行中的变量a、b、c都只有在调用sum函数时,才会分配存储空间,当sum函数执行完毕后,变量a、b、c就会被释放存储空间。因此,它们的作用域仅限于sum函数内部。
- 第3行sum左边的int称为“返回值类型”,第6行return关键字后面跟着的数值称为“返回值”,因此第6行的变量c就是返回值,返回值的数据类型应该跟“返回值类型”保持一致。
三、形式参数和实际参数
1.基本概念
1> 形式参数:在定义函数时,函数名后面的小括号()中定义的变量称为形式参数,简称形参
2> 实际参数:在调用函数时传入的值称为实际参数,简称实参
2.调用函数时传递的实参个数 必须和 函数的形参个数必须保持一致

1 int sum(int a, int b, int c)
2 {
3 return a + b + c;
4 }
5
6 int main()
7 {
8 sum(10, 9, 7);
9 return 0;
10 }

第1行中sum函数中有3个形参,因此在第8行调用sum函数时,需要传入3个实参
3.当使用基本数据类型(char、int、float等)作为实参时,实参和形参之间只是值传递,修改形参的值并不影响到实参

1 #include <stdio.h>
2
3 int test(char a)
4 {
5 a = 10;
6
7 return 0;
8 }
9
10 int main()
11 {
12 char b = 5;
13
14 test(b);
15
16 printf("b的值是%d", b);
17
18 return 0;
19 }

- 在第3行定义了test函数,只有一个形参a
- 在第14行调用了test函数,接着就会分配内存给变量a。这里将变量b当做实参,那么变量b的值将传递给变量a。这个时候,内存中大致如下图所示:
(其实在内存中存储的是二进制数据,这里我写成10进制是为了直观性)
- 执行完第5行代码后,变量a的值变成了10,但是变量b的值依然是5
- 第16行代码的输出结果是:
b的值是5
因此,在函数内部修改了形参的值,并不会影响到外面的实参。
4.函数可以没有形参
定义一个函数时是可以没有形参的,比如下面的函数

1 #include <stdio.h>
2
3 int test()
4 {
5 printf("调用了test函数");
6 return 0;
7 }
8
9 int main()
10 {
11 test();
12 return 0;
13 }

- 在第3行定义了test函数,可以发现,它的形参列表是空的,也就是没有形参
- 那么在第11行调用test函数时,就不用传递任何实参
- 其实,第9行定义的main函数也是没有形参的
四、返回值类型
1.返回值就是函数调用完后,返回给函数调用者的结果,用return关键字进行返回。定义函数时,要指明函数的返回值类型

1 double pi()
2 {
3 return 3.4;
4 }
5
6 int main()
7 {
8 double a = pi();
9 return 0;
10 }

- 第1行定义了一个pi函数,返回值类型是double,因此用return返回的数值应该是double类型的,这里返回的是3.14
- 第8行pi函数调用完毕后,函数调用者得到的值就是3.14,因此,变量a的值是3.14
2.一个函数可以没有返回值,如果没有返回值,应该用void表示返回值类型

1 #include <stdio.h>
2
3 void test()
4 {
5 printf("调用了test函数");
6 return;
7 }
8
9 int main()
10 {
11 test();
12 return 0;
13 }

- 在第3行定义了一个test函数,它是没有返回值的,所以第6行的return后面没有跟上任何数值
- 在第11行调用了test函数
3.如果一个函数没有返回值,最后面的return语句可以省略
所以,上面的test函数可以简化成:
1 void test()
2 {
3 printf("调用了test函数");
4 }
4.如果一个函数没有明确写出返回值类型,那么代表这个函数的返回值类型是int
1 sum(int a, int b)
2 {
3 return a + b;
4 }
可以看到,第1行定义的sum函数没有明确写出返回值类型,那么这个sum函数的返回值类型就是int。因此,第3行return后面跟随的是int类型数据
1.return语句可以在函数内部返回一个值给函数调用者

1 int sum(int a, int b)
2 {
3 return a + b;
4 }
5
6 int main()
7 {
8 int c = sum(5, 8);
9 return 0;
10 }

第3行使用了return语句,将a+b的值返回给了函数调用者,因此第8行变量c的值是13
2.一个函数内部可以多次使用return语句,使用了return语句后,函数就会马上停止执行,return语句后面的代码就不再被执行

1 int max(int a, int b)
2 {
3 if (a>b)
4 {
5 return a;
6 }
7
8 return b;
9 }

- 这个max函数可以用来求出两个整数中的最大值
- 如果a大于b,就执行第5行代码,直接将a返回,函数就会停止执行。也就是说,后面的第8行代码就不会被执行
- 如果a不大于b,就执行第8行代码,将b返回
六、函数定义的注意
1.函数名不能重复
默认情况下,函数的名字必须唯一。下面的写法是错误的:

1 void test(int a)
2 {
3
4 }
5
6 int test()
7 {
8 return 10;
9 }

第1、6行定义的函数的名称都是test,编译器会直接报错
2.每一个函数都应该独立定义,不能嵌套定义
下面的写法是错误的:

1 int main()
2 {
3 void test()
4 {
5
6 }
7
8 return 0;
9 }

在第3行把test函数定义在了main函数内部,这是错误的写法
七、常见函数
1.main函数
从第一个C语言开始,就认识了这个main函数。main函数是整个C程序的入口,有了main函数,C程序才能运行成功,而且整个C程序中只能有一个main函数。
main函数的简单定义如下:
1 int main()
2 {
3
4 return 0;
5 }
它可以没有形式参数,返回值是int类型。它的返回值用于说明程序的退出状态:如果返回0,则代表程序正常退出,否则代表程序异常退出
2.printf函数
你可能已经注意到,平时一直在使用的printf其实也是一个函数,这是系统自带的函数

1 #include <stdio.h>
2
3 int main()
4 {
5
6 printf("我要学习iOS开发");
7
8 return 0;
9 }

- 在第6行调用了printf函数,传入的参数是一个字符串常量:"我要学习iOS开发"
- printf函数的作用是在屏幕上输出内容
- 注意第1行代码,如果你使用了printf函数,就要加上这一句,至于原因,会在后面的章节详细介绍
【零基础学习iOS开发】【02-C语言】10-函数的更多相关文章
- 李洪强iOS开发之零基础学习iOS开发【02-C语言】03-关键字、标识符、注释
上一讲中已经创建了第一个C语言程序,知道了C程序是由函数构成的,这讲继续学习C语言的一些基本语法.C语言属于一门高级语言,其实,所有的高级语言的基本语法组成部分都是一样的,只是表现形式不太一样.就好像 ...
- 【零基础学习iOS开发】【转载】
原文地址:http://www.cnblogs.com/mjios/archive/2013/04/24/3039357.html 本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开 ...
- 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇
从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...
- 【零基础学习iOS开发】【01-前言】01-开篇
本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开发 四.学习iOS开发的目的 五.学习iOS开发的前提 从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过I ...
- 零基础学习iOS开发
零基础学习iOS开发不管你是否涉足过IT领域,只要你对iOS开发感兴趣,都可以阅读此专题. [零基础学习iOS开发][02-C语言]11-函数的声明和定义 摘要: 在上一讲中,简单介绍了函数的定义和使 ...
- [iOS]关于零基础学习iOS开发的学习方法总结
关于零基础学习iOS开发的学习方法总结 最近很多零基础来参加蓝鸥培训的学生经常会问到一些学习方法的问题,就如下我自己见过的好的学习方法一起讨论一下. 蓝鸥iOS开发技术的学习路线图 程序员的主要工作是 ...
- 李洪强iOS开发之【零基础学习iOS开发】【02-C语言】02-第一个C语言程序
前言 前面已经唠叨了这么多理论知识,从这讲开始,就要通过接触代码来学习C语言的语法.学习任何一门语言,首先要掌握的肯定是语法.学习C语言语法的目的:就是能够利用C语言编写程序,然后运行程序跟硬件(计算 ...
- 李洪强iOS开发之【零基础学习iOS开发】【01-前言】02-准备
在上一讲中,介绍了什么是iOS开发.说简单一点,iOS开发,就是开发运行在iPhone或者iPad上的软件.这么一说完,应该有很多人就会产生一些疑惑,比如学习iOS开发是不是一定要买iPhone?需不 ...
- 【零基础学习iOS开发】【01-前言】02-准备
一.程序设计语言 上一讲已经说到:要想开发一款软件,首先得学习一些对应的程序设计语言. 至于iOS开发,须要学习的语言主要有:C.C++.Objective-C. 回到顶部 二.是否须要计算机专业知识 ...
- 李洪强iOS开发之零基础学习iOS开发】【02-C语言】01-概述
前面已经给大家介绍了iOS开发相关的一些基础知识,其实iOS开发就是开发iPhone\iPad上的软件,而要想开发一款软件,首先要学习程序设计语言.iOS开发需要学习的主要程序设计语言有:C语言.C+ ...
随机推荐
- 创建一个目录info,并在目录中创建一个文件test.txt,把该文件的信息读取出来,并显示出来
/*4.创建一个目录info,并在目录中创建一个文件test.txt,把该文件的信息读取出来,并显示出来*/ #import <Foundation/Foundation.h>#defin ...
- C# 添加,修改,删除文件夹/文件集合
C#追加文件 StreamWriter sw = File.AppendText(Server.MapPath(".")+"\\myText.txt"); sw ...
- MVC 生成PDf表格并插入图片
最近做的项目中有一个功能,将最终的个人信息生成PDF表格,并插入图片.对于没接触过的程序员来说回一片茫然,网上有多种生成PDf的方法,我给大家介绍一下我认为比较简单,好操作的一种. iTextShar ...
- 【Leetcode】357. Count Numbers with Unique Digits
题目描述: Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. ...
- Java流的正确关闭方式
因为流是无论如何一定要关闭的,所以要写在finally里.如下: BufferedReader reader = null; try { reader = (BufferedReader) getRe ...
- ubuntu 阿里云安全配置
1. 添加新用户, 加入 root 组, 赋予 sudo 权限 2. 禁用 root 3.
- Unity编程回忆录之控制物体移动
最新心血来潮,然后开始学习Unity3D游戏开发引擎,对于一个主流的跨平台3D游戏开发引擎,我已经深深的为他着迷了,于是果断的开始学习这个引擎,而且刚刚预装的游戏引擎最新版中4.3版本已经开始原生支持 ...
- rpm与yum命令的初步认识
RPM:Red Hat package manager(RedHat软件包管理工具),现在为RPM is Package Manager好比windows里的文件扩展名为·exe的软件包. RPM的包 ...
- java实现多模匹配算法
这个是好几年前写的了.都统一放到cnblogs上面. --------------------------------Node ---------------------------------- p ...
- WinForm多线程及委托防止界面假死
当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决. using System; using System.Collections.Generi ...