C语言辅导:可移植性,第1张

C语言辅导:可移植性,第2张

可移植性不是说写出来的程序不需要修改就可以在任何计算机上运行,而是当条件发生变化时,程序不需要做很多修改就可以运行。
不要过早说“我不会遇到这种情况”。在MS-Windows出现之前,很多MS-DOS程序员都不太在乎可移植性。然后,突然之间,他们的程序不得不运行在一个看起来不同的操作系统上。当Power PC变得流行时,Mac程序员不得不处理新的处理器。任何在同一版本的UNIX下维护过程序的人,对可移植性的了解足以写一本书,更不用说一章了。
假设你用基本的albatr-OS(防抱死制动和轮胎转动操作系统)的Tucker C编写防抱死制动软件,听起来就是最典型的非便携软件。即便如此,可移植性仍然很重要:你可能需要将其从Tucker C的7.55c版本升级到8.o版本,或者从ALBATR—OS的3.o版本升级到3.2a版本,以纠正软件中的一些错误;出于模拟测试或宣传的目的,您也可以将其(或其一部分)移植到MS-Windows或UNIX工作站上;更有可能的是,在它最终完成之前,你会把它从一个程序员手中移交给另一个程序员。
可移植性的初衷是按照预期的方式做事。它的目的不是为了简化编译程序的工作,而是为了进行重写(重写!)程序的工作就变得容易了。如果你是接手别人程序的“倒霉蛋”,那么原程序中每一个意想不到的地方都会占用你的时间,并可能在以后造成细微的错误。如果你是原程序的编写者,你应该注意不要让你的程序出现意外代码。你要尽量让程序通俗易懂,这样就没人会抱怨你的程序难懂了。况且,再过几个月,下一个“倒霉的人”
很可能就是你自己,到时候你可能已经忘了当初为什么要这么复杂地写一个for循环了。
让程序可移植的本质很简单:如果有简单标准的方法来做某件事,就这么做。
使程序可移植的第一步是使用标准库函数,并与ANSI/ISO C标准中定义的头文件一起使用。详见第11章“标准库函数”。
第二步,让编写的程序尽可能适用于所有编译器,而不仅仅是你现在使用的编译器。如果你的手册提醒你一个函数或者一个函数是你的编译器或者某些编译器独有的。你应该小心使用它。有很多关于C语言编程的好书对如何保持良好的可移植性提出了一些建议。尤其是在不知道某个东西是否会工作的时候,不要马上写一个测试程序,看看你的编译器会不会接受,因为即使这个版本的编译器接受了,也不代表这个程序有很好的移植性(C++程序员比C程序员更应该重视这个问题)。此外,小的测试程序很可能会遗漏要测试的性能或问题的某些方面。
第三步,分离不可移植代码。如果你不确定某个程序是否可移植,你应该尽早把它注释掉。如果有一些大的程序段(完整的函数或更多)依赖于它们的运行环境或编译方法,你应该将不可移植的代码分离成一些独立的”。c "文件。如果只有几个小程序段存在可移植性问题,可以使用#ifdef预处理指令。比如在MS-DOS中,文件名的形式是“\ tools \ readme”,而在UNIX中,文件名的形式是“/tools/readme”。如果您的程序需要将这样的
文件名分解成独立的部分,您需要找到正确的分隔符。如果有这样的代码
# ifdefunix
# define file _ sep _ char '/'
# endif
# ifdef _ _ msdos _
define FILE SEP CHAR ' \ \
# endif
通过将FILE _ SEP _ CHAR传递给strchr()或strtok(),可以找到文件名的路径部分。虽然这一步还找不出一个MS-DOS文件的驱动器名,但已经是一个正确的开始了。
最后,发现潜在的可移植性问题的方法之一就是请别人去找!如果可以的话,请别人来检查你的程序。他可能知道一些你不知道的东西,也可能发现一些你从未想到的问题(一些名字中带有“lint”的工具和一些编译器选项可以帮助你发现一些问题,但你不能指望它们发现大问题)。
15.1编译器中的C++扩展函数可以用在C程序中吗?
不,它们只能在真正的C++程序中使用。
c++中的一些优秀性能已经被ANSI/ISO C标准委员会接受。它们不再是“c++扩展函数”而是成为了C的一部分,比如在C中加入了函数原型和const关键字,因为它们真的非常有用。
有一些C++的性能,比如inline function和用const替换#define的方法,有时被称为“高级C”性能。一些由C和C++共享的编译器提供了这样的性能。你能使用它们吗?
有些程序员持有这样的观点,如果他们想写C代码,就应该只写C代码,并且让所有的C编译器都能接受。如果你想用C++性能,那就去用C++。可以一步一步来,每次用一点新技能;你也可以一步写一个模块化的抽象基类,里面有大量的内联函数,异常处理和转换操作符。当你跨过这一步,你的程序将是当前的C++程序,你不能指望C编译器接受它。
作者的看法是,你的工作从一个新的C标准开始,这个标准包含了一些C++的性能和一些全新的性能。在接下来的几年里,一些编译器开发人员将会实现其中的一些新性能,但这并不能保证所有的编译器都会实现这些性能,也不能保证下一个C标准会包含这些性能。你应该关注事态的发展。当一个新的性能似乎真的变得流行了,而且它不仅出现在你现在使用的编译器中,而且出现在你可能使用的所有编译器中,你就可以考虑使用它了。举个例子,如果过去有人要等到1989年才开始使用函数原型,那就不是明智之举。另一方面,在可移植的前提下,过去没有时间开始使用noalias关键字。
请看:
15.2 c++和C有什么区别?
15.2 c++和C有什么区别?
这个问题要从C程序员和C++程序员的角度来分析。
对于C程序员来说,C++是一种奇怪而又难以掌握的语言。大多数C++库无法通过C编译器连接到C程序(连接时,编译器必须创建模型或“虚拟表”,但C编译器不提供这种支持)。即使用C++编译器来连接程序,C程序仍然不能调用很多c++函数。除非你非常仔细地编写C++程序,否则c++程序永远比类似的C程序要慢,要大。C++编译器的错误也比C编译器多。C++程序更难从一个编译器移植到另一个编译器。最后,C++是一门庞大而难学的语言。它的定义手册(1990年)有400多页,每年都会增加大量的内容。另一方面,C语言是一门漂亮简洁的语言,这几年变化不大(当然不可能永远不变,见14.1)。c编译器很好用,而且越来越好。好的C程序很容易在好的C编译器之间移植。虽然用C做面向对象设计不容易,但也不是很难。如果需要,你可以(几乎)一直用c++编译程序,生成C程序。
对于C++程序员来说,C是一个很好的开始。在C++里,你不会重复C里犯的很多错误,因为编译器不会给你这个机会。C的一些技能,如果使用稍有不当,就会带来很大的危险。
另一方面,c++是一门优秀的语言。只有应用几个原则,提前做一点设计工作,才能写出一个安全、高效、易于理解和维护的C++程序。一些编写C++程序的方法可以使C++程序比类似的C程序更快更小。面向对象的设计在C++中非常容易,但是你不必这样工作。编制程序日臻完善,标准逐步建立。如果有必要,你可以随时返回C.
那么,C和C++的具体区别是什么?C的一些组件是不允许在c++中使用的,比如老式的函数定义。总的来说,C++只是一种有一些新特性的C:
…新的注释规则(见15.3);
…真真假值的Boolean类型,兼容现有C或c++程序(显示器上贴的“O=false,1=true”的纸条可以扔掉。它仍然有效,但不再需要)。
内联函数比#define宏定义更安全更强大,速度也是一样的。
…如果需要,可以确保变量的初始化,不再有用的变量会被自动清除。
类型检查和内存管理更好、更安全、更强大。
封装——允许定义新类型及其所有操作。C++中有一种复杂类型,它的运算和语法规则与float和double相同,但它不是编译器固有的,而是在C++中实现的,它使用的是每个c++程序员都可以使用的那些性能。
...访问控制01——使新类型只能通过它所允许的操作来使用。
继承和模板——编程的两种辅助方法,提供了函数调用之外的代码重用方法。
...异常——允许函数向其调用方以外的函数报告问题。
一种新的I/O处理方法——比printf()更安全更强大,可以将格式与要写入的文件类型分离。
…一个数据类型丰富的库——你永远不需要自己写链表或者二叉树(这是真的!)。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C语言辅导:可移植性

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情