opus编译
Ⅰ “宏”的问题
宏
[编辑本段]一.计算机中的“宏”
什么是宏
计算机科学里的宏是一种抽象,它根据一系列预定义的规则替换一定的文本模式。Excel 办公软件自动集成了“VBA”高级程序语言,用此语言编制出的程序就叫“宏”。使用“VBA”需要有一定的编程基础和耗费大量的时间,因此,绝大多数的使用者仅使用了Excel的一般制表功能,很少使用到“VBA”。
解释器或编译器在遇到宏时会自动进行这一模式替换。对于编译语言,宏展开在编译时发生,进行宏展开的工具常被称为宏展开器。宏这一术语也常常被用于许多类似的环境中,它们是源自宏展开的概念,这包括键盘宏和宏语言。绝大多数情况下,使用“宏”这个词的使用暗示着将小命令或动作转化为一系列指令。
宏的用途在于自动化频繁使用的序列或者是获得一种更强大的抽象能力--但这常常是一回事。
计算机语言如C或汇编语言有简单的宏系统,由编译器或汇编器的预处理器实现。C的宏预处理器的工作只是简单的文本搜索和替换,使用附加的文本处理语言如M4,C 程序员可以获得更精巧的宏。
Lisp类语言如Common Lisp和Scheme有更精巧的宏系统: 宏的行为如同是函数对自身程序文本的变形,并且可以应用全部语言来表达这种变形。一个C宏可以定义一段语法的替换,然而一个Lisp的宏却可以控制一节代码的计算。
获得了控制代码的执行顺序(见惰性计算和非限制函数)的能力,使得新创建的语法结构与语言内建的语法结构不可区分。例如,一种Lisp 方言有 cond 而没有if ,就可以使用宏由前者定义后者。Lisp 语法的去部主要扩展,比如面向对象的CLOS 系统,可以由宏来定义。
宏的典型应用
加速日常编辑和格式设置
组合多个命令
使对话框中的选项更易于访问
使一系列复杂的任务自动执行
宏编程介绍
在用一种不熟悉的宏语言进行宏编程时,可以这样做,首先记录下用户想要宏完成什么,然后打开宏文件并尝试理解命令结构如何工作。也可以修改命令以调整宏。一些宏语言,比如Great Plains账务(?accounting)软件的 Dexterity 运行时引擎,不能从其它数据源(如由逗号分隔的文本文件)导入数据。这一限制可以通过用更强大的编程语言,如 VBA 来创建一个计算机程序在此弱编程语言里生成一个特别的宏来解决。例如,可以对 Microsoft Excel 宏编程从扩展样式表或文本文件中读取数据并创建 Great Plains .mac 文件,这一文件被用于将特定的数据导入 Great Plains. 需要针对每一个新的数据集合声称新的 .mac 文件。
键盘宏
键盘宏和编辑器宏分别在图形用户界面和编辑器中被交互式地使用。使用它们可以用简短的击键代替冗长的命令序列,并为重复性任务提供了一个简单的自动化形式。
程序员的文本编辑器 Emacs (“编辑宏”[Editing MACroS]的简称)是沿用这一思想的产物。事实上,大多数编辑器是由宏组成的,Emacs 最初被设计为编辑语言 TECO 的宏集,后被移植为 Lisp 的一中方言 Emacs Lisp。
宏语言
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用,但在文本处理程序中应用普遍。例如,
C preprocessor C 预处理器
Internet Macros(iOpus)
M4(如前所述,源于AT&T,捆绑于Unix)
宏定义
c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为:
#define 标志符(参数表) 字符串
宏名
在上定义中的标志符被称为“宏名”。
宏展开
在c程序编译时将宏名替换成字符串的过程称为“宏展开”。
微软Word和宏病毒
Visual Basic for Applications (VBA),是 Microsoft Office 里的一种编程语言. 但由上面的定义,它完全不是一种宏语言。然而,它的功能已经从中发展并最终替代了用户应用程序的宏思想,所以他被广泛地错误地称为是一种宏语言。
VBA 可以访问许多操作系统函数并支持文档打开时自动执行宏。这使得用这种语言写计算机病毒成为可能。1990年代中后期,宏病毒成为了最流行的计算机病毒类型之一。其它的包括宏语言的项目,如openoffice.org,故意从其宏语言中排除了一些功能(如:自动执行)以避免破坏程序。然而,这一特性在很多事务中受到欢迎。
[编辑本段]二.汉字:宏
宏 #hóng
【释义】①广大;广博:宏大|宏伟|宽宏大量。②姓。
【宏大】 #hóngdà 宏伟巨大。
〖例句〗小强立下了宏大的志愿,要为将来成为一名出色的建筑工程师努力学习。
【宏图】 #hóngtú 远大的设想,宏伟的计划。
〖例句〗国家希望在海外留学完成学业的人回国,为实现祖国的宏图大业贡献力量。
【宏伟】 #hóngwěi 气势雄壮,规模盛大。
〖例句〗宏伟的人民英雄纪念碑矗立在天安门广场中央。
===================关于这个字的更多的信息=================
宏〈形〉
(形声。从宀,表示与家室房屋有关,厷声。本义:屋子宽大而深)
同本义
宏,屋深响也。――《说文》。段玉裁注:“屋深也。各本深下衍响字,此因下文‘屋响’而误,今依《韵会》、《集韵》、《类篇》正。…屋深者,其内深广也。”
宏我邦我家。――《毛公鼎》
宏,按:深大之屋凡声如有应响。――清·朱骏声《说文通训定声》
大;宏大
宏,大也。――《尔雅·释诂》
若保宏父。――《书·酒诰》
举其宏纲。――《书·序》
其器宏以弇。――《吕氏春秋·孟冬》
又如:宏才(大才);宏硕(大儒硕学。指有学问的人);宏
宏hóng广大,广博:~大。~观。~量。~图。~伟。宽~。
郑码:WDGZ,U:5B8F,GBK:BAEA (5) 笔画数:7,部首:宀,笔顺编号:4451354
Ⅱ 宏定义c语言是什么意思
在C语言源程序中,允许用一个标识符来表示一个字符串,称为宏,宏定义是由源程序中的宏定义命令完成的,宏替换是由预处理程序自动完成的。宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译。
C语言中,预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换,预处理过程还会删除程序中的注释和多余的空白符号。
预处理指令是以#开头的代码行,#必须是该行除了空白字符外的第一个字符。#后是指令关键字,在#和指令关键字之间允许存在若干空白字符。
宏的用途
在于自动化频繁使用的序列或者是获得一种更强大的抽象能力。
计算机语言如C语言或汇编语言有简单的宏系统,由编译器或汇编器的预处理器实现。C语言的宏预处理器的工作只是简单的文本搜索和替换,使用附加的文本处理语言如M4,C程序员可以获得更精巧的宏。
Lisp类语言如Common Lisp和Scheme有更精巧的宏系统:宏的行为如同是函数对自身程序文本的变形,并且可以应用全部语言来表达这种变形。一个C宏可以定义一段语法的替换,然而一个Lisp的宏却可以控制一节代码的计算。
以上内容参考:网络-宏定义
Ⅲ u盘里多了.fseventsd,.Spotlight-V100,.Trashes三个文件夹 怎么删都删不掉
SparkleShare 是一个开源的基于 Git 的 Dropbox 风格的文件共享应用程序。在我们的系列文章中了解有关 Git 鲜为人知的用法。-- Seth Kenlon(作者)
Git 是一个少有的能将如此多的现代计算封装到一个程序之中的应用程序,它可以用作许多其他应用程序的计算引擎。虽然它以跟踪软件开发中的源代码更改而闻名,但它还有许多其他用途,可以让你的生活更轻松、更有条理。在这个 Git 系列中,我们将分享七种鲜为人知的使用 Git 的方法。
今天,我们将看看 SparkleShare,它使用 Git 作为文件共享的基础。
用于文件共享的 Git
Git 的优点之一是它具有固有的分发能力。它可用来建立共享。即使你只是与自己网络上的其他计算机共享资源库,Git 也会为从共享位置获取文件的行为带来透明性。
随着其界面的发展,Git 变得非常简单。虽然因用户而异,他们坐下来完成一些工作时的共同点仅仅是 git pull 或稍微复杂一点的 git pull && git checkout -b my-branch。但是,对于某些人来说,将命令输入到他们的计算机中的做法完全是令人困惑或烦恼的。计算机旨在使生活变得轻松,它擅长于重复性工作,因此有更简便的方法可以与 Git 共享文件。
SparkleShare
SparkleShare 项目是一个基于 Git 的跨平台的、开源的 Dropbox 式的文件共享应用程序。它通过将文件拖放到专门指定的 SparkleShare 目录中的简单操作,自动执行所有 Git 命令,触发添加、提交、推送和拉取过程。因为它基于 Git,所以你可以获得基于差异(diff)的快速推送和拉取,并且继承了 Git 版本控制和后端基础设施(如 Git 挂钩)的所有优点。它可以完全自托管,也可以将其与 GitLab 、GitHub、Bitbucket 等 Git 托管服务一起使用。此外,由于它基本上只是一个 Git 的前端,因此你可以在可能没有 SparkleShare 客户端但有 Git 客户端的设备上访问 SparkleShare 中的文件。
正如你获得 Git 的所有好处一样,你也会受到所有常见的 Git 限制:使用 SparkleShare 存储数百张照片、音乐和视频是不切实际的,因为 Git 是为文本而设计和优化的。Git 当然可以存储二进制文件的大文件,但是因为它可以跟踪历史记录,因此一旦将文件添加到其中,几乎就不可能完全删除它。这在某种程度上限制了 SparkleShare 对某些人的实用性,但使其非常适合许多工作流程,包括 日程安排 。
安装 SparkleShare
SparkleShare 是跨平台的,可从 网站 获得适用于 Windows 和 Mac 的安装程序。对于 linux,有一个 Flatpak 安装包,或者你可以在终端中运行以下命令:
$ sudo flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo
$ sudo flatpak install flathub org.sparkleshare.SparkleShare
创建一个 Git 存储库
SparkleShare 并不是软件即服务(SaaS)。你在计算机上运行 SparkleShare 与 Git 存储库进行通信,而 SparkleShare 并不存储你的数据。如果你还没有与文件夹同步的 Git 存储库,则必须在启动 SparkleShare 之前创建一个文件夹。你有三个选择:托管的 Git、自托管 Git 或自托管 SparkleShare。
托管的 Git
SparkleShare 可以使用你能访问的任何 Git 存储库进行存储,因此,如果你拥有 GitLab 或任何其他托管服务的帐户(或创建一个),则它可以成为 SparkleShare 的后端。例如,开源 Notabug.org 服务是一个类似于 GitHub 和 GitLab 的 Git 托管服务,但其独特性足以证明 SparkleShare 的灵活性。根据用户界面的不同,不同的托管服务创建新存储库的方法也有所不同,但是所有主要存储库都遵循相同的通用模型。
首先,在托管服务中找到创建新项目或存储库的按钮,单击它以开始。然后逐步完成存储库的创建过程,为存储库提供名称、隐私级别(存储库通常默认为公共),以及是否使用 README 文件初始化存储库。无论你是否需要个 README 文件,请初始化建立一个。使用一个文件来创建存储库不是绝对必要的,但是它会强制 Git 主机实例化存储库中的 master 分支,这有助于确保前端应用程序(例如 SparkleShare)具有要提交并推送的分支。即使文件是几乎空的 README 文件,也可以用来查看该文件以确认你已连接成功。
Creating a Git repository
创建存储库后,获取其用于 SSH 克隆的 URL。就像从 Git 项目获得其 URL 一样,你也可以获取此 URL:导航至存储库页面并查找 “Clone” 按钮或字段。
GitHub 的克隆 URL。
GitLab 的克隆 URL。
这是 SparkleShare 用于获取数据的地址,因此请记下它。你的 Git 存储库现已配置好。
自托管的 Git
你可以使用 SparkleShare 访问你有权访问的任何计算机上的 Git 存储库。除了一个 Git 裸存储库外,无需任何特殊设置。但是,如果你想将对 Git 存储库的访问权授予其他任何人,则应运行 Gitolite 之类的 Git 管理器或 SparkleShare 自己的 Dazzle 服务器来帮助你管理 SSH 密钥和帐户。至少,创建一个特定于 Git 的用户,以便有权访问你的 Git 存储库的用户不会自动获得对服务器其余部分的访问权限。
以 Git 用户身份登录服务器(如果你非常擅长管理用户和组权限,则可以以自己的用户登录)并创建存储库:
$ mkdir ~/sparkly.git
$ cd ~/sparkly.git
$ git init --bare .
你的 Git 存储库现已配置好。
Dazzle
SparkleShare 的开发人员提供了一个名为 Dazzle 的 Git 管理系统,以帮助你自托管 Git 存储库。
在你的服务器上,将 Dazzle 应用程序下载到你的路径中的某个位置:
$ curl https://raw.githubusercontent.com/hbons/Dazzle/master/dazzle.sh --output ~/bin/dazzle
$ chmod +x ~/bin/dazzle
Dazzle 设置了一个特定于 Git 和 SparkleShare 的用户,并且还基于 SparkleShare 应用程序生成的密钥实现了访问权限。现在,只需设置一个项目:
$ dazzle create sparkly
你的服务器现在已经配置好,可以用作 SparkleShare 托管了。
配置 SparkleShare
首次启动 SparkleShare 时,系统会提示你配置 SparkleShare 用于存储的服务器。这个过程可能看起来像一个首次运行的安装向导,但实际上是在 SparkleShare 中设置新共享位置的通常过程。与许多共享驱动器应用程序不同,使用 SparkleShare 可以一次配置多个位置。你配置的第一个共享位置并不比你以后可以配置的任何共享位置更重要,并且你也不用注册 SparkleShare 或任何其他服务。你只是将 SparkleShare 指向 Git 存储库,以便它知道如何使第一个 SparkleShare 文件夹保持同步。
在第一个屏幕上,给出一个身份信息,SparkleShare 将在代表你进行的 Git 提交记录中使用这些信息。你可以使用任何内容,甚至可以使用不代表任何意义的伪造信息。它仅用于提交消息,如果你对审查 Git 后端进程没有兴趣,你可能甚至看不到它们。
下一个屏幕提示你选择主机类型。如果你使用的是 GitLab、GitHub、Planio 或 Bitbucket,则可以选择一个适当的。否则,请选择“自己的服务器”。
Choosing a Sparkleshare host
在此屏幕底部,你必须输入 SSH 的克隆 URL。如果你是自托管的 Git,则地址类似于 <ssh://[email protected]>,而远程路径是为此目的而创建的 Git 存储库的绝对路径。
根据上面的自托管示例,我虚构的服务器的地址为 ssh://[email protected]:22122(:22122 表示一个非标准的 SSH 端口),远程路径为 /home/git/sparkly.git。
如果我改用 Notabug.org 帐户,则上例中的地址为 ssh://[email protected],路径为 seth/sparkly.git。
SparkleShare 首次尝试连接到主机时会失败,因为你尚未将 SparkleShare 客户端 ID(特定于 SparkleShare 应用程序的 SSH 密钥)复制到 Git 主机。这是预料之中的,所以不要取消该过程。将 SparkleShare 设置窗口保持打开状态,并从系统任务栏中的 SparkleShare 图标处获取客户端 ID。然后将客户端 ID 复制到剪贴板,以便可以将其添加到 Git 主机。
Getting the client ID from Sparkleshare
将你的客户端 ID 添加到托管的 Git 帐户
除了较小的 UI 差异外,在任何托管服务上添加 SSH 密钥(所有客户端 ID 都是这样)的过程基本上是相同的。在你的 Git 主机的 Web 仪表板中,导航到你的用户设置,然后找到 “SSH 密钥”类别。单击“添加新密钥”按钮(或类似按钮),然后粘贴你的 SparkleShare 客户端 ID 的内容。
Adding an SSH key
保存密钥。如果你希望其他人(例如协作者或家庭成员)能够访问同一存储库,则他们必须向你提供其 SparkleShare 客户端 ID,以便你可以将其添加到帐户中。
将你的客户端 ID 添加到自托管的 Git 帐户
SparkleShare 客户端 ID 只是一个 SSH 密钥,因此将其复制并粘贴到 Git 用户的 ~/.ssh/authorized_keys 文件中。
使用 Dazzle 添加你的客户 ID
如果你使用 Dazzle 管理 SparkleShare 项目,请使用以下命令添加客户端 ID:
$ dazzle link
当 Dazzle 提示你输入该 ID 时,请粘贴在 SparkleShare 菜单中找到的客户端 ID。
使用 SparkleShare
将客户端 ID 添加到 Git 主机后,在 SparkleShare 窗口中单击“重试”按钮以完成设置。克隆存储库完成后,你可以关闭 SparkleShare 设置窗口,并在你的家目录中找到一个新的 SparkleShare 文件夹。如果你设置了带有托管服务的 Git 存储库,并选择包括 README 文件或许可证文件,则可以在 SparkleShare 目录中看到它们。
Sparkleshare file manager
此外,有一些隐藏目录,你可以通过在文件管理器中显示隐藏目录来查看。
Showing hidden files in GNOME
使用 SparkleShare 的方式与使用计算机上任何目录的方式相同:将文件放入其中。每当将文件或目录放入 SparkleShare 文件夹时,它都会在后台复制到你的 Git 存储库。
排除某些文件
由于 Git 从设计上就是要记住一切,因此你可能希望从记录中排除特定的文件类型。排除一些文件是有原因的。通过定义摆脱 SparkleShare 管理的文件,可以避免意外复制大文件。你还可以为自己设计一种方案,使你可以将存储在一个目录中的逻辑上属于同一个文件(例如,MIDI 文件及其 .flac 导出文件),但是可以自己手动备份大文件,而同时让 SparkleShare 备份基于文本的文件。
如果在系统的文件管理器中看不到隐藏的文件,请显示它们。导航到你的 SparkleShare 文件夹,然后到代表你的存储库的目录,找到一个名为 .gitignore 的文件,然后在文本编辑器中将其打开。你可以在 .gitignore 中输入文件扩展名或文件名(每行一个),任何与你列出的文件匹配的文件都会被忽略(如文件名所示)。
Thumbs.db
$RECYCLE.BIN/
.DS_Store
._*
.fseventsd
.Spotlight-V100
.Trashes
.directory
.Trash-*
*.wav
*.ogg
*.flac
*.mp3
*.m4a
*.opus
*.jpg
*.png
*.mp4
*.mov
*.mkv
*.avi
*.pdf
*.djvu
*.epub
*.od{s,t}
*.cbz
你知道最经常遇到哪些文件类型,因此请集中精力处理最有可能潜入你的 SparkleShare 目录的文件。如果你想稍微矫枉过正一些,可以在 Notabug.org 以及整个网上找到 .gitignore 文件的好集合。
通过将这些条目保存在 .gitignore 文件中,你可以将不需要发送到 Git 主机的大文件放在 SparkleShare 目录中,SparkleShare 将完全忽略它们。当然,这意味着你需要确保它们可以备份或通过其他方式分发给你的 SparkleShare 协作者。
自动化
自动化 是我们与计算机达成的默契之一:计算机执行重复的、无聊的工作,而我们人类要么不擅长做这些,要么不擅长记忆这些。SparkleShare 是一种很好的、简单的自动执行例行数据分发的方法。但不管怎么说,这并不适合每个 Git 存储库。它没有用于高级 Git 功能的接口,它没有暂停按钮或手动管理的操作。没关系,因为它的使用范围是有意限制的。SparkleShare 可以完成它计划要做的事情,它做得很好,而且它是你无需关心的一个 Git 存储库。
如果你想使用这种稳定的、看不见的自动化,请尝试一下 SparkleShare。
via: https://opensource.com/article/19/4/file-sharing-git
作者: Seth Kenlon 选题: lujun9972 译者: wxy 校对: wxy
本文由 LCTT 原创编译, Linux中国 荣誉推出
Ⅳ C语言中,宏替换的替换规则
简单来说:宏定义又称为宏代换、宏替换,简称“宏”。宏替换是C/C++的预处理中的一部分,在C++标准中有4条规则来定义替换。
规则1:实参替换。
本条规则描述带参数的宏的替换过程。
对于宏定义中的形参,在替换列表中,如果不是作为#或##的操作数,那么将对应实参完全
展开(相当于对实参进行求值),然后将替换列表中的形参替换掉.如果是#或##的操作数,
那么不进行替换。
规则2:多次扫描。
在所有的形参替换为实参后,对结果进行再次扫描,如果发现还有可替换的宏,则进行替换,
否则中止。
规则3:递归替换抑制。
如果在替换列表中发现当前正在展开的宏的名字,那么这里不进行替换.更进一步,在嵌套
的替换过程中发现已经替换过的宏的名字,则不进行替换。
规则4:递归预处理抑制。
如果替换后的结果形成预处理指令,则不执行这条预处理指令。
看几个C++标准中的例子:
#define x 3
#define f(a) f(x * (a))
#undef x
#define x 2
#define g f
#define z z[0]
#define h g(~
#define m(a) a(w)
#define w 0,1
#define t(a) a
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h 5) & m(f)^m(m);
其结果分别是
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * ( ~ 5)) & f(2 * (0,1))^m(0,1);
对于第一个,主要在于t(t(g)(0) + t)(1)的展开。
容易计算出最外层的t的实参是f(2 * (0)) + t,而作为t的参数传入时其中的t是
正在被展开的宏,所以根据规则3,不对这个t进行处理,保持不变,得到f(2 * (0)) + t(1)。
对于第二个,h 5)被替换为g(~5),应用规则2,被替换为f(2 * ( ~ 5))。
而m(m)首先被替换为m(w),然后应用规则2再次进行替换,但是m已经是替换过的了,所以保持
不变,只对w进行替换。
#define str(s) # s
#define xstr(s) str(s)
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s",
x ## s, x ## t)
#define INCFILE(n) vers ## n /* from previous #include example */
#define glue(a, b) a ## b
#define xglue(a, b) glue(a, b)
#define HIGHLOW "hello"
#define LOW LOW ", world"
debug(1, 2);
fputs(str(strncmp("abc d", "abc", ’4’) /* this goes away */
== 0) str(: @ ), s);
#include xstr(INCFILE(2).h)
glue(HIGH, LOW);
xglue(HIGH, LOW)
其结果分别是
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
fputs("strncmp("abc\0d", "abc", ’\4’) = = 0" ": @ ", s);
#include "vers2.h"
"hello";
"hello" ", world"
关键是glue和xglue.
对于glue(HIGH, LOW),首先有一个规则1的抑制,得到HIGHLOW;的结果,然后二次扫描,得到
"hello";
对于xglue(HIGH, LOW)没有抑制效果,所以对参数求值,分别得到HIGH和LOW ", world",即
glue(HIGH, LOW ", world")。
然后进行连接操作得到HIGHLOW ", world",最后再扫描一次得到"hello" ", world"
如果考虑字符串的自然的连接,就可以得到"hello, world"了。
(4)opus编译扩展阅读
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用,但在文本处理程序中应用普遍。例如, C preprocessor C预处理器Internet Macros(iOpus) M4(如前所述,源于AT&T,捆绑于Unix)
宏定义
c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为:
#define标志符[(参数表)] 字符串
宏名
在上定义中的标志符被称为“宏名”。
宏展开
在c程序编译时将宏名替换成字符串的过程称为“宏展开”。
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用, 但在文本处理程序中应用普遍。例如,
C preprocessorC 预处理器
Internet Macros(iOpus)
M4(如前所述,源于AT&T,捆绑于Unix)
Ⅳ 计算机中出现的宏设置是什么意思
计算机科学里的宏是一种抽象,它根据一系列预定义的规则替换一定的文本模式。Excel 办公软件自动集成了“VBA”高级程序语言,用此语言编制出的程序就叫“宏”。使用“VBA”需要有一定的编程基础和耗费大量的时间,因此,绝大多数的使用者仅使用了Excel的一般制表功能,很少使用到“VBA”。 解释器或编译器在遇到宏时会自动进行这一模式替换。对于编译语言,宏展开在编译时发生,进行宏展开的工具常被称为宏展开器。宏这一术语也常常被用于许多类似的环境中,它们是源自宏展开的概念,这包括键盘宏和宏语言。绝大多数情况下,使用“宏”这个词的使用暗示着将小命令或动作转化为一系列指令。 宏的用途在于自动化频繁使用的序列或者是获得一种更强大的抽象能力--但这常常是一回事。 计算机语言如C或汇编语言有简单的宏系统,由编译器或汇编器的预处理器实现。C的宏预处理器的工作只是简单的文本搜索和替换,使用附加的文本处理语言如M4,C 程序员可以获得更精巧的宏。 Lisp类语言如Common Lisp和Scheme有更精巧的宏系统: 宏的行为如同是函数对自身程序文本的变形,并且可以应用全部语言来表达这种变形。一个C宏可以定义一段语法的替换,然而一个Lisp的宏却可以控制一节代码的计算。 获得了控制代码的执行顺序(见惰性计算和非限制函数)的能力,使得新创建的语法结构与语言内建的语法结构不可区分。例如,一种Lisp 方言有 cond 而没有if ,就可以使用宏由前者定义后者。Lisp 语法的去部主要扩展,比如面向对象的CLOS 系统,可以由宏来定义。 宏的典型应用 加速日常编辑和格式设置 组合多个命令 使对话框中的选项更易于访问 使一系列复杂的任务自动执行 宏编程介绍 在用一种不熟悉的宏语言进行宏编程时,可以这样做,首先记录下用户想要宏完成什么,然后打开宏文件并尝试理解命令结构如何工作。也可以修改命令以调整宏。一些宏语言,比如Great Plains账务(?accounting)软件的 Dexterity 运行时引擎,不能从其它数据源(如由逗号分隔的文本文件)导入数据。这一限制可以通过用更强大的编程语言,如 VBA 来创建一个计算机程序在此弱编程语言里生成一个特别的宏来解决。例如,可以对 Microsoft Excel 宏编程从扩展样式表或文本文件中读取数据并创建 Great Plains .mac 文件,这一文件被用于将特定的数据导入 Great Plains. 需要针对每一个新的数据集合声称新的 .mac 文件。 键盘宏 键盘宏和编辑器宏分别在图形用户界面和编辑器中被交互式地使用。使用它们可以用简短的击键代替冗长的命令序列,并为重复性任务提供了一个简单的自动化形式。 程序员的文本编辑器 Emacs (“编辑宏”[Editing MACroS]的简称)是沿用这一思想的产物。事实上,大多数编辑器是由宏组成的,Emacs 最初被设计为编辑语言 TECO 的宏集,后被移植为 Lisp 的一中方言 Emacs Lisp。 宏语言 宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用,但在文本处理程序中应用普遍。例如, C preprocessor C 预处理器 Internet Macros(iOpus) M4(如前所述,源于AT&T,捆绑于Unix) 宏定义 c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为: #define 标志符(参数表) 字符串 宏名 在上定义中的标志符被称为“宏名”。 宏展开 在c程序编译时将宏名替换成字符串的过程称为“宏展开”。 微软Word和宏病毒 Visual Basic for Applications (VBA),是 Microsoft Office 里的一种编程语言. 但由上面的定义,它完全不是一种宏语言。然而,它的功能已经从中发展并最终替代了用户应用程序的宏思想,所以他被广泛地错误地称为是一种宏语言。 VBA 可以访问许多操作系统函数并支持文档打开时自动执行宏。这使得用这种语言写计算机病毒成为可能。1990年代中后期,宏病毒成为了最流行的计算机病毒类型之一。其它的包括宏语言的项目,如openoffice.org,故意从其宏语言中排除了一些功能(如:自动执行)以避免破坏程序。然而,这一特性在很多事务中受到欢迎。
Ⅵ linux下编译ffmpeg时关于configure的问题.
你准备工作没做好吧!!
先编译安装Yasm。
然后编译安装H.264 (也就是x264)。
再编译安装AAC audio encoder (fdk-aac)。
编译安装libmp3lame (MP3 audio encoder)。
编译安装libopus (Opus audio decoder and encoder)。
编译安装libvpx (VP8/VP9 video encoder and decoder)。
做后编译安装ffmpeg。
其中1-6你可以选择编译安装,也可以使用源直接安装。安装后了再编译安装ffmpeg
你使用 sudo ldconfig -p |grep libx264 看看你的libx264是否正确安装.
你编译安装x264的时候可以使用2中方式都安装。
先
cd ../x264
./configure --enable-shared
make
make install
最后
cd ../x264
make distclean
./configure --enable-static
make
make install
Ⅶ 张汝伦的抄袭事件
针对复旦大学教授张汝伦的专着《历史与实践》,孙周兴教授在《中华读书报》(2000 年3月29日)发表评论——《实践哲学的悲哀》:称该书“并不是张汝伦教授的‘着作’ ,而是一本‘译作’,或者充其量也只能说张汝伦教授‘编译’的”,因而《历史与实践》是“伪书”、张是“文抄公”。
为了“不负孙教授的苦心,亦为《历史与实践》的读者负责”,张汝伦教授发表《批评的悲哀》(注:《中华读书报》2000年3月29日。):称其书“主题极为突出,无论在内容、风格和目的上都与《哲学历史词典》有极大的不同”,而且“除了‘实践概念和实践哲学’这一节引用了《哲学历史词典》的一些材料外,《历史与实践》与《哲学历史词典》没有任何关系”。在他看来,其《历史与实践》“有着明确的主题、完整的结构和一以贯之的思路和线索。正是这些使所谓它是一部‘伪书’的指控不攻自破”。而孙“真正目的是仅仅根据那几页来自《哲学历史词典》的材料没有注明出处,来一口咬定这本书是抄自该词典。其想象也未免太大胆了一些,但却忘了小心求证。《历史与实践》共487页,要证明它抄自《哲学历史词典》,仅靠他目前提供的那点证据是远远不够的。即使是他提到的第103~105页的内容,要证明它出自《哲学历史词典》或其他任何一本书,我想他也是绝对办不到的,更不用说本书的其他部分了。孙教授……缺乏足够的证据就一口咬定《历史与实践》一书是抄自《哲学历史词典》,这就不是批评,而是诬陷和诽谤了。而诬陷和诽谤就不仅仅是一个道德问题了”。
很显然,在上述回应中,张汝伦教授既没有丝毫的自我批评,也没有对孙教授认定的《历史与实践》第98~102页抄自《哲学历史词典》的批评有任何认错的表示。张教授尽管无奈中遮遮掩掩地表示“‘实践概念和实践哲学’这一节引用了《哲学历史词典》的一些材料”,但他强调的还是已经“把自己的东西和别人的东西分得很清楚了”。如此一来,逼得孙周兴教授只好在《悲哀复悲哀》中继续揭发、再证《历史与实践》的抄袭性质:“经本人对张汝伦教授的‘专着’《历史与实践》第96~105页与德文版《哲学历史词典》第七卷中‘实践、实践的’条目所作的仔细对照,现已查明,其中有7页文字(第96~102页,其余3页性质不明),加上这7页中出现的32个注释,完完全全是从上述《词典》条目中抄袭下来的,其中没有一个句子是属于张汝伦教授自己的……我断定:张汝伦教授的《历史与实践》具有抄袭性质,是一部伪书。而且我断定:这种把《词典》条目正文连同注释不加修饰地照抄下来的做法,决非出于无意和疏忽,而是一种蓄意的剽窃行为。”
孙周兴先生原为浙江大学教授,现任同济大学教授,以研究海德格尔着称。他说:“ 我与张汝伦教授是熟识的同行,既没有个人恩怨,也没有发生过学术上的争论。”“在我的印象当中,张汝伦是一位严肃的学者,在学术上经常表现出凛然不可犯的样子,学风应该是正派的。”张汝伦先生是复旦大学哲学系的名牌教授,不仅搞西方现代哲学,而且也出了大部头的中国现代哲学专书。只是张教授不够爱惜自己,倒了牌子,砸了形象,尽管他仍在复旦大学继续当教授和博士生导师。
因为在张汝伦教授出事之前,已有中文系申小龙教授抄袭在先,继之有哲学系佘碧平副教授剽窃在后,还有历史系已通过答辩的某博士学位论文被发现存在大量抄袭的问题,故他们工作的大学曾一度被风趣的网友给幽默为“复印大学”。其实,与其说是幽默,毋宁说是无奈、痛心、心酸,或者说是“怒其不争”“恨铁不成钢”。
悲哀复悲哀——再证张汝伦《历史与实践》的抄袭性质
时间:2001年11月21日
作者:孙周兴(浙江大学教授)
来源:原创
关键词:
这是一篇揭露学界丑事的文章
读了张汝伦教授的文章《批评的悲哀——我对孙周兴教授批评的回答》,首先知道自己已得了一个不小的“罪过”:原以为只有“实践哲学”被张教授弄得比较悲哀了,没想到因为我那篇揭露他的《历史与实践》抄袭真相的文章,中国的“批评”也变得悲哀了。张教授的说法是:国外的批评是“对事不对人”,而国内的批评则是“对人不对事”。不过,张教授应该没有忘记,对于他的同一本“专着”《历史与实践》,我曾撰写过一篇赞扬性的书评;现在我发现他这本书具有抄袭性质,所以要写文章予以揭露。张教授,你说我是“对人”还是“对事”?
张教授还在文中说:“客观公正的批评还牵涉到学者的人品、修养和风度”。意思大概是指责作为批评者的孙周兴在“人品、修养和风度”方面大有问题。这话若由旁的人说出来,我还愿意听一听,然后好好反省一下自己最近的作为;但现在由张汝伦教授来说这个话,我就只觉得有点滑稽了。
为避免被张教授混淆了视听,看来我还得首先作一次澄清:拙文《实践哲学的悲哀》(以下简称《悲哀》)根本就不是一篇学术批评文章,而是一篇揭露学界丑事的文章(读者诸君眼下看到的这篇亦属此类)。学术批评是讨论学术问题的,而我现在没有任何学术问题需要向张教授请教的,其实拙文《悲哀》也没有涉及任何学术性的问题,而只是向读者们报道张教授是如何抄袭的。我的主张是:对于学术问题,大家讨论时应当而且必须心平气和,与人为善。而对于学界丑陋现象的揭露,就是另一回事了,摆出事实后,稍稍传达一点愤怒和讥讽,不但是可以的,而且是必需的。举个例子说,群众抓住了一个偷儿,当然是可以、而且是大有必要表达一下愤怒的心情的。
然而,偷儿也有自己的逻辑。群众愤怒地对偷儿说:喂,你这几件东西是偷来的!偷儿看看人证物证俱在,就答道:第一、不错,这几件东西是人家的,但不是我偷来的,而是“借”来的,只是有一点点对不起了,我忘了从哪里“借”的,本来我是要跟人家说一声的;第二、即使这几件东西是人家的,我这里还有别的几样东西,你们知道它们是从哪里来的吗?哈哈,我看你们就不知道!所以,我怎么可能是小偷?!
上帝见谅,我为这段文字犹豫了好几天,一直想把它删掉算了,免得张教授生气,以为我又在存心“讽刺和挖苦”。但读者诸君,你们如果把张教授的《批评的悲哀》一文总结、提炼一下,就会看到其中的意思差不多也就是上面两点。更有甚者,在表达了这个意思以后,张教授就壮了胆子,反过来倒打一耙,指责我“诬陷”和“诽谤”他了。我想,这就有点无耻了。
的确,到眼下为止,除了《悲哀》一文所做的以及本文要补充的事实指证外,我还不知道《历史与实践》中的“别的东西”是从哪里来的。因为我已经在《悲哀》一文中明言,我眼下身在德国,手头只有《历史与实践》第96-105页的复印件。但我认为,我陈述的事实已足以证明《历史与实践》的抄袭性质了。张汝伦教授避而不谈我举证的事实,却振振有词地要求我拿出更多的“证据”,因为他说这本书一共有487页——这就接近于我前面讲的偷儿的“逻辑”了!
从操作角度上讲,张汝伦教授对我提出的这个要求也是不可能实现的。之所以不可能,是因为外文版的哲学图书和资料浩如烟海,张教授既然抄袭了《哲学历史词典》,也就有可能抄其他图书;而且,倘若我又找出十页、二十页来,张教授还是会说:那么还有其他的呢?这样推下去,即使我有愚公移山的精神,显然也是完成不了这项艰巨任务的。
继续揭发
要做这种全面的对照工作,其实只有一个人能够胜任——那就是张教授自己,正如只有他清楚地知道,我指证的10页中有3页不是从《词典》中抄来的。也正因此,张教授才敢在文中指责我的证据“其实只涉及从98-102页等5页的内容”,并责问道:“其余5页的内容既然也可在该条目下找到,为何不一并‘揭发’,以正视听?”
既然张教授这样问了,我只好答一答。我在写《悲哀》一文时,因为篇幅的限制,的确没有从第96页开始“揭发”,而是从第98页开始,止于第102页。到第102页,觉得文章已经太长,而且证据已经确凿,就没有再对照下去。现在听张教授一说,我对照了一下,确实没有在《词典》第七卷相关条目中发现第103页以下3页的内容。
但无论如何,张汝伦教授要求我继续“揭发”的“其余5页”中的另外2页(即第96-97页)的内容,却是完完全全在这部词典上的。既然张教授要求我一并“揭发”出来,我在这里只得把这2页也补上。
张教授的原文如下:
筑,学习或趋向目标和本身即是目的(如生活、幸福、看、沉思和思考)。这些活动就是狭义的“实践”。亚里士多德用Energeia这个词来专指这种目标在其本身的实践。这就把行为与“做”与“生产”区分开来了。实践是趋向目的的过程和本身就是目的的“行”。《尼各马可伦理学》虽然使用的术语与《形而上学》有所不同,但基本上仍坚持了这种区分。只不过在《形而上学》中Energeria只是指自身就是目的的行为,而在《尼各马可伦理学》中实现目的的过程也叫做Energeria。实践及其对象同时也是人存在表现的全部形式的总称:既指理论科学,工艺技术和狭义的行为,但另一方面也指有别于理论,工艺的人的活动。(注8)这种三分法对亚里士多德哲学本身以及后世的实践哲学都有很大的意义。狭义的实践概念,即我们正在考察的实践概念由此有了明确的规定和轮廓。[抄自第1281页]行为就是做决定,行为的对象就是决定的对象。与这种三分法相应,亚里士多德把真理的形式也分为三种,实践以“实践的真理”为目标。在试图从内容上确定通过行为实现的最高的善时,亚里士多德从柏拉图那里接受了把生活形式分为理论——哲学生活和公民——政治生活的做法。(注9)不过与后来中世纪翻译亚里士多德的做法不同的是,亚里士多德把日常生活称为“政治生活”而不是“实践生活”。“实践生活”指的是哲学专门的理论生活方式。[抄自第1282页]只有Eupragia(正确的行为)才是人的最终目标,而幸福作为所有人实践的目标本身就是实践。(注10)实践在这里既不是生物学或宇宙学意义上的创造运动,也不是单一的行为或活动,更不是生物学的功能,而是正确的行为,即一个完全圆满的完成,自身构成目的的实践。这就是作为实践哲学的核心概念的“实践”的基本意义。[抄自第1283页]这种正确的行为,即实践,与他人和社会的福祉有关,主要是指与生产劳动相区别的人的伦理道德行为和政治行为。然而,理论在最终意义上自身便是目的,故它是最高的实践。(注11)[抄自第1285页] 但亚里士多德以后,人们对“实践”概念的理解却逐渐狭窄。普罗丁把实践理解为由向外的趋向造成的行为。(注12)他也像亚里士多德一样,把最高的活动称为Energeia。但这不是指实践,而是指Poiesis(生产)。实践只是理论的一种派生形式,因为外向的实践是模仿最高的和第一的Poiesis,它由于自身的弱点不能以自身为目标,而需要向外诉求。“人们在理论上不行,就转向实践——理论和逻各斯的影子”。(注13)与亚里士多德相反,不是理论是实践的形式,而是实践是理论的形式。实践只是为了观察,因为一切实践都要求回到纯理论的特殊起源。[抄自第1286页]早期中世纪并未接受古希腊的实践概念,只是通过对亚里士多德的《尼各马可伦理学》的翻译诠释,实践概念才重新进入欧洲的精神世界。希腊的实践在拉丁文中被译为actus,这就使它有了“行动”的意思,并且是与人的意志选择有关的活动。这是中世纪后期哲学的实践概念的基本规定。[抄自第1287页]罗吉尔·培根认为要在一切科学和道德哲学中区分出思辩因素和实践因素。因为人的活动都是可以进行道德评价的行为,在此意义上理智被称为“实践的”,因为它完成实践,即善或恶的行为。这样,实践概念又和道德行为相关了。道德哲学因此和神学一起有一种基础科学的地位。与这种狭义的实践相比,其它认识都是思辨的,是为实践服务的。“一切不教我们善的科学,真正和绝对地看都是思辨的,这就是道德科学之外的一切科学。只有教我们为善的科学才是真正和绝对是实践的”。(注14)[抄自第1288页](张汝伦:《历史与实践》,第96-98页)
首先要做两点说明:一、上列引文开头的“筑”字前面一个字在《历史与实践》的第95页上面,是我目前见不到的,但对照一下德文原文,就可以确定那就是“建”字了,而这也表明第95页上至少还有一段文字是抄袭的。二、最后一句话已经在98页上了,紧接着就是张教授抄来的关于邓·司各特的实践概念那一段了。
本来我想仍旧按照《悲哀》一文的做法,根据德文原文(《哲学历史词典》第七卷第1281-1288页,原作者为GüntherBien先生)把张教授的文字再译一遍,但我发现他这里的译文基本上还是忠实的,再译实在是多此一举,所以,我只用黑体字在上列引文中间标明原文的页码。张教授在这里的抄袭手段,自然也跟我在《悲哀》中描述的一模一样:仍旧是把比较难解难译的句子跳过去,不认识的希腊文词语和句子就不抄,原文共有51个注释,他抄下来7个。但上引《历史与实践》的两页文字,字字句句都在《词典》里面,没有一句是张教授自己写的!
注释也是抄来的
关于注释的抄袭性质,我在拙文《悲哀》中没有充分举证,这里需要补一下,以免张汝伦教授又怪我的工作做得不到家。因为《历史与实践》做的不是当页注,所以我见不到他上引两页的注释。但根据德文原文,我就知道张教授抄袭下来的7个注释是下面这个样子的:
注8:Aristoteles:Eth.Nic.I,1,1049a1。
注9:Aristoteles:Eth.Nic.I,3,1095b14ff。
注10:Aristoteles:Pol.VII,3,1325a32。 注11:J.Frese:Proze?imHandlungsfeld(1985)32f。
注12:Plotin:Enn.V,3,6,35;IV,4,4;VI,8,6,20。
注13:Plotin:8,4,32。
注14:RogerBacon:MoralisPhilosophia,hg.E.Massa(Zürich1953),249;vgl.auchOpustertium,a.O.13,48。
读者只要把《历史与实践》第二章的注释部分翻开来对照一下,就会看到其中的第8-14个注就如上列。在这7个注释当中,注8、注9、注10抄自《词典》第七卷原文第1285页上的注31、注36、注42;注12、注13抄自原文第1287页上的注3、注6;注14抄自原文第1294页上的注16。最有趣的是注11,张教授抄的竟是人家在注释中的一个注释:他把原文第1285页上的注51中的一句话(“……理论是最高的实践”)抄了下来,顺手就加了一个注,把其中列出的一本参考书标上了!但这回可真把我弄苦了:我在原文正文中反复查找,差点以为这个注终于是张教授“自己的东西”了。
加上我在《悲哀》中举证过的5页,在他抄自《词典》的7页文字中(《历史与实践》第96-102页),张教授一共抄袭了原文的32个注释———在我的记忆中,他的注释都是用外文原文标出的。但他在《批评的悲哀》一文中居然还能说:为了表明他的书是虚心地“听别人的意见”,所以他就“尽量多加注(全书487页,共843个注,平均每1页两个注)”。从我们举出的事实看,注释确实是蛮多的,但不是张教授自己“加”的,而是抄来的。而以这些抄来的注释为依据的“参考文献”(其中应有希、拉、德、英、法等多种欧洲语言的书目),当然也是抄来的了。——这还用得着我来证明么?
在《词典》注释中出现的书名多半是缩写的,比如上列注8和注9中的亚里士多德的《尼各马可伦理学》(Nikomachische Ethik)被缩写为:Eth.Nic.。上列注12中的Enn.也是普罗丁的Enneades(《九章集》)一书的缩写。《词典》中可以缩写,但在“专着”中就不行了。所以,张教授在抄袭这些注释时,还不得不做一个从书名缩写到全名的“恢复”工作。这个工作是够他烦的!
张教授在《批评的悲哀》一文中为读者们编造了一个美丽的谎言:他说《历史与实践》的“相当一部分内容”其实是他在德国时的“读书记录和笔记”,但最初记下来并不是为了出版,而“只是为了自己看”,所以“摘录、翻译”都“比较随意”,后来回国了,“觉得实践哲学非常重要,而国内对之了解不够,遂决定在此基础上成书”;又因为回国以后已经找不到有关图书了,所以他就没有注明出处(参看张汝伦:《批评的悲哀》第三段;重点号为引者所加)。根据我上面的举证,他的这个谎言已经可以不攻自破:要不是从一开始就为了出书而存心剽窃,而只是做一点供自己欣赏的“比较随意”的“笔记”,张教授又何苦把原文中的这许多个注释严格地一一查对、抄录下来,并且要做好上述繁琐的“恢复”工作?
到这里,我要来谈谈《历史与实践》的“后记”了,因为张教授在《批评的悲哀》中主要是用这个“后记”来表明他没有抄袭。诚如张教授所言,我以前是好好读过他这个“后记”的,当时却丝毫没感觉到它有什么特别的,自然也没有体会到它的真正“功能”和“意义”。现在我没法重温这个“后记”,但我已从张教授那里知道了它的巨大威力,因为它把“像这种由于某种原因未注明出处的材料都包括进去了”(张汝伦:《批评的悲哀》第三段。而这也就是说,这个“后记”能够把张教授在《历史与实践》中的抄袭行径完全“合法化”,能够把他抄来的别人的文字都占为己有!读者诸君,你们说这一招厉害不厉害?
看来张教授真是深谋远虑,早就在抄好书后精心制作了这个“后记”,自以为已经为自己留了一条退路。但我有点怀疑:这能成为一条退路吗?整页整页地抄了人家的文字(论述、引文和注释)之后,只要在“后记”中说明一下这本书是根据自己的一些读书“心得和记录”写成的,你就可以为自己的抄袭行为辩护了吗?
如果张教授的这种“逻辑”可以成立,则无论是谁都可以把他的“专着”《历史与实践》再“记录”一遍,然后也写个“后记”说明是“心得和记录”,把书名改一下,然后署上无论是谁的大名,就拿去出版好了。这样做来固然好,但不知道他张教授愿意不愿意?
抄袭性质不容置疑
好了,让我来作一个总结,最后把张汝伦教授《历史与实践》一书的抄袭事实明确如下:
经本人对张汝伦教授的“专着”《历史与实践》第96-105页与德文版《哲学历史词典》第七卷中“实践、实践的”条目所作的仔细对照,现已查明,其中有7页文字(第96-102页,其余3页性质不明),加上这7页中出现的32个注释,完完全全是从上述《词典》条目中抄袭下来的,其中没有一个句子是属于张汝伦教授自己的。粗略计算一下,已举证的正文为7页,32个注释以每个至少一行计算,约为1.5页,此外还有第95页的部分或全部,暂且折合为0.5页(声明:这是我推断出来的,因为第96页上只是亚里士多德实践概念的后半部分,前半部分必定在第95页上了),共计9页。这就是说,仅仅根据对《历史与实践》10页文字的调查,我已经确证张汝伦教授至少抄袭了9页、6750个汉字(以每页750个计)。据此事实,我断定:张汝伦教授的《历史与实践》具有抄袭性质,是一部伪书。而且我断定:这种把《词典》条目正文连同注释不加修饰地照抄下来的做法,决非出于无意和疏忽,而是一种蓄意的剽窃行为。
对于这个事实的鉴定工作,我建议可以由国内从事西方哲学研究的同行组成专家小组来完成。根据我新近了解到的情况,北京大学图书馆就有这套德文版的《哲学历史词典》,因此完全有条件在国内进行这项鉴定。而对于我基于这个事实所做的断定,我想请读者诸君来评论。因为,学术乃天下公器,而群众的眼睛是雪亮的。
Ⅷ 宏的宏语言
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用,但在文本处理程序中应用普遍。例如, C preprocessor C预处理器Internet Macros(iOpus) M4(如前所述,源于AT&T,捆绑于Unix)
宏定义
c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为:
#define标志符[(参数表)] 字符串
宏名
在上定义中的标志符被称为“宏名”。
宏展开
在c程序编译时将宏名替换成字符串的过程称为“宏展开”。
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用, 但在文本处理程序中应用普遍。例如,
C preprocessorC 预处理器
Internet Macros(iOpus)
M4(如前所述,源于AT&T,捆绑于Unix)
Ⅸ 电脑软件中的(宏)功能是什么
计算机科学里的宏是一种抽象,它根据一系列预定义的规则替换一定的文本模式。Excel 办公软件自动集成了“VBA”高级程序语言,用此语言编制出的程序就叫“宏”。使用“VBA”需要有一定的编程基础和耗费大量的时间,因此,绝大多数的使用者仅使用了Excel的一般制表功能,很少使用到“VBA”。 解释器或编译器在遇到宏时会自动进行这一模式替换。对于编译语言,宏展开在编译时发生,进行宏展开的工具常被称为宏展开器。宏这一术语也常常被用于许多类似的环境中,它们是源自宏展开的概念,这包括键盘宏和宏语言。绝大多数情况下,使用“宏”这个词的使用暗示着将小命令或动作转化为一系列指令。 宏的用途在于自动化频繁使用的序列或者是获得一种更强大的抽象能力--但这常常是一回事。 计算机语言如C或汇编语言有简单的宏系统,由编译器或汇编器的预处理器实现。C的宏预处理器的工作只是简单的文本搜索和替换,使用附加的文本处理语言如M4,C 程序员可以获得更精巧的宏。 Lisp类语言如Common Lisp和Scheme有更精巧的宏系统: 宏的行为如同是函数对自身程序文本的变形,并且可以应用全部语言来表达这种变形。一个C宏可以定义一段语法的替换,然而一个Lisp的宏却可以控制一节代码的计算。 获得了控制代码的执行顺序(见惰性计算和非限制函数)的能力,使得新创建的语法结构与语言内建的语法结构不可区分。例如,一种Lisp 方言有 cond 而没有if ,就可以使用宏由前者定义后者。Lisp 语法的去部主要扩展,比如面向对象的CLOS 系统,可以由宏来定义。
宏的典型应用
加速日常编辑和格式设置 组合多个命令 使对话框中的选项更易于访问 使一系列复杂的任务自动执行
宏编程介绍
在用一种不熟悉的宏语言进行宏编程时,可以这样做,首先记录下用户想要宏完成什么,然后打开宏文件并尝试理解命令结构如何工作。也可以修改命令以调整宏。一些宏语言,比如Great Plains账务(?accounting)软件的 Dexterity 运行时引擎,不能从其它数据源(如由逗号分隔的文本文件)导入数据。这一限制可以通过用更强大的编程语言,如 VBA 来创建一个计算机程序在此弱编程语言里生成一个特别的宏来解决。例如,可以对 Microsoft Excel 宏编程从扩展样式表或文本文件中读取数据并创建 Great Plains .mac 文件,这一文件被用于将特定的数据导入 Great Plains. 需要针对每一个新的数据集合声称新的 .mac 文件。
键盘宏
键盘宏和编辑器宏分别在图形用户界面和编辑器中被交互式地使用。使用它们可以用简短的击键代替冗长的命令序列,并为重复性任务提供了一个简单的自动化形式。 程序员的文本编辑器 Emacs (“编辑宏”[Editing MACroS]的简称)是沿用这一思想的产物。事实上,大多数编辑器是由宏组成的,Emacs 最初被设计为编辑语言 TECO 的宏集,后被移植为 Lisp 的一中方言 Emacs Lisp。
宏语言
宏语言是一类编程语言,其全部或多数计算是由扩展宏完成的。宏语言并未在通用编程中广泛使用,但在文本处理程序中应用普遍。例如,
C preprocessor C 预处理器 Internet Macros(iOpus) M4(如前所述,源于AT&T,捆绑于Unix) 宏定义 c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为: #define 标志符(参数表) 字符串 宏名 在上定义中的标志符被称为“宏名”。 宏展开 在c程序编译时将宏名替换成字符串的过程称为“宏展开”。
微软Word和宏病毒
Visual Basic for Applications (VBA),是 Microsoft Office 里的一种编程语言. 但由上面的定义,它完全不是一种宏语言。然而,它的功能已经从中发展并最终替代了用户应用程序的宏思想,所以他被广泛地错误地称为是一种宏语言。 VBA 可以访问许多操作系统函数并支持文档打开时自动执行宏。这使得用这种语言写计算机病毒成为可能。1990年代中后期,宏病毒成为了最流行的计算机病毒类型之一。其它的包括宏语言的项目,如openoffice.org,故意从其宏语言中排除了一些功能(如:自动执行)以避免破坏程序。然而,这一特性在很多事务中受到欢迎。
望采纳!!!
Ⅹ 德律风根opus studio 2650的音频输出是什么插头
最近项目中用到了语音编码opus,在网上搜了一下,资料非常少,而且没有一个完整的教程,现在简单记录下来opus的使用方法。
首先介绍一下opus
Opus
Opus编码器 是一个有损声音编码的格式,由互联网工程任务组(IETF)进来开发,适用于网络上的实时声音传输,标准格式为RFC 6716。Opus 格式是一个开放格式,使用上没有任何专利或限制。
特性
Opus的前身是celt编码器。在当今的有损音频格式争夺上,拥有众多不同编码器的AAC格式打败了同样颇有潜力的Musepack、Vorbis等格式,而在Opus格式诞生后,情况似乎不同了。通过诸多的对比测试,低码率下Opsu完胜曾经优势明显的HE AAC,中码率就已经可以媲敌码率高出30%左右的AAC格式,而高码率下更接近原始音频。
以上来自网络(PS:网络对opus的介绍都很少)
简单来说,opus是一个高保真的适合在网络中传输的开源的语音编码格式,相对于其他编码格式来讲,保真性更好,但体积会稍微大一些。官网地址:http://www.opus-codec.org/
怎么用呢?
首先你可以使用编译好的so库直接使用,或者也可以使用源码自己根据需求生成so库来使用,当然,你也可以直接将源码使用到自己工程各中,这就是开源的好处。好了下面介绍如何编译。
我是通过Eclipse来编译的,首先在opus官网下载源代码,解压。
编码工作需要ndk编程所以需要一些NDK编程的知识。
在工程中创建OpusTool类,该类用于调用native层的方法。
[java] view plain
package com.ione.opustool;
public class OpusTool {
public native String nativeGetString();
public native int encode_wav_file(String in_path, String out_path);
public native int decode_opus_file(String in_path, String out_path);
}
其中nativeGetString()方法是用来测试jni调用是否成功的测试方法,encode_wav_file(String in_path, String out_path);和 decode_opus_file(String in_path, String out_path);分别是用来编解码。以上三个方法均需声明为native,用来调用jni的c函数。然后在项目根目录下打开命令行,使用javah命令生成.h文件,即:
javah -classpath .\bin\classes -d jni com.ione.opustool.OpusTool
其中.\bin\classes为指定OpusTool.class的路径,-d jni为在当前目录下生成jni文件夹,用来存放native层代码。回车之后便在工程的根目录下生成了jni文件夹以及com_ione_opustool_OpusTool.h文件。如:
[cpp] view plain
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ione_opustool_OpusTool */
#ifndef _Included_com_ione_opustool_OpusTool
#define _Included_com_ione_opustool_OpusTool
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ione_opustool_OpusTool
* Method: nativeGetString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_ione_opustool_OpusTool_nativeGetString
(JNIEnv *, jobject);
/*
* Class: com_ione_opustool_OpusTool
* Method: encode_wav_file
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_encode_1wav_1file
(JNIEnv *, jobject, jstring, jstring);
/*
* Class: com_ione_opustool_OpusTool
* Method: decode_opus_file
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_decode_1opus_1file
(JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
接下来复制一份com_ione_opustool_OpusTool.h文件到jni目录,修改名称为com_ione_opustool_OpusTool.c修改内容为:
[cpp] view plain
#include <com_ione_opustool_OpusTool.h>
JNIEXPORT jstring JNICALL Java_com_ione_opustool_OpusTool_nativeGetString
JNIEnv * env, jobject obj) {
return (*env)->NewStringUTF(env, "Hello Opus");
}
JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_encode_1wav_1file(
JNIEnv *env, jobject obj, jstring wav_path, jstring opus_path) {
return 0;
}
JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_decode_1opus_1file(
JNIEnv *env, jobject obj, jstring wav_path, jstring opus_path) {
return 0;
}
然后创建并配置makefile和android.mk文件,后面会给出。记得配置NDK_Builder。
此时可以调用OpusTool类的nativeGetString()方法查看返回数据是否正常,若为Hello Opus 则jni调用成功。可以继续下面的工作。
在jni目录下创建libopus文件夹,将Opus源码粘贴到该文件夹下,即celt、include、silk、src文件夹以及config文件,当然不是所有的文件都用的上,可以根据自记得需求进行拷贝。配置好makefile等配置文件后即可编译工程,如果编译顺利,则说明配置文件没有问题,继续操作。在src文件加下创建opus_tool.c文件用来进行音频文件的编解码的c实现。
opus_tool.c
[cpp] view plain
/*****************************************************************************
# -*- coding:utf-8 -*-
# author: ione
# create date: 2014-11-27
*****************************************************************************/
#include "android_log.h"
#include "opus.h"
#include "opus_types.h"
#include "opus_multistream.h"
#define SAMPLE_RATE 16000
#define CHANNEL_NUM 1
#define BIT_RATE 16000
#define BIT_PER_SAMPLE 16
#define WB_FRAME_SIZE 320
#define DATA_SIZE 1024 * 1024 * 4
int encode(char* in, int len, unsigned char* opus, int* opus_len) {
int err = 0;
opus_int32 skip = 0;
OpusEncoder *enc = opus_encoder_create(SAMPLE_RATE, CHANNEL_NUM,
OPUS_APPLICATION_VOIP, &err);
if (err != OPUS_OK) {
fprintf(stderr, "cannnot create opus encoder: %s\n",
opus_strerror(err));
enc = NULL;
return -1;
}
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
opus_encoder_ctl(enc, OPUS_SET_BITRATE(BIT_RATE));
opus_encoder_ctl(enc, OPUS_SET_VBR(1));
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO));
opus_encoder_ctl(enc, OPUS_SET_DTX(0));
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0));
opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
short frame_size = WB_FRAME_SIZE;
int frame_bytes = (frame_size << 1);
opus_int16 *frame = (opus_int16 *) in;
unsigned char *cbits = opus;
while (len > frame_bytes) {
int nbytes = opus_encode(enc, frame, frame_size, cbits + sizeof(char),
640 - sizeof(short));
if (nbytes > frame_size * 2 || nbytes < 0) {
return -1;
}
cbits[0] = nbytes;
frame += WB_FRAME_SIZE;
cbits += nbytes + sizeof(char);
len -= frame_bytes;
*opus_len += nbytes + sizeof(char);
}
opus_encoder_destroy(enc);
return 0;
}
int decode(unsigned char* in, int len, short* out, int* out_len) {
int err = 0;
opus_int32 skip = 0;
*out_len = 0;
OpusDecoder *dec = opus_decoder_create(SAMPLE_RATE, 1, &err);
if (err != OPUS_OK) {
fprintf(stderr, "cannnot decode opus: %s\n", opus_strerror(err));
dec = NULL;
return -1;
}
short frame_size = WB_FRAME_SIZE;
opus_int16 *frame = (opus_int16 *) in;
while (len > 0) {
int nbytes = in[0];
if (nbytes <= 0) {
return -1;
}
int decode_len = opus_decode(dec, in + sizeof(char), nbytes, out,
frame_size, 0);
if (decode_len != frame_size) {
return -1;
}
in += sizeof(char) + nbytes;
out += frame_size;
len -= nbytes - sizeof(char);
*out_len += frame_size;
}
opus_decoder_destroy(dec);
return 0;
}
int encode_wav_file(char *in_file_path, char *out_file_path) {
FILE *fin = fopen(in_file_path, "rb");
if (fin == NULL || fin == 0) {
return -1;
}
char *in = (char*) malloc(DATA_SIZE);
memset(in, 0, DATA_SIZE);
int len = fread(in, 1, DATA_SIZE, fin);
if (len == 0) {
return -1;
}
FILE *fout = fopen(out_file_path, "wb");
if (fout == NULL || fout == 0) {
return -1;
}
unsigned char *out = (unsigned char*) malloc(DATA_SIZE);
memset(out, 0, DATA_SIZE);
int out_len = 0;
encode(in, len, out, &out_len);
if (len < 0) {
return -1;
}
fwrite(out, 1, out_len * sizeof(unsigned char), fout);
free(in);
free(out);
fclose(fin);
fclose(fout);
return len;
}
int make_wav_header(FILE *out, int len) {
int size = 0;
int *sz = &size;
int number;
int * nm = &number;
// RIFF 4 bytes
fseek(out, 0, SEEK_SET);
fputs("RIFF", out);
// len 4 bytes
len = (len + 44 - 8);
fwrite(&len, 2, 1, out);
number = 0;
fwrite(nm, 2, 1, out);
// WAVE 4 bytes + "fmt " 4 bytes
fputs("WAVEfmt ", out);
// size1 4 bytes
number = 16;
fwrite(nm, 2, 1, out);
number = 0;
fwrite(nm, 2, 1, out);
// format tag 2 bytes
number = 1;
fwrite(nm, 2, 1, out);
// channel 2 bytes
number = CHANNEL_NUM;
fwrite(nm, 2, 1, out);
// sample rate 4 bytes
number = SAMPLE_RATE;
fwrite(nm, 2, 1, out);
number = 0;
fwrite(nm, 2, 1, out);
//byte per seconds 4 bytes
number = 22664;
fwrite(nm, 2, 1, out);
number = 0;
fwrite(nm, 2, 1, out);
// block align 2 bytes
number = CHANNEL_NUM * BIT_PER_SAMPLE / 8;
fwrite(nm, 2, 1, out);
// bitPerSample 2 bytes
number = 16;
fwrite(nm, 2, 1, out);
// "data" 4 bytes
fputs("data", out);
// size2 4 bytes
size = (size - 36);
fwrite(sz, 2, 1, out);
number = 0;
fwrite(nm, 2, 1, out);
return 0;
}
int decode_opus_file(char *in_file_path, char *out_file_path) {
printf("%s\n", in_file_path);
FILE *fin = fopen(in_file_path, "rb");
if (fin == NULL || fin == 0) {
return -1;
}
unsigned char *in = (unsigned char *) malloc(DATA_SIZE);
memset(in, 0, DATA_SIZE);
int len = fread(in, 1, DATA_SIZE, fin);
FILE *fout = fopen(out_file_path, "wb");
if (fout == NULL || fout == 0) {
return -1;
}
short *out = (short *) malloc(DATA_SIZE);
memset(out, 0, DATA_SIZE);
int out_len = 0;
out += 44;
decode(in, len, (short *) out, &out_len);
if (len < 0) {
return -1;
}
fwrite(out, 1, out_len * sizeof(short), fout);
int err = make_wav_header(fout, out_len);
free(in);
free(out);
fclose(fin);
fclose(fout);
return out_len;
}
配置makefile文件添加opus_tool.c文件,然后编译,即可在libs目录下生成.so文件