C语言和FORTRAN语言
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
快速 的动 作。 而 FORTRAN 从一 开始 就用 于科 学计 算, 它与 C 的差 异主 要表 现为 :
* 复数运算的速度
* 程序参数与字串
* 内存的动态管理
* 多维阵列的处理
* 函数调用与参数传递
2.1. 复 数运 算 的速 度
在 进 行 复 数 运 算 的 时 候 ,C++ 可 以 定 义 复 数 的 class,还 可 以 重 新 定 义 所 有 的 四 则 运 算 式 ,复 杂 的 算 式 也 可 以 做 到 由 一 个 表 达 式 来 解 决 。但 它 的 重 新 定 义 复 数 四 则 运 算 是 用 函 数 来 做 的 , 使 用 函 数 来 调 用 其 速 度 很 慢 , 除 非 采 用 inline function 的 方 式 , 但 会 遇 到 以 下 的 问 题 : 要 先 将 这 个 算 式 拆 解 , 分 别 算过 后再 重组 结果 ,故 表面 上程 序代 码很 简洁 ,但 实际 上是 compiler 做了 很多 工作 ,还 是要 付出 相当 的计 算时 间代 价的 。
b = atoi(argv[2]); c = atoi(argv[3]); }
而 程 序 执 行 时 , 参 数 就 是 这 样 传 入 : a.out 12 15 18
Fortran 却没 有办 法 ,要 传入 任何 参数 ,只 能透 过对 话的 方式 :
integer a, b, c c -----------------------------------write(*,*) ''please input integer a:'' read(*,*) a write(*,*) ''please input integer b:'' read(*,*) b write(*,*) ''please input integer c:'' read(*,*) c c -----------------------------------end
至 于 Fortran,最 大 的 优 点 在 于 复 数 (complex number) 的 运 算 ,复 数 是 Fortran 的 基 本 数 据 类 型 之 一 ,这 正 是 C 所 缺 乏 的 (C 基 本 上 只 有 实 型 与 整 型 类 型 而 已 )。 虽 然 C 也 可 以 由 struct 的 定 义 , 达 到 复 数 四 则 运 算 的 目 的 , 但 却 很 可 能 牺 牲 了 程 序 效 能 , 或 者 是 程 序 写 起 来 相 当 繁 杂 降 低 可 读 性 。 因 此 , 在 大 量 而 且 要 求 高 速 的 复 数 运 算 场 合 , Fortran 实 际 上 比 C 还 要 适 合 。
2. C 语 言 和 Fortran 语 言 的 差 异
由于两者产生的背景不同,它们是存在差异的,在比较了几组源代码之后,主要有以下体会: C 最 大 的 优 点 在 于 灵 活 ,不 但 可 以 藉 由 struct 来 定 义 新 的 数 据 结 构 ,同 时 C 的 pointer 更 可 以 让 我 们 自 由 而 且 有 效 率 地 处 理 大 数 据 。而 在 UNIX 系 统 中,由于整个操作系统绝大部分就是 C 写出来的,故我们也有方便的 C 函数库, 直接使用系统资源与享受系统带来的服务,以做到一些低阶、
2.3. 内 存的 动 态管 理
C 可以 动态 分配 存储 空间 给任 何数 据类 型, 而 Fortran 却不 行。
例如:
float *c_function(int cnt) { float *a; a = malloc(sizeof(float) * cnt); /* * 操作 array a. */ return a; }
因 此 , 如 果 我 们 要 在 Fortran 中 配 置 一 个 与 上 头 那 个 C 一 模 一 样 的 二 维 阵 列 时 , 实 际 上 应 该 要 将 其 index 反 过 来 : double precision a(10,12)
除 此 之 外 , C 的 阵 列 index 一 律 是 从 0 开 始 ,对 于 一 个 有 N 个 元 素 的 阵 列 ,其 最 后 一 个 index 是 N-1 ,且 每 个 阵 列 元 素 的 index 值 差 1。 Fortran 不一定,要看怎么声明了。例如声明一个阵列如下:
real(a) =……; imag(a) = …….
如此只需两步就得到结果。直到遇到太长太复杂的算式,才去做拆解的动作。
这样使用 C 来做复数运算可能需要绕圈圈,而且绕出来的圈圈可能还不小。不过如果程序中需要复合的数据结构,如一个自定义的数据结构中既有浮 点数 、整 数、 还有 字符 串时 , Fortran 只有 举白 旗投 降了 。当 然, Fortran 如果 要做 还是 可以 做, 只是 不太 方便 ,而 且可 能也 需要 绕圈 圈。 但如 果使 用 Fortran 90 则 不 成 问 题 了 , 因 为 Fortran 90 也 有 类 似 C 的 struct 结 构 以 定 义 复 合 的 数 据 类 型 。
C 语 言 和 Fortran 语 言 作者: 解放军信息工程大学理学院学员旅一队 温睿
目录 第 1 章 . C++语 言 和 Fortran 语 言 的 发 展 背 景 第 2 章 . C 语 言 和 Fortran 语 言 的 差 异 2.1. 复数 运算 的速 度 . 2.2. 程序 参数 与字 串 . 2.3. 内存 的动 态管 理 . 2.4. 多维 阵列 的处 理 . 2.5. 函数 调用 与参 数传 递 .
2.2. 程 序参 数 与字 串
C 程序 可以 有参 数串 列, Fortran 则没 有。 例如 ,当 程序 执 行时 ,必 须输 入 a, b, c 三个参数,在 C 可以这样写:
int main(int argc, char **argv) { int a, b, c; a = atoi(argv[1]);
所以 它实 际上 是一 块 12*10*sizeof(double) bytes 的连 续存 储区 块, 而经 由以 上的 声明 , compiler 便知 道当 使用 到它 时, 要将 分割 成每 单位 元素 为 sizeof(double),每 10 个 单 位 一 组 ,而 总 共 12 组 的 一 个 二 维 阵 列 ,则 当 我 们 使 用 阵 列 的 index 来 存 取 阵 列 元 素 时 , compiler 也 会 自 动 算 好 该 元 素 阵列在此存储区块的位置,因此就能很方便地使用。
double precision a(100)
则 此 阵 列 index 是 从 1 开 始 , 最 后 一 个 是 100, 每 个 的 值 差 1。 不 仅 如 此 , Fortran 还 可 以 这 样 声 明 :
double precision a(11:110)
这 还 是 一 个 一 维 阵 列 , 共 100 个 元 素 ,但 第 一 个 元 素 的 index 是 11, 最 后 一 个 是 110 。在 这 里 我 们 可 以 看 到 , (idx1:idx2) 这 样 的 叙 述 在 Fortran 中就是用来指定一个阵列的范围。
Fortran 也是 如此 ,但 有一 个很 大的 不同 ,它 的存 储区 块分 割配 置的 方式 是与 C 反向 的。 例如 声明 一个 二维 阵列 如下 :
double precision a(12,10)
则它在存储空间中的配置为:
|<--- 12 ---><--- 12 ---> ...Hale Waihona Puke Baidu <--- 12 --->| |<<--------------- 共 10 组 -------------->>|
而且 如果 在程 序执 行过 程中 ,如 果不 再需 要这 个 array a 了, 还可 以随 时释 放 a 所占 用的 存储 空间 。而 Fortran 在一 般情 况下 是不 行的 ,因 此在 一般 的 Fortran 程 序 中 , 常 见 所 有 需 要 用 的 array, 都 是 在 MAIN__里 头 就 配 置 好 记 存 储 空 间 , 再 一 个 个 传 入 subroutine 里 头 来 用 , 例 如 :
program fout c ----------------------------
integer cnt parameter (cnt^P00) real a(cnt) call f_routine(cnt, a) end c ---------------------------subroutine f_routine(cnt, a) c ---------------------------integer cnt real a(cnt) c c 操作 array a. c end
然 而 既 然 复 数 已 是 Fortran 基 本 数 据 类 型 之 一 , 则 Fortran compiler 在 设 计 上 可 以 做 到 对 复 数 特 别 的 optimization, 例 如 如 果 遇 到 较 短 的 复 数 运 算 式 , 它 可 以 用 “心 算 ” 直 接 得 出 real_part 与 imag_part 的 expression, 像 这 样 :
这里 的 parameter 是设 定变 数的 固定 值, 其作 用就 相当 于 C 的 const 一样 ,经 设定 后的 参数 就是 一个 无法 改变 其值 的常 数了 。有 的时 候, 在某 个函 数 中 我 们 临 时 需 要 一 个 暂 存 阵 列 ,但 等 到 计 算 完 成 离 开 函 数 后 ,该 阵 列 就 没 有 用 了 ,这 在 C 可 以 做 的 很 划 算 ,即 进 入 函 数 时 malloc() 一 个 阵 列 ,离 开 前 再 free() 掉 它 。 但 在 Fortran 中 却 别 无 选 择 , 一 定 要 在 MAIN__ 里 头 先 将 暂 存 阵 列 配 置 好 , 再 一 起 传 入 subroutine 中 。
1. C++语 言 和 Fortran 语 言 的 发 展 背 景
在 程 序 设 计 语 言 的 发 展 过 程 中 ,FORTRAN 语 言 被 认 为 是 科 学 计 算 的 专 用 语 言 。后 来 推 出 的 FORTRAN90 和 FORTRAN 95 版 本 也 不 例 外 ,它 们 虽 然 可 以 完 全 实 现 C++语 言 同 样 的 功 能 , 然 而 其 软 件 开 发 环 境 和 软 件 的 集 成 性 等 方 面 都 远 不 如 C++ 语 言 。 近 年 来 , 随 着 计 算 机 软 硬 件 技 术 的 发 展 , 数 据 结 构 、 数据库管理技术、可视化与计算机图形学、用户接口系统集成以及人工智能等领域的成果被逐渐应用到结构分析软件中,结构分析软件的设计并不仅仅 局 限 于 单 一 的 科 学 计 算 需 要 涉 及 众 多 的 软 件 开 发 领 域 。 C++ 语 言 可 以 提 供 这 类 软 件 开 发 所 需 的 功 能 , 而 用 FORTRAN 90 却 很 难 实 现 , 另 一 方 面 从 软 件 的 编 程 环 境 来 看 , 目 前 FORTRAN 90 的 编 译 器 极 少 , 而 C++ 语 言 的 编 译 系 统 相 当 普 及 , 可 以 运 行 在 各 种 机 型 上 , 便 于 实 现 跨 平 台 的 软 件 系 统 集 成 。
2.4. 多 维阵 列 的处 理
不论 是在 C 或 Fortran, 所谓 的多 维阵 列实 际上 只是 一个 很长 的一 维连 续存 储空 间, 经过 分割 后当 做多 维阵 列使 用。 例如 ,一 个 C 的二 维阵 列声 明 如下:
double a[12][10];
则它在存储空间中的配置为:
|<--- 10 ---><--- 10 ---> .... <--- 10 --->| |<<-------------- 共 12 组 --------------->>|