Object-C基础(4)—— 函数

C是一门结构化的编程语言,Objective-C是C的超集。

为什么要定义函数?

为了方便复用某段代码,可以将这段代码定义成一个函数,以后每次调用该函数,就相当于让程序去执行这段代码。

定义函数(function)的语法

返回值类型 函数名(形参列表)

{

}

返回值类型:可以是任何有效的类型(基本类型、构造类型、引用类型)。

所谓返回值类型,决定了该函数执行成功之后,所返回的结果的类型。

因此如果没有返回值类型,应该将返回值类型声明为void。

如果不写返回值类型,表明返回值类型为int。

如果声明了返回值类型(包括不写),程序应该在函数体使用return语句来返回函数的返回值。

函数名:标识符即可。

实际上,函数名应该一个或多个有意义的单词连缀而成。

形参列表: 形参类型 形参名, 形参类型 形参名, ...

每个形参都必须由 形参类型和形参名所组成。

调用函数

注意点:

1. 声明函数时指定了几个形参,调用函数时就需要传入几个参数、而且参数的类型要一致。

2. 函数的返回值,既可用变量去装;也可立即拿来用掉(将函数返回值放入表达式中)。

函数声明

C语言是从上到下的,默认要求:函数必须先定义、再使用。

对于如下两种情况:

- 函数定义在函数调用处的后面。

- 函数定义在另一个源文件中。

此时就需要使用函数声明 —— 函数声明就是告诉编译器:这个函数是存在的。

函数声明:就是重要函数的返回值类型、函数名、形参类型即可,不要函数执行体。

注意:函数声明时既可有形参名,也可没有形参名。

import语句,就是导入大量的函数声明。

由于函数声明必须在所有函数调用的前面,因此程序就需要将#import语句放在程序在最上面。

函数的传参机制

Object-C的传参机制是“值传递”,程序传入函数的只是参数本身的副本(复制品),

因此函数所参数所作的修改,对参数本身是没有任何影响的。

注意:对于传递指针的情形,实际上传递的依然是指针的复制品(副本)。

递归函数

如果一个函数,调用了自身,该函数就会形成递归函数。

递归,可实现一个隐式的循环。

与循环类似的是,递归也必须有结束的时候。

递归:一定要有结束的时,要向已知的方向递归。

使用数组本身(数组的本质就是指针)作为参数

注意:

1. 当在函数中声明数组类型的参数时,既可指定数组的长度,也可不指定数组的长度,但通常都不会指定。

2. 由于数组本身是一个指针,因此传入函数的并不是数组本身,只是一个指针的副本。

因此函数无法通过sizeof来获取被传入的数组的长度。

3. 由于数组本身是指针,因此函数对数组元素所做的修改会影响数组本身的元素的。

内部函数与外部函数

C语言是结构化程序设计语言,因此函数是C的一等公民:

一个C程序通常是由于很多个函数组成,程序员开发的函数,可能还需要依赖系统内置的函数。

由此可见:C语言程序,可能由成千上万的函数组成,但最多只能有一个main函数

—— 它作为程序的入口,其他函数都是直接或间接地被main函数调用,所有函数的地位是平等。

每个函数都可调用别的函数,也可被别的函数调用。

static修饰符的作用之一:把外部东西(函数、全局变量),变成内部东西(函数、全局变量)。

- static函数,就是内部函数——只能在当前源文件中被调用。

- 没static修饰或extern修饰的函数,可以任何地方被调用(只要先做函数声明即可)。

对于内部函数,程序只有通过直接把源代码import进来才可以调用内部函数。

而外部函数,程序即使拿不到定义函数的源代码,只要有定义函数的源代码生成的库,程序也可通过函数声明之后来调用外部函数。

局部变量与全局变量

C的变量分为:

局部(local)变量:在函数里、方法里定义的变量,都是局部变量。

局部变量保存在各自的栈区中,函数、方法执行结束时,栈区被销毁。

特征:只在定义该变量的函数、方法内有效,函数、方法执行完,局部变量立即消失。

全局(global)变量:在文件范围内定义的变量,都是全局变量。

