引入

c语言是比较底层的语言,相对于c++和java等高级语言而言。c语言在许多不同的系统平台上都有各自的实现,由于各自的实现之间有细微的差别,导致了如今的移植性问题。

在书中说到,由于程序的生命期一般比硬件更长,所以应该注意语言自身的可移植性。但时至今天,这个说法或许需要更正了。

但作者的原意在于,注意可移植性问题可以使你的程序生命期更长,可施展的空间

更大。

一 c语言标准的变更

c语言标准的变更使得语言的特性更多,更方便程序的工作。但是这种变更经常不具备向后兼容性,如此要在语言的重用性和更强大的语言特性间做个选择。

二 标识符名称的限制

这种限制主要体现在其大小写和长度上面。

三 整数的大小

c语言中为编程者提供了3种不同长度的整数:shor型、int型和long型,c语言的定义中对各种类型整数的相对长度进行了规定:

1 3种类型的整数其长度是非递减的。

2 一个普通(int类型)整数足够大以容纳任何数组下标。

3 字符长度由硬件特性决定。

注: 现代大多数机器的字符长度为8位,然而,现在越来越多的c语言实现的字符长度都是16位,已处理诸如汉字之类的语言的大字符集。但是字符类型char仍然是8位的。

在32位机器上,vc6.0的编译环境下,shor类型为16位,int和long类型都是32位。

解决方法 用类型定义来定义“新的”类型,即使类型长度需要变动之需要改动类型定义即可。

如 typedef long

tenmil;//tenmil类型表示的是最大的类型

四 字符是有符号整数还是无符号整数

根据系统不一样可能有不一样的定义,但是如果需要统一的话,可以把字符转变为无符号数然后再处理。

五 移位运算符

1 在向右移位时,空出来的位可能由0或符号位的副本来填充。

2 移位计数(即移位操作的位数)的范围为[0,被移位的对象的长度)

六 内存位置0

在所有的c程序中,无用null指针的效果都是未定义的。但对于0内存地址的数据,不同的机器有自己不同的权限保护。

七 除法运算时发生的截断

例如

q = a / b;

r = a % b;

我们希望a、b、q、r之间维护以下的关系:

1 最重要的一点,我们希望q*b + r =

a,因为这是定义余数的关系。

2 如果我们改变a的正负号,我们希望这会改变q的符号,但这不会改变q的绝对值。

3 当b〉0时,我们希望保证r>=0且r

但这三条性质不能同时具备,大多数的程序设计语言选择了放弃第3条,使得性质1和性质2可以得到满足。

八 随机数的大小

ANSI

C标准中定义了一个常数RAND_MAX,它的值等于了随机数的最大取值。

九 大小写转换

库函数toupper和tolower起初被实现为宏:

#define toupper(c) ((c) + 'A' - 'a')

#define tolower(c) ((c) + 'a' - 'A')

这两个宏都依赖于特定实现中字符集的性质,即需要所有的大写字母与相应的小写字母之间的差值是一个常量。这个假定对ASCII字符集和EBCDIC字符集来说都是成立的。

十 首先释放,然后重新分配

大多数c语言实现都是用了3个内存分配函数:malloc,

realloc和free。

但是问题在于free掉的内存会被系统重新分配,但是如果在系统没有重新分配之前,再次使用这段内存的话仍能获得之前的内存内容。

例如

free(p);

p = realloc (p, newsize);

在某些系统中是允许的。

但是这种做法还是有危险的。因为并非所有的c实现按在某块内存被释放后还能较长时间地保留。

十一 可移植性问题的一个例子

原型:

void

printnum (long n, void (*p)90)

{

if(n<0) {

(*p) ('-');

n = -n;

}

if (n >= 10)

printnum(n/10, p);

(*p) ((int)(n % 10) + '0');

}

这是个打印整数的函数,以下为考虑到可移植性后经过改动的程序:

void

printeg (long n, void (*p)())

{

long q;

int r;

q = n / 10;

r = n % 10;

if (r>0) {

r - =10;

q++;

}

if (n <= -10)

printneg (q, p);

(*p) ("0123456789"[-r]);

}

修改点:

1 在字符集上0-9的字符未必是连续有序的。

2 n<0时,由于有符号数的范围一般是-2[n]~2[n]-1(2[n]表示2的n次幂,n为位数),所以当-2[n]取

正数时变为2[n]时已经溢出了。解决方法为从负数方向去解决这个问题。

后语:

考虑可移植性是个复杂和繁琐的问题,因为以后的硬件什么的怎么变化无法预计。但是,努力提高软件的可移植性,实际上延长了软件的生命期。

tips

软件中出现的很多可移植性问题或其他问题,很多时候在于边界条件上。所以在写程序时,不妨把边界条件作为一个重要的考虑点进行测试。

以下为本章的第二道联系题我的答案:

int

ctol(char ctl)

//该处在答案中不存在,但考虑到字符集自身排序问题还是在此处加上了,

//不过效率显然降低了。

{

int i=0;

char num[10] = "0123456789";

for(;i<10;i++)

{

if(num[i] == ctl)

return i;

}

}

long

atol(char *cl)

