C语言和Fortran语言
- 格式:doc
- 大小:60.50 KB
- 文档页数:7
程序设计语言发展史程序设计语言是计算机科学的核心领域之一,已经发生了很多变化和发展。
它是计算机程序员用来编写和运行计算机程序的工具,它在计算机科学的发展历程中扮演了非常重要的角色。
本文将为您介绍程序设计语言发展的历史、特点以及未来发展趋势等方面的内容。
程序设计语言的早期历史计算机程序设计语言的历史可以追溯到20世纪50年代初的Fortran(Formula Translation)语言。
Fortran是一种针对科学和工程计算而设计的高级语言,它使得程序员能够更简单地编写复杂的计算程序。
随着计算机技术的进步,计算机的应用领域不断扩大,越来越多的人开始学习和使用Fortran语言。
在Fortran之后不久,C语言开始出现在计算机程序设计语言的舞台上。
C语言是由Dennis Ritchie和Ken Thompson在贝尔实验室中设计的一种通用高级语言,具有高效的编译器、可移植性和易于学习的特点,很快就被广泛应用于操作系统、编译器和其他系统软件等方面。
C语言的出现标志着程序设计语言向更加灵活和可移植的方向发展。
1980年代是程序设计语言的重要时期1980年代是计算机技术迅速发展的时期,也是程序设计语言历史上的一个重要时期。
在这个时期,出现了许多新的编程语言,如Pascal、Ada、C++、Objective-C等语言。
Pascal是由Niklaus Wirth在20世纪70年代后期设计的一种结构化编程语言。
它被广泛地应用于当时的教育和科学计算领域,因为它可读性强、容易学习,所以被广泛地作为计算机课程的编程语言。
Ada技术也是80年代发展起来的。
它是由美国国防部为了促进软件标准化而制定的一种高级语言。
Ada语言被设计成一个通用的高级语言,在航空、武器系统等领域得到了广泛的应用。
Ada语言的特点是可靠、安全和可维护性高,这也是这种语言能够获得广泛应用的原因之一。
C++是对C语言的一种扩展。
它是在20世纪80年代初由Bjarne Stroustrup发明的。
用于科学和工程计算的主要语言
于科学和工程计算的主要语言包括:
1、C语言:C语言是一种通用的、高级的编程语言,广泛
应用于科学和工程计算中。
C语言具有较高的运行效率,可以满足科学和工程计算中对计算速度要求较高的场合。
2、Python:Python是一种解释型的编程语言,具有较简
单的语法和丰富的第三方库,广泛应用于科学和工程计算中。
Python提供了大量的数据分析工具和可视化库,可以方便地
进行数据分析和可视化。
3、Matlab:Matlab是一种专门用于科学和工程计算的编程语言和环境。
Matlab提供了大量的数学函数和工具,可以
方便地进行数学建模和计算。
4、R语言:R语言是一种专门用于统计分析和数据可视化的编程语言。
R语言提供了大量的统计分析函数和可视化工具,可以方便地进行数据分析。
在科学和工程计算中,除了上述几种常用的编程语言,还
有其他一些较少使用的语言。
例如:
1、Fortran:Fortran是一种专门用于科学计算的编程语言,拥有比较优秀的数值计算能力。
Fortran在科学和工程计算中有着悠久的历史,但随着其他语言的发展,Fortran在科
学和工程计算中的应用范围较小。
2、Lisp:Lisp是一种通用的编程语言,有着较简单的语法和较强的递归能力。
c语言调用fortran module中函数在C语言中调用Fortran模块中的函数,需要使用特定的接口和约定。
下面是一个简单的示例,展示如何在C语言中调用Fortran 模块中的函数:1、首先,创建一个Fortran模块文件,例如module_example.f90,其中包含要调用的函数:module module_exampleimplicit noneinteger, parameter :: dp = kind(1.0d0)containssubroutine example_subroutine(a, b, c)implicit nonereal(dp), intent(in) :: a, breal(dp), intent(out) :: cc = a + bend subroutine example_subroutineend module module_example2、接下来,创建一个C语言源文件,例如main.c,用于调用Fortran模块中的函数:#include <stdio.h>#include "module_example.h" // 包含Fortran模块的头文件int main() {double a = 2.0, b = 3.0;double c;example_subroutine(a, b, c); // 调用Fortran模块中的函数printf("c = %f\n", c); // 输出结果return 0;}然后,编译生成可执行文件。
在命令行中,使用gfortran编译器将Fortran模块和C语言源文件一起编译:gfortran -c module_example.f90 -o module_example.o # 编译Fortran模块文件gcc main.c module_example.o -o main # 编译C语言源文件和链接Fortran模块文件最后,运行生成的可执行文件:./main # 运行可执行文件并查看输出结果输出结果应为:c = 5.000000。
程式语言的发展过程
程式语言的发展过程可以追溯到上个世纪50年代。
当时,计算机正处于快速发展的阶段,人们意识到需要一种能够方便地与计算机交流的方式。
于是,第一种程式语言Fortran应运而生。
Fortran的出现使得科学家和工程师能够更加便捷地使用计算机进行数值计算。
随着计算机的不断发展,更多的程式语言被发明出来,如COBOL、BASIC等。
这些程式语言为计算机编程提供了更多的选择。
然而,这些程式语言存在着一些缺点,比如可读性差、运行效率低等。
在20世纪70年代后期,C语言应运而生,它在计算机编程领域占据了重要地位。
C语言的出现使得计算机编程更加高效、简洁、易读。
随着互联网的出现,计算机编程的需求也随之增加。
为此,Java、Python等新的程式语言应运而生。
这些新的程式语言具有更加灵活的语法结构、更高效的运行速度和更简单易学的特点。
总的来说,程式语言的发展过程体现了人们对于计算机编程的不断追求和创新,同时也反映了科技的不断进步和变革。
- 1 -。
C 、C ++、Fortran 混合编程研究魏 威,魏 冲(郑州铁路职业技术学院,河南郑州450052)摘 要:不同计算机编程语言都有其特有的优势和局限性,将多种语言混合起来进行编程,不但可以充分发挥各自的优势,而且可以弥补各自功能的不足,这样既能充分利用现有程序资源,又能加快应用程序的开发.主要阐述了C 、C ++、Fortran 等3种语言在不同平台下混合编程应注意的问题,以及在混合编程中经常遇到的2个问题.关键词:混合编程;C;C ++;Fortran中图分类号:TP311 文献标识码:A 文章编号:1007-113X (2007)04-0094-05Fortran 语言是所有编程语言中惟一能将复数定义为一种标准数据类型的语言,其优势在于数值计算,但是Fortran 语言在可视化程序设计方面却是非常欠缺的,目前还没有一家厂商推出具有RAD 特性的Fortran 编译集成开发环境.当用Fortran 实现了某一大型科学计算以后,却难以将这种计算转变为数据输入简易、结果显示方便的W indows 可视化应用程序,而采用C 、C ++进行编程却比较容易实现这些功能.因此,在许多情况下,我们应该使用C 、C ++、Fortran 等进行混合编程.在混合语言编程中,主要的问题是函数调用和数据结构的存储.1 W indows 平台的混合编程Fortran 语言没有大小写之分,而W indows 平台下的混合语言编程过程中大小写问题十分突出.考虑到编译器的差异,可以用以下方式进行跨平台编程的函数声明.C 、C ++编译器使用M icr os oft V isual C ++6.0编译集成开发环境,Fortran 编译器使用D igital V isual Fortran 6.0编译集成开发环境.假设一个C 语言函数为void cFuncti on (),那么只需要在它的头文件里面进行如下定义即可. #ifdef _cp lus p lus extern “C ”v oid { #endif extern v oid _stdcall CFuncti on (); #define cFuncti on CF UNCTI O N #ifdef _cp lus p lus } #endif这样就可实现上述函数在Fortran 或C ++程序中的直接调用.假设一个Fortran 函数为S UBROUTI N E FF UNCTI O N (),那么在C ++头文件里可进行如下定义. #ifdef _cp lus p lus extern “C ”v oid { #endif extern v oid _stdcall ffuncti on (); #define ffuncti on FF UNCTI O N #ifdef _cp lus p lus第22卷第4期2007年12月 洛阳大学学报JOURNAL OF LUOY ANG UN I V ERSI TY Vol .22No .4Dec .20073收稿日期:2007-11-01作者简介:魏 威(1960-),女,汉族,河南省郑州市人,工程师,研究方向:计算机技术. } #endif这样,就可以在C ++的程序里面直接调用上述函数.由于C 编译器里面没有定义cp lus p lus 这个环境变量,因此在C 文件里面也可以直接使用这个头文件.如果是一个C ++函数void cPlus p lusFuncti on (),和C 函数一样可定义如下. #ifdef _cp lus p lus extern “C ”v oid { #endif extern v oid _stdcall cPlus p lusFuncti on (); #define cPlus p lusFuncti on CP LUSP LUSF UNCTI O N #ifdef _cp lus p lus } #endif经过上面的定义后,所有的函数便可实现在3种语言间自由调用.在用3三种语言进行混合编程过程中要注意函数的参数、字符串的传递问题.对含有字符串的函数,如函数v oid cCharFuncti on (char 3m sg ),需要定义如下. void cCharFuncti on (char 3m sg,int len )经过上面的定义之后,在Fortran 中只需调用cCharFuncti on (m sg )即可.由于Fortran 程序没有明显的字符串结束标志,如果是2个字符串连在一起,C 程序里就只能得到1个字符串.所以,最好在C 的程序里对这个由Fortran 程序得到的字符串进行处理,因为从len 变量可以得到字符串长度,截取m sg 的前len 个字符作为这个字符串的应有长度.而在Fortran 程序里面,如函数S UBROUTI N E FCHARF UNCTI O N (fchar ),经过相应声明,进行下面的定义即可. #define f CharFuncti on (fchar ),FCHARF UNCTI O N (fchar,strlen (fchar ))这样,在C 、C ++程序里即可直接调用.在3种语言的混合编程里还有一个需要注意的问题就是指针问题.Fortran 里面所有的变量都相当于C 、C ++里面的指针,所以,在C 、C ++程序里函数的参数应一律声明为指针形式(除字符串参数后面的长度外).在混合编程过程中,数据方面存在的差异也必须引起足够的重视,这体现在数组和结构2个方面.在Fortran 语言里,数组和C 、C ++里的数组有些不同,这表现在行列顺序和数组起始值.Fortran 语言不同于C 、C ++的行优先,而使用列优先的方式.假设有一个数组a,m 行n 列,采用行优先时的数据存放格式如下. a 11,a 12,…,a 1n ,a 21,a 22,…,a 2n ,…,a m 1,a m 2,…,a m n而采用列优先的数据存放格式如下. a 11,a 21,…,a m 1,a 12,a 22,…,a m 2,…,a 1n ,a 2n ,…,a m n行优先顺序推广到多维数组,规定为先排最右的下标;列优先顺序推广到多维数组,规定为先排最左的下标.这样,在混合语言编程里调用数据时必须注意行列优先的差别,进行准确地调用.数组的另一个差别是起始下标的不同.Fortran 默认的数组下标是以1开始的,而C 、C ++默认的数组下标却是从0开始的,所以在调用时要注意加1或者减1,以保证调用到正确的数据.Fortran 语言里的结构经过声明后就被分配了空间,在C 、C ++里面也要声明它,采用下面的方式.Fortran 结构声明格式如下. COMMON /COLOR7/C_RE D ,C_GREEN,C_BLUE COMMON /NDDAT/N I D (NASI ZE ),XN (3,NASI ZE )C 、C ++结构声明格式如下. #ifdef _cp lus p lus extern "C"{・59・第4期 魏 威等:C 、C ++、Fortran 混合编程研究 #endif #define col or7COLOR7 #define nddat NDDAT extern struct {fl oat c_red;fl oat c_green;fl oat c_blue;}col or7; extern struct {int nid[NASI ZE ];fl oat xn[NASI ZE ][3];}nddat; #ifdef _cp lus p lus } #endif2 L inux 平台的混合编程L inux 平台的混合语言编程和W indows 平台的混合语言编程基本没有什么区别,主要是在define 上的不同.考虑到编译器的差异,在函数声明上可以用下面的方式进行跨平台编程的函数声明.C 、C ++编译器使用G NU gcc,Fortran 编译器使用pgi Fortran .假设一个C 函数为void cFuncti on (),那么只需要在它的头文件里面进行如下定义即可. #ifdef _cp lus p lus extern “C ”v oid { #endif extern v oid CFuncti on (); #define cFuncti on cfuncti on_ #ifdef _cp lus p lus } #endif这样,在Fortran 或者C ++的程序里面就可以直接进行调用了.需要注意的是,函数名应该不多于31个字符.同样,对于C ++和Fortran 里的函数,函数名在声明的时候也应改成小写加下划线即可.对于数组来说,具体变化和W indows 平台的处理方式是一致的,都是行列优先顺序不同的.而对于字符串来说,则不需要额外的注意,gcc 编译器会处理好这个问题,也就是说并不需要额外的改变.对于数据结构的定义,也要改成小写加下划线的方式.其中,Fortran 的数据结构定义方式如下. COMMON /COLOR7/C_RE D ,C_GREEN,C_BLUE COMMON /NDDAT/N I D (NASI ZE ),XN (3,NASI ZE )C 、C ++的数据结构定义方式如下. #ifdef _cp lus p lus extern "C"{ #endif #define col or7col or7_ #define nddat nddat_ extern struct {fl oat c_red;fl oat c_green;fl oat c_blue;}col or7; extern struct {int nid[NASI ZE ];fl oat xn[NASI ZE ][3];}nddat; #ifdef _cp lus p lus } #endif3 其他平台的混合编程对于Solaris 平台,基本上和L inux 平台完全一致,但是考虑到Solaris 大多运行在Sparc CP U 上,它是采用big endian 的,而W indows 和L inux 运行在I ntel 或AMD 的X86平台上,采用的是little endian,这一点需要特别注意,在读写数据文件时应该给予足够的重视.其他的Unix 平台,如HP Unix 、ULTR I X 、I R I S 等,一般都只有define 上的微小差别,在字符串处理、结构及数组方面基本与L inux 相同.对它们・69・洛阳大学学报 2007来说,考虑更多的应该是中央处理器不同带来的差别.4 混合编程中的字符串处理混合编程中经常会出现需要传递字符串的情况,而字符串的传递是一个较为麻烦的问题.在Fortran 里,字符串是没有结束符的,但是有长度的概念,也就是说,编译器会给每一个字符串一个长度以控制字符串的长度,但是这个长度参数在不同的平台下其位置也是不同的(有的直接跟在字符串后面,有的则跟在函数参数的最后面),对于常见的平台,如W indows 、L inux 、Solaris 、HP Unix 、I R I S,可以用如下方法定义.以C 函数为例,定义如下. void messag (char 3m sg1,int 3where1,char 3m sg2,int 3where2) { p rintf (“……%s should be %d,while %s should be %d \n ”,m sg1,3where1,m sg2,where2); }如果要在Fortran 里调用的话,需要以下定义. #if defined ULT R I X ||SP ARC ||I R I S ||L I N UX ||W I N 32 #if defined ULT R I X ||SP ARC ||I R I S ||L I N UX extern v oid _stdcall messag (char 3,int 3,char 3,int 3,int,int ) #define messag (s1,i1,s2,i2)messag_(s1,i1,s2,i2,strlen (s1),strlen (s2)) #else /3W I N 32Platf or m 3/ extern v oid _stdcall messag (char 3,int,int 3,char 3,int,int 3) #define messag (s1,i1,s2,i2)MESS AGE (s1,strlen (s1),i1,s2,strlen (s2),i2) #endif #else /3O ther Platf or m 3/ extern v oid _stdcall messag (char 3,int 3,char 3,int 3,int,int ) #define messag (s1,i1,s2,i2)messag (s1,i1,s2,i2,strlen (s1),strlen (s2)) #endif如果要用在C ++中,需要如下定义. #ifdef _cp lus p lus extern “C ”{ #endif /3your extern code 3/ #ifdef _cp lus p lus } #endifFortran 里便可以直接调用如下. CALL MESS AG (char1,i1,char2,i2)同样,在Fortran 里写的字符串处理函数使用以上的define 和extern 后,也可以在C 里直接调用.5 混合编程中的文件读写处理文件读写也是混合编程中一个非常重要的问题,通常的问题发生于不同平台下的混合编程或者不同Fortran 编译器间的编译.在Fortran 中,文件的写入是由write 语句完成的,而每一个write 语句可一次性写入多个数据构成一个数据块,而每一个无格式数据块都由下面3部分组成:(1)数据块的开始标志,记录所有数据所占的字节数;(2)组成该数据块的各数据内容.整型数和浮点数均占4个字节,低字节在前,高字节在后.各数据间不空格;(3)每个数据块的结束标志,也为该数据块的字节数,而不是以回车换行符作为结束标志.各记录之间也没有分隔符.另外,由于编程语言的差异,不同的编译器的存储格式也存在差异,如V isual Fortran 与D igital Fortran 在存储数据块中还存在着差别.在一个write 语句中,V isual Fortran 存储数据块的开始标志与结束标志是・79・第4期 魏 威等:C 、C ++、Fortran 混合编程研究 用一个字节表示,而在D igital Fortran 是用一个整形数,即4个字节来表示.也就是说,V isual Fortran 一个数据块最多可以存储128个字节,如果一个write 语句要求写入的数据量大于128字节时,则按循环形式存入.所以,D igital Fortran 在读取时就应该把它转化为相应的D igital Fortran 存储形式.6 结束语混合编程的优势在于它允许调用用另一种语言编写的现有程序代码、使用在特定语言环境下难以实现的算法和获得处理速度方面的优势.在混合编程中的关键问题是协调2种或多种语言间所的调用约定、命名约定及参数传递方式,并使它们在数据结构、数据类型上保持一致.参考文献:[1]孙 鑫,余安萍.V isual C ++深入详解[M ].北京:电子工业出版社,2006.[2]埃克尔.C ++编程思想[M ].北京:机械工业出版社,2002.[3]任 哲.MFC W indows 应用程序设计[M ].北京:清华大学出版社,2004.[4]周振红.Fortran 90/95高级程序设计[M ].郑州:黄河水利出版社,2006.[5]周振红.I ntel V isual Fortran 应用程序开发[M ].郑州:黄河水利出版社,2006.[6]浩强工作组.Fortran 经典程序设计[M ].大连:大连理工大学出版社,2004.[7]霍 顿.V isual C ++2005入门经典[M ].北京:清华大学出版社,2007.[8]Stanley B,L i ppman .Essential C ++[M ].武汉:华中科技大学出版社,2001.Study on M i xed 2l anguage Co m p ili n g Usi n g C,C ++and FortranW E IW ei,W E I Chong(Zhengzhou Rail w ay Vocati onal and Technical College,Zhengzhou 450052,China )ABSTRACT:There are different peculiar advantage and li m itati on in each kind of p r ogra mm ing language .The m ixing p r ogra mm ing can make the best of merits of different languages and avoid the deficiencies of the m.This paper mainly discuss the questi on of m ixing p r ogra mm ing using the C,C ++and Fortran .KEY WORDS:m ixing p r ogra mm ing;C;C ++;Fortran(责任编辑:王 晓)・89・洛阳大学学报 2007。
[转载]Fortran程序基本特点及不同版本之间的区别原⽂地址:Fortran程序基本特点及不同版本之间的区别作者:caodanping_7141、F77和F90的区别名称:F77固定格式(fixed format),程序代码扩展名:.f或.for,F90⾃由格式(free format),扩展名:.f90格式:F77每⾏前六个字符不写程序代码,可以空着或者1-5字符使⽤数字来标注⾏代码(⽤作格式化输⼊出等),7-72为程序代码编写区,73⾏后被忽略,超过的话可以续⾏,F90每⾏可132字符注释:F77以C,c或*开头的⾏被当成注释;F90以"!"引导注释,也可放在⾏尾续⾏:F77所续⾏的第六个字符是"0"以外的字符,通过⽤+表⽰,F90以&续⾏,放在该⾏末或下⾏初均可变量名:F77⽀持6个字符长,F90⽀持31个字符长常数:F90中PARAMETER可以做形容词,和变量声明同时写在⼀起Real, parameter :: pi=3.1415926关系运算符:F90: == /= > >= < <= (更接近标准的数学符号)F77: .EQ. .NE. .GT. .GE. .LT. .LE.逻辑运算符:.AND. .OR. .NOT. .EQV. .NEQV.变量声明赋值:(1)integer: kind=1,2,4(长整型)F90: integer(kind=2) aInteger(kind=4)::a=15(加上两个冒号可以在定义时就直接赋值)F77: integer*2 b or integer(2) c⽤DATA命令单独赋值(属于声明),data b,c /1, 2.0/Fortran规定变量名以字母IJKLMN六个字母开头的即认为是整型变量(I-N规则),其他字母开头的为实型变量(2)real:kind=4,8(双精度)/real* 8=double precision(1.23E3/1.23D3)F90:real(kind=4) a, F77:real*4 a or real(4) a(3)complex kind=4,8(双精度)F90: complex(kind=4) a a=(3.1,2.5)(4)character len为最⼤长度(26个字母,数字0-9,专⽤字符13个:空格'$()+-*/,=.:)F90: character(len=10) c c=”Hello”, F77: c=’Hello’(5)logical kind=4,2(最少只需要1即可)F90: logical(kind=4) a a=.true.(6)⾃定义类型type:类似于C中的structF90: type::person ……引⽤时变量和元素直接以%区隔,visual fortran可以⽤.来表⽰全局变量全局变量:F77采⽤command来声明全局变量,编译器只提供内存共享⽽不去检查数据类型,使⽤时需要注意定义的是否⼀主程序和主程序中致,⽽F90则提供了module(不是函数,⽤于封装程序模块),可以把全局变量都声明在module中,这样主程序和主程序中就不需要编写重复的程序代码来声明全局变量就不需要编写重复的程序代码来声明全局变量了,函数在需要使⽤时只需要⽤use来调⽤该module_name即可:module module_name...end module还可以把功能上相关的函数放在同⼀个module模块中,程序想要调⽤时use该module才能调⽤,这样⽐较符合模块化的概念,在该module中⽤contains引导函数即可。
Fortran语言的最大特性是接近数学公式的自然描述,在计算机里具有很高的执行效率。
易学,语法严谨。
可以直接对矩阵和复数进行运算,这一点类似matlab。
自诞生以来广泛地应用于数值计算领域,积累了大量高效而可靠的源程序。
很多专用的大型数值运算计算机针对Fortran做了优化。
广泛地应用于并行计算和高性能计算领域。
Fortran90,Fortran95,Fortran2003的相继推出使Fortran语言具备了现代高级编程语言的一些特性。
Fortran语言是一种极具发展潜力的语言,在全球范围内流行过程中,Fortran语言的标准化不断吸收现代化编程语言的新特性,并且在工程计算领域仍然占有重要地位。
不可否认,Fortran语言与目前流行的JAVA,C#等高级语言相比,它缺乏创造力。
但是,工科学生必须注意到,由于Fortran在工程计算领域长期处于统治地位,很多优秀的工程计算软件都是运用fortran语言编写,例如ANSYS,Marc,为了能够使用这些商业软件的高级功能,必须先学会fortran语言,才能编写应用程序接口。
在数值计算中,Fortran语言仍然不可替代。
Fortran90标准引入了数组计算等非常利于矩阵运算的功能。
在数组运算时,Fortran能够自动进行并行运算,这是很多编程语言不具备的。
运用fortran语言,你能够运用很多现成的函数软件包,所以非常便利。
(目前流行的Matlab的早期版本,主要就是为两个著名的Fortran函数包提供程序接口)Prolog(Programming in Logic的缩写)是一种逻辑编程语言。
它建立在逻辑学的理论基础之上,最初被运用于自然语言等研究领域。
现在它已广泛的应用在人工智能的研究中,它可以用来建造专家系统、自然语言理解、智能知识库等。
同时它对一些通常的应用程序的编写也很有帮助。
使用它能够比其他的语言更快速地开发程序,因为它的编程方法更象是使用逻辑的语言来描述程序。
C语言转换为fortran语言C/C++采用的是缺省调用约定是STDCALL约定.在C程序中,可以在函数原型的声明中使用_stdcall关键字来指明过程采用STDCALL调用约定。
Fortran过程采用的缺省标识符是,全部大写的过程名加上“_”前缀和“@n”后缀。
在C程序中保留标识符的大小写。
编译程序会给采用STDCALL约定的过程标识符加上“_”前缀和“@n”后缀。
Fortran过程缺省的参数传递方式是引用方式是。
对于下面这个Fortarn过程:SUBROUTINE ForSub(ivar,rvar)INTEGER ivarREAL rvarWRITE(*,*) ivar,rvarEND在C语言程序中应给出过程的函数原型及调用方式为:void main(){extern void__stdcall FORSUB(int*I,float*f);int iCV AR=1;float rCV AR=2.0;FORSUB(&iCV AR,&rCV AR);}在C++中调用Fortan的过程,在声明函数原型时需要用extern“C”语句,以避免C++编译程序对标识符的修饰;并且C++也可以通过引用方式传递参数。
对于上面的Fortran过程,C++程序应给出的函数原型及调用方法是:void main(){extern “C”{void__stdcall FORSUB(int*I,float*f);}int iCV AR=1;float rCV AR=2.0;FORSUB(&iCV AR,&rCV AR);}另外,也可以在Fortran中用!MS$ATTRIBUTES编译伪指令来改变Fortran子过程的调用约定,以便于被其他语言的程序调用。
在下面的例子中,过程ForSub具有C语言的调用约定。
SUBROUTINE ForSub(ivar,rvar)!MS$ATTRIBUTES C::ForSubINTEGER ivarREAL rvarWRITE(*,*) ivar,rvarEND这样,这个过程使用的是C调用约定,并且参数传递方式也变为传值方式,过程的标识符变为全部小写且有_前缀而无后缀的方式。
程序设计的发展历程程序设计的发展历程可以追溯到20世纪40年代。
在那个时候,计算机技术刚刚开始兴起,计算机的运作主要依靠硬件的控制,且程序设计还没有形成明确的概念。
随着计算机技术的发展,人们逐渐意识到需要一种高级语言来简化程序设计过程。
于是,在20世纪50年代末和60年代初,高级程序设计语言开始出现。
最早的高级语言是Fortran和Lisp。
Fortran主要用于科学计算,而Lisp则被用于人工智能领域。
在20世纪60年代末和70年代初,C语言和Pascal语言相继诞生。
C语言成为了一种通用的高级语言,广泛应用于软件开发。
同时,Pascal语言也主要用于教育和学术领域。
20世纪70年代,面向对象编程的概念开始被提出。
Smalltalk语言成为了第一种真正意义上的面向对象编程语言,它对程序设计产生了深远的影响。
20世纪80年代,C++语言问世,它是在C语言的基础上添加了面向对象编程的特性。
C++语言的出现推动了面向对象编程的普及。
随着计算机硬件的不断发展,计算机程序也逐渐变得越来越复杂。
为了应对这个问题,人们开始寻求一种更高级的程序设计方法。
在20世纪80年代末和90年代初,面向组件编程和面向服务编程概念相继提出。
这些概念强调将程序分解为可重用的模块或服务,以便提高开发效率和降低维护成本。
21世纪初,云计算和移动应用的兴起带来了全新的挑战和机遇。
为了适应这些变化,人们开始采用敏捷开发和DevOps等新的开发方法和流程。
随着人工智能和大数据技术的飞速发展,程序设计也面临着新的挑战和机遇。
人工智能技术开发出了一种新的编程范式,即机器学习和深度学习。
这种编程范式在解决复杂问题和进行模式识别方面具有巨大潜力。
总的来说,程序设计的发展历程是一个逐步演进的过程。
从最早的机器语言到高级语言,再到面向对象编程和组件化编程,以及如今的云计算和人工智能,每一个阶段都为程序员提供了更高效、更便捷的工具和方法。
未来,随着技术的不断进步,程序设计的发展将继续推动着计算机技术的进一步革新。
C语言和Fortran语言作者: 解放军信息工程大学理学院学员旅一队温睿目录第1章. C++语言和Fortran语言的发展背景第2章. C语言和Fortran语言的差异2.1. 复数运算的速度.2.2. 程序参数与字串.2.3. 内存的动态管理.2.4. 多维阵列的处理.2.5. 函数调用与参数传递.1. C++语言和Fortran语言的发展背景在程序设计语言的发展过程中,FORTRAN 语言被认为是科学计算的专用语言。
后来推出的FORTRAN90 和FORTRAN 95 版本也不例外,它们虽然可以完全实现C++语言同样的功能,然而其软件开发环境和软件的集成性等方面都远不如C++ 语言。
近年来,随着计算机软硬件技术的发展,数据结构、数据库管理技术、可视化与计算机图形学、用户接口系统集成以及人工智能等领域的成果被逐渐应用到结构分析软件中,结构分析软件的设计并不仅仅局限于单一的科学计算需要涉及众多的软件开发领域。
C++ 语言可以提供这类软件开发所需的功能,而用FORTRAN 90 却很难实现,另一方面从软件的编程环境来看,目前FORTRAN 90 的编译器极少,而C++ 语言的编译系统相当普及,可以运行在各种机型上,便于实现跨平台的软件系统集成。
2. C语言和Fortran语言的差异由于两者产生的背景不同,它们是存在差异的,在比较了几组源代码之后,主要有以下体会:C 最大的优点在于灵活,不但可以藉由struct 来定义新的数据结构,同时 C 的pointer 更可以让我们自由而且有效率地处理大数据。
而在UNIX 系统中,由于整个操作系统绝大部分就是 C 写出来的,故我们也有方便的 C 函数库,直接使用系统资源与享受系统带来的服务,以做到一些低阶、快速的动作。
而FORTRAN从一开始就用于科学计算,它与C的差异主要表现为:* 复数运算的速度* 程序参数与字串* 内存的动态管理* 多维阵列的处理* 函数调用与参数传递2.1. 复数运算的速度在进行复数运算的时候,C++ 可以定义复数的class,还可以重新定义所有的四则运算式,复杂的算式也可以做到由一个表达式来解决。
但它的重新定义复数四则运算是用函数来做的,使用函数来调用其速度很慢,除非采用inline function 的方式,但会遇到以下的问题:要先将这个算式拆解,分别算过后再重组结果,故表面上程序代码很简洁,但实际上是compiler做了很多工作,还是要付出相当的计算时间代价的。
至于Fortran,最大的优点在于复数(complex number) 的运算,复数是Fortran 的基本数据类型之一,这正是 C 所缺乏的(C 基本上只有实型与整型类型而已)。
虽然C 也可以由struct 的定义,达到复数四则运算的目的,但却很可能牺牲了程序效能,或者是程序写起来相当繁杂降低可读性。
因此,在大量而且要求高速的复数运算场合,Fortran 实际上比 C 还要适合。
然而既然复数已是Fortran 基本数据类型之一,则Fortran compiler在设计上可以做到对复数特别的optimization,例如如果遇到较短的复数运算式,它可以用“心算” 直接得出real_part 与imag_part 的expression,像这样:real(a) =……;imag(a) = …….如此只需两步就得到结果。
直到遇到太长太复杂的算式,才去做拆解的动作。
这样使用 C 来做复数运算可能需要绕圈圈,而且绕出来的圈圈可能还不小。
不过如果程序中需要复合的数据结构,如一个自定义的数据结构中既有浮点数、整数、还有字符串时,Fortran 只有举白旗投降了。
当然,Fortran 如果要做还是可以做,只是不太方便,而且可能也需要绕圈圈。
但如果使用Fortran 90 则不成问题了,因为Fortran 90 也有类似 C 的struct 结构以定义复合的数据类型。
2.2. 程序参数与字串C 程序可以有参数串列,Fortran 则没有。
例如,当程序执行时,必须输入a, b, c三个参数,在 C 可以这样写:int main(int argc, char **argv){int a, b, c;a = atoi(argv[1]);b = atoi(argv[2]);c = atoi(argv[3]);}而程序执行时,参数就是这样传入: a.out 12 15 18Fortran 却没有办法,要传入任何参数,只能透过对话的方式:integer a, b, cc ------------------------------------write(*,*) ''please input integer a:''read(*,*) awrite(*,*) ''please input integer b:''read(*,*) bwrite(*,*) ''please input integer c:''read(*,*) cc ------------------------------------end2.3. 内存的动态管理C 可以动态分配存储空间给任何数据类型,而Fortran 却不行。
例如:float *c_function(int cnt){float *a;a = malloc(sizeof(float) * cnt);/** 操作 array a.*/return a;}而且如果在程序执行过程中,如果不再需要这个array a 了,还可以随时释放a所占用的存储空间。
而Fortran 在一般情况下是不行的,因此在一般的Fortran 程序中,常见所有需要用的array, 都是在MAIN__里头就配置好记存储空间,再一个个传入subroutine 里头来用,例如:program foutc ----------------------------integer cntparameter (cnt^P00)real a(cnt)call f_routine(cnt, a)endc ----------------------------subroutine f_routine(cnt, a)c ----------------------------integer cntreal a(cnt)cc 操作 array a.cend这里的parameter 是设定变数的固定值,其作用就相当于 C 的const 一样,经设定后的参数就是一个无法改变其值的常数了。
有的时候,在某个函数中我们临时需要一个暂存阵列,但等到计算完成离开函数后,该阵列就没有用了,这在 C 可以做的很划算,即进入函数时malloc() 一个阵列,离开前再free() 掉它。
但在Fortran 中却别无选择,一定要在MAIN__ 里头先将暂存阵列配置好,再一起传入subroutine 中。
2.4. 多维阵列的处理不论是在 C 或Fortran,所谓的多维阵列实际上只是一个很长的一维连续存储空间,经过分割后当做多维阵列使用。
例如,一个 C 的二维阵列声明如下:double a[12][10];则它在存储空间中的配置为:|<--- 10 ---><--- 10 ---> .... <--- 10 --->||<<-------------- 共12 组--------------->>|所以它实际上是一块12*10*sizeof(double) bytes 的连续存储区块,而经由以上的声明,compiler 便知道当使用到它时,要将分割成每单位元素为sizeof(double),每10 个单位一组,而总共12 组的一个二维阵列,则当我们使用阵列的index 来存取阵列元素时,compiler 也会自动算好该元素阵列在此存储区块的位置,因此就能很方便地使用。
Fortran 也是如此,但有一个很大的不同,它的存储区块分割配置的方式是与 C 反向的。
例如声明一个二维阵列如下:double precision a(12,10)则它在存储空间中的配置为:|<--- 12 ---><--- 12 ---> .... <--- 12 --->||<<--------------- 共10 组-------------->>|因此,如果我们要在Fortran 中配置一个与上头那个 C 一模一样的二维阵列时,实际上应该要将其index 反过来:double precision a(10,12)除此之外,C 的阵列index 一律是从0 开始,对于一个有N 个元素的阵列,其最后一个index 是N-1,且每个阵列元素的index 值差1。
Fortran 不一定,要看怎么声明了。
例如声明一个阵列如下:double precision a(100)则此阵列index 是从 1 开始,最后一个是100, 每个的值差1。
不仅如此,Fortran 还可以这样声明:double precision a(11:110)这还是一个一维阵列,共100 个元素,但第一个元素的index 是11, 最后一个是110 。
在这里我们可以看到,(idx1:idx2) 这样的叙述在Fortran 中就是用来指定一个阵列的范围。
2.5. 函数调用与参数传递C 的函数调用就只有一种方式,函数可以传入参数,也可以返回值,例如:void c_function1(int a, float *b){........}int c_function2(int a, float *b){int r;........return r;}int main(void){int a, r;float b;c_function1(a, &b);r = c_function2(a, &b);}其中c_function1() 没有返回值,而c_function2() 有返回值。
而 C 函数的参数传入则有两种方式,正如前面的例子,一个是call-by-value, 即(int a),另一个是call-by-reference, 即(float *b),二者的差别在于:call-by-value 是将参数值复制一份副本到子函数的参数列中,让子函数使用,就算子函数改变了副本的值,也只是改变了子函数中的副本,也不会影响到上层父函数的原参数值。
Call-by-refernce 则相反,它则是将参数所在的地址当做参数传给子函数中,子函数只知道此参数的存储空间所在的地址,它要存取该参数时,必须由此地址去找到该参数。