全局变量保存在整个程序的内存(静态存储区)中。程序不结束,静态存储区不会消失。

特征:只要程序不退出,全局变量将一直有效。

细分局部变量,又可分为:

- 形参:从函数被调用开始,形参开始生效,函数结束时,参数失效。

- 方法里局部变量:从定义该变量开始生效,函数结束时,该变量失效。

- 代码块的局部变量:从定义该变量开始生效,代码块结束时,该变量失效。

包括在if条件体、循环体、for循环的初始化语句中定义的变量,都属于代码块的局部变量,离开了定义该变量的花括号区域,那么该变量就失效了。

细分全局变量

- static全局变量,就是内部[全局]变量——只能在当前源文件中被调用。

- 没static修饰的全局变量,可以任何地方被调用(只要先做变量声明即可)。

变量声明:如果程序要使用其他源程序中定义的全局变量时,就必须做变量声明。语法是:

extern 类型变量名;

局部变量的存储机制:

定义局部变量时,有如下几个修饰符:

auto - 有auto和没auto效果是一样的。也就是说,你定义的所有的局部变量,默认就相当于有个auto。

auto修饰的局部变量,会被保存到函数或方法的栈区中。

static - 把局部变量放到静态存储区中。

对于static的局部变量而言,只要程序不退出,静态局部变量将一直有效。

由于static局部变量会一直有效,因此程序只有第一次调用函数时,才会对static局部变量赋初始值。

register - 控制把局部变量放入寄存器中。

但OS并不保证register变量一定会进入寄存器,所以实际上这个修饰用的并不多。

关于定义变量的原则:

1. 程序应该优先使用局部变量(全局变量是非常糟糕的设计、会造成牵一发而动全身的效果)。

2. 如果局部变量需要能在函数、方法结束时,依然可以保存上次运行的数据,或者该变量只希望第一次调用时被初始化,

该局部变量应该用static修饰。

3. 实在没办法,才考虑使用全局变量。

典型的,当一个程序单元需要把数据共享给另外一个程序单元时,正确做法是参数传递,而不是全局变量。

static修饰符有2个作用:

- 修饰全局函数、全局变量,使之变成内部函数、内部全局变量。

- 修饰局部变量,使之成为静态局部变量——静态局部变量会被保存到程序的静态存储区。

extern修饰符也有2个作用:

- 声明全局变量。

- 修饰外部函数。————但实际上,不用extern效果也是一样的。

预处理

预处理:程序在编译阶段就会处理调用东西,这些预处理指令不会保留到运行阶段。

对于源程序中包含的预处理,编译器会在编译阶段处理完成,到运行时就不存在预处理指令。

预处理的特征:

- 通常在程序的开头。

- 必须以#开始。

#define 或 #undef定义宏变量和取消宏

#define定义的又被称为:“宏(macro)变量”。

#define的作用是:编译器在处理程序之前,先执行查找、替换。

通过#define定义宏变量有两个好处:

- 可以方便程序以后修改。

- 可以提高程序的可读性。

#undef:取消宏定义

#define还可以定义带参数的宏

对于带参数的宏定义而言,有两点要注意:

- 定义宏的参数时,并不是定义函数的参数,因此宏的参数无需指定参数类型。

- 使用宏的参数时,一定要参数放在圆括号中。

使用#ifdef   #ifndef   #else   #endif执行条件编译。

它的用法基本上和前面介绍的分支是一样的。

它们的主要作用是判断指定的宏是否存在,根据指定宏是否存在来执行相应的分支。

使用#if #elif #else#endif执行条件编译。

预处理的if分支比普通的if分支的效率要高的多。

能用预处理的if分支,应该尽量使用预处理的if分支。

记住:只要你的if条件中包含了变量、函数调用等表达式,就只能使用普通的if分支。

#include和#import

#include和#import的功能是类似的,但#import的功能更强大一些。

#import就可以自动避免重复include导致的错误。

时间: 2024-11-04 11:46:54

Object-C基础(4)—— 函数的相关文章

python基础——sorted()函数