{

int result = 0;

int i = 0;

if((*cl == '+') || (*cl == '-'))

i++;

while(1)

{

if((cl[i] < '0') || (cl[i]

> '9'))

{

assert(0,

"invalid input!");

}

result = result*10 +

ctol(cli[i]); i++;

}

if(*cl == '-')

result = -result;

return result;

}

c语言可移植性较差吗,c陷阱与缺陷--可移植性缺陷相关推荐

  1. 计算日期差的方法c语言,C语言计算日期差的方法示例

    本文实例讲述了C语言计算日期差的方法.分享给大家供大家参考,具体如下: 历史上,不同的人类聚居地可能有不同的历法,因而记录下来的资料中日期的换算就很麻烦.幸好今天我们统一使用公元纪年法.当然,这种历法 ...

  2. 用c语言实现交并差算法,C语言实现集合的交,并,差

    C语言实现集合的交,并,差 作者:Raining_C      来源:http://blog.csdn.net/Raining_CN [问题描述] 编制一个能演示执行集合的并.交和差运算的程序 [基本 ...

  3. js与c语言效率_JavaScript比c语言的性能差了多少?

    我这里先不说和C之间的性能差距,而是展开说JavaScript递归优化问题,有人问我为什么不说性能差距,我:???这个问题就跟问地球为什么是圆的一样(明摆着) 传统的递归函数,比如: function ...

  4. 利用python语言实现帧差法,python+opencv实现帧差法

    实验效果如下图: 需要的可以下载代码文件直接就可以运行看看效果哦. 帧差法实现运动目标检测

  5. 高次差周跳检测C语言,利用高次差与自相关函数对周跳探测与处理

    0引言在高精度BD/GPS数据处理中,由于接收机所获得的载波相位是用于估计参数的主要观测量.在 连续观测中由于某种原因(卫星信号被遮挡而无法到达接收机,外界干扰或者是环境恶劣引起接收机失锁)而导致整周 ...

  6. c语言volatile 结构体,volatile的陷阱

    例:多次的间接指针引用 考察如下代码: /* DMA buffer descriptor */ struct bd { unsigned int state; unsigned char *data_ ...

  7. R语言读取Excel文件的一系列陷阱

    你想用R读取一个Excel文件,你觉得这事没啥难的,就像所有的文件读取,只需要知道文件名就万事大吉了. 于是,你把1.xls放到读取.R的文件夹下面,重命名为1.csv,打开rstudio,执行下面这 ...

  8. c语言程序能够在不同的操作系统下运行,这说明c语言具有很好的,程序设计(C)作业一(有答案)...

    程序设计(C)作业一 1.C语言程序的执行,总是起始于(). A.程序中的第一条可执行语句 B.程序中的第一个函数 C.main函数 D.包含文件中的第一个函数 2.以下叙述不正确的是(). A.一个 ...

  9. C 语言编程 — 静态库、动态库和共享库

    目录 文章目录 目录 文章目录 程序函数库 静态链接 创建静态库文件 动态链接 创建共享库文件 共享库文件的名字 共享库文件的存储路径 LD_LIBRARY_PATH 环境变量 ldconfig 指令 ...

最新文章

  1. IE6重复字符BUG
  2. c# 多线程中lock用法的经典实例
  3. linux php安装memcached扩展
  4. Java Socket编程详解
  5. java 快速io_Java编程在ICPC快速IO实现源码
  6. C语言实例:3个数从小到大排序
  7. MATLAB学习笔记(十一)
  8. 高性能HTTP加速器Varnish(概念篇)
  9. CSS轮廓 边距 填充 分组和嵌套
  10. 解决jupyter notebook输出显示不完整问题
  11. Futter基础第20篇: 实现轮播图 flutter_swiper
  12. java clob内存溢出_java - 从JSON创建CLOB属性 - 堆栈内存溢出
  13. ios怎么引入masonry_iOS Masonry的使用需要注意的地方
  14. 190527每日一句,励志| 为了成功,约束自己;有时候“再等等”,就再也等不到了
  15. 康佳电视系统升级服务器地址,【当贝市场】康佳智能电视本地升级教程
  16. visio2003中、origin中、matlab中,字体的大小以pt为单位,与word中的几号字大小是如何对应?
  17. python 多元字符多项式的展开问题
  18. 403 Forbidden - PUT https://registry.npmjs.org/- Forbidden
  19. 笔记本电脑电流声(滋啦滋啦声)解决方案
  20. matlab滤波实验,卡尔曼滤波实验及matlab实现

热门文章

  1. Codeforces Beta Round #4 (Div. 2)【完结】
  2. 【C++】运算符重载
  3. Spring boot重新编译
  4. 32M内存 跑linux内核,32位Linux单进程4G内存限制
  5. 板材开料最优算法_板材套料软件AutoNest与Tekla Structures协同工作实现设计到加工自动化...
  6. 通过 Docker 部署 Redis 6.x 集群
  7. 一整套Java线上故障排查技巧,爱了!
  8. 硬核!如何在 Github 精准搜索开源项目?
  9. java数字转字符串及字符串转数字
  10. js浮点数运算不精确 如何解决_解决 浏览器处理数字运算时精度丢失的方法