所谓的作用域就是指变量起作用的范围,也是变量的有效范围。变量按他的作用域可以分为局部变量和全局变量。局部变量在一个函数内部声明的变量是内部变量,它只在本函数内有效,在本函数以外是不能使用的,这样的变量就是局部变量。此外,函数的形参也是局部变量,形参我们会在后面再详细解释。
当我们走在马路上的时候,经常会看到马路两侧有一些 LED 点阵的广告牌,这些广告牌看起来绚烂夺目,非常吸引人,而且还会变化很多种不同的显示方式。本章我们就会学习到点阵 LED 的控制方式,但是首先得来了解一点 C 语言变量的进阶知识——变量的作用域和存储类别。
单片机又称单片微控制器,它不是完成某一个逻辑功能的芯片,而是把一个计算机系统集成到一个芯片上。相当于一个微型的计算机,和计算机相比,单片机只缺少了I/O设备。本文是全程套教程第二部分。适用人群本文手把手教你学51单片机,可让您夯实单片机基础。学习前提本教程中,单片机的功能由C语言实现,如果您不了解C语言,看清阅读C语言入门教程。
在 messager 系统添加的另外一种东西是宏。在 mess_config.hrl 文件中包含如下的定义: %%% Configure the location of the server node,-define(server_node, messenger@super).这个头文件被包括到了 mess_server.erl 文件中: -include("mess_config.hrl").这样,在 mess_server.erl 中出现的每个 server_node 都被替换为 messenger@super。
记录的定义如下: -record(name_of_record,{field_name1, field_name2, field_name3, ......}).例如,-record(message_to,{to_name, message}).
如上所示,某些文件的扩展名为 .hrl。这些是在 .erl 文件中会用到的头文件,使用方法如下: -include("File_Name").例如: -include("mess_interface.hrl").在本例中,上面所有的文件与 messager 系统的其它文件在同一个目录下。 .hrl 文件中可以包含任何合法的 Erlang 代码,但是通常里面只包含一些记录和宏的定义。
为了演示需要,我们将前面几节中 messager 程序分布到五个文件中: mess_config.hrl 配置所需数据头文件mess_interface.hrl 客户端与 messager 之间的接口定义user_interface.erl用户接口函数mess_client.erlmessager 系统客户端的函数mess_server.
让我们改进 Messager 程序以增加该程序的健壮性: %%% Message passing utility. %%% User interface:%%% login(Name)%%% One user at a time can log in from each Erlang node in the%%% system messenger: and choose a suitable Name.
在讨论监督与错误处理细节之前,让我们先一起来看一下 Erlang 进程的终止过程,或者说 Erlang 的术语 exit。 进程执行 exit(normal) 结束或者运行完所有的代码而结束都被认为是进程的正常(normal)终止。 进程因为触发运行时错误(例如,除零、错误匹配、调用不存在了函数等)而终止被称之为异常终止。
在改进 messager 程序之前,让我们一起学习一些基本的原则。回忆一下,当 “ping” 结束的时候,它向 “pong” 发送一个原子值 finished 的消息以通知 “pong” 结束程序。另一种让 “pong” 结束的办法是当 “pong” 有一定时间没有收到来自 “ping” 的消息时则退出程序。我们可在 pong 中添加一个 time-out 来实现它: -module(tut19).
上一节中的完整示例还存在一些问题。当用户所登录的结点崩溃时,用户没有从系统中登出,因此该用户仍然在服务器的 User_List 中,但事实是用户已经不在系统中了。这会导致这用户不能再次登录,因为系统认为它已经在系统中了。 或者,如果服务器发送消息出现故障了,那么这时候会导致客户端在 await_result 函数中一直等待,那又该怎么处理这个问题呢?
接下来这个示例是一个简单的消息传递者(messager)示例。Messager 是一个允许用登录到不同的结点并向彼此发送消息的应用程序。 开始之前,请注意以下几点: 这个示例只演示了消息传递的逻辑---没有提供用户友好的界面(虽然这在 Erlang 是可以做到的)。这类的问题使用 OTP 的工具可以非常方便的实现,还能同时提供线上更新的方法等。
下面我们进一步对 ping pong 示例程序进行改进。 这一次,我们要让 “ping”、“pong” 进程分别位于不同的计算机上。要想让这个程序工作,你首先的搭建一下分布式的系统环境。分布式 Erlang 系统的实现提供了基本的安全机制,它阻止未授权的外部设备访问本机的 Erlang 系统。同一个系统中的 Erlang 要想相互通信需要设置相同的 magic cookie。
上面的例子中,因为 “Pong” 在 “ping” 进程开始前已经创建完成,所以才能将 “pong” 进程的进程标识符作为参数传递给进程 “ping”。这也就说,“ping” 进程必须通过某种途径获得 “pong” 进程的进程标识符后才能将消息发送 “pong” 进程。然而,某些情况下,进程需要相互独立地启动,而这些进程之间又要求知道彼此的进程标识符,前面提到的这种方式就不能满足要求了。
下面的例子中创建了两个进程,它们相互之间会发送多个消息。 -module(tut15).-export([start/0, ping/2, pong/0]).ping(0, Pong_PID) -> Pong_PID ! finished, io:format("ping finished~n", []);ping(N, Pong_PID) -> Pong_PID ! {ping, self()}, receive pong ->
相比于其它函数式编程语言,Erlang 的优势在于它的并发程序设计与分布式程序设计。并发是指一个程序中同时有多个线程在执行。例如,现代操作系统允许你同时使用文字处理、电子制表软件、邮件终端和打印任务。在任意一个时刻,系统中每个处理单元(CPU)都只有一个线程(任务)在执行,但是可以通过以一定速率交替执行这些线程使得这些它们看上去像是在同时运行一样。
Erlang 作为函数式编程语言自然拥有高阶函数。在 shell 中,我们可以这样使用: 86> Xf = fun(X) -> X * 2 end. #Fun<erl_eval.5.123085357>87> Xf(5).10这里定义了一个数值翻倍的函数,并将这个函数赋给了一个变量。所以,Xf(5) 返回值为 10。Erlang 有两个非常有用的操作列表的函数 foreach 与 map, 定义如下: foreach(Fun, [First|Rest]) ->
内置函数是指那些出于某种需求而内置到 Erlang 虚拟机中的函数。内置函数常常实现那些在 Erlang 中不容易实现或者在 Erlang 中实现效率不高的函数。某些内置函数也可以只用函数名就调用,因为这些函数是由于默认属于 erlang 模块。例如,下面调用内置函数 trunc 等价于调用 erlang:trunc。 如下所示,判断一个是否为闰年。如果可以被 400 整除,则为闰年。
上面的 find_max_and_min 函数可以找到温度的最大值与最小值。这儿介绍一个新的结构 if。If 的语法格式如下: if Condition 1 -> Action 1; Condition 2 -> Action 2; Condition 3 -> Action 3; Condition 4 -> Action 4end注意,在 end 之前没有 “;”。
| 操作符可以用于取列表中的首元素: 47> [M1|T1] = [paris, london, rome].[paris,london,rome]48> M1.paris49> T1.[london,rome]同时,| 操作符也可以用于在列表首部添加元素: 50> L1 = [madrid | T1].[madrid,london,rome]51> L1.[madrid,london,rome]使用 | 操作符操作列表的例子如下 -- 翻转列表中的元素: -module(tut8).
关注时代Java