c语言可移植性较差吗,c陷阱与缺陷--可移植性缺陷
引入
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陷阱与缺陷--可移植性缺陷的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言将字符项链,【能量项链】 (C语言
- 下一篇: 99用c语言怎么写出来的,c语言的书写格