python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来. Python内置的sorted()函数就可以对list进行排序: >>> sorted([36, 5, -12, 9, -21]) [-21, -12, 5, 9, 36] 此外,sorted()函数也是一个

C++ Primer 学习笔记33_面向对象编程(4)--虚函数与多态(一):多态、派生类重定义、虚函数的访问、 . 和->的区别、虚析构函数、object slicing与虚函数

C++ Primer学习笔记33_面向对象编程(4)--虚函数与多态(一):多态.派生类重定义.虚函数的访问. . 和->的区别.虚析构函数.object slicing与虚函数 一.多态 多态可以简单地概括为"一个接口,多种方法",前面讲过的重载就是一种简单的多态,一个函数名(调用接口)对应着几个不同的函数原型(方法). 更通俗的说,多态行是指同一个操作作用于不同的对象就会产生不同的响应.或者说,多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同的行为. 多态行分

Python基础07 函数

Python基础07 函数 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 函数最重要的目的是方便我们重复使用相同的一段程序. 将一些操作隶属于一个函数,以后你想实现相同的操作的时候,只用调用函数名就可以,而不需要重复敲所有的语句. 函数的定义 首先,我们要定义一个函数, 以说明这个函数的功能. def square_sum(a,b): c = a**2 + b**2 return c 这个函数的功能是求两个数的平方和. 首先

Oracle实践--PL/SQL基础之函数

PL/SQL基础之函数 /* 函数:可以有返回值得命名的PL/SQL子程序,必须有返回值 关键字:function return */ --函数1 create or replace function helloworld return varchar2--指定返回类型,不能给定长度 as v_hello varchar2(50); begin v_hello :='helloworld!'; return v_hello;--不可少的return end; --函数调用方式: select h

SQL Server 基础 04 函数与分组查询数据

函数与分组查询数据 系统函数分 聚合函数.数据类型转换函数.日期函数.数学函数 . . . 1. 聚合函数 主要是对一组值进行计算,然后返回一个值. 聚合函数包括 sum(求和).avg(求平均值).min().max().count(求数量) sum函数语法  :  sum(列明) select sum(sno) as 序号和 from stu_info avg select avg(sno) as 序号平均值 from stu_info . . . count 用来一组值的个数,统计 sel

c#编程基础之函数可变参数

可变参数:int sum (params int[] values)int sum (string name,params int[] values) 注意:params参数必须是形参表中的最后一个参数. 代码如下: using System; using System.Collections.Generic; using System.Text; namespace 函数可变参数学习 { class Program { static void Main(string[] args) { Say

python基础——匿名函数及递归函数

python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x表示函数参数. 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果. 2 匿名函数举例 用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突.此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数: >>> f = lam

数据分析与展示——Matplotlib基础绘图函数示例

Matplotlib库入门 Matplotlib基础绘图函数示例 pyplot基础图表函数概述 函数 说明 plt.plot(x,y,fmt, ...) 绘制一个坐标图 plt.boxplot(data,notch,position) 绘制一个箱体图 plt.bar(left,height,width,bottom) 绘制一个条形图 plt.barh(width,bottom,left,height) 绘制一个横向条形图 plt.polar(theta,r) 绘制极坐标图 plt.pie(dat

java基础--常用函数总结

java基础--常用函数总结 2019-3-16-23:28:01-----云林原创 1.split()字符串分割函数 将一个字符串分割为子字符串,然后将结果作为字符串数组返回. 2.Math.floor( )舍掉小数取整数 3.Math.rint( )四舍五入取整数 4.Math.ceil( )进位取整数 5.IndexOf( )查找特定字符出现的索引 ----------------------------------------->特定字符出现的最先出现的位置:IndexOf(): ---

Typescript基础(2)——函数

前言 今天继续typescript的学习,开始函数的学习. 函数 函数的定义 和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数. 你可以随意选择适合应用程序的方式,不论是定义一系列API函数还是只使用一次的函数. 定义有名字的函数: function fn(){ return 123; } console.log(fn()) 定义匿名函数: let fn1 = function(){ return 456; } console.log(fn1()) 函数定义类型