chenglong7997

chapter 7(可移植性缺陷)

1.标示符名称的限制

ANSI C标准只保证了C实现必须能够区别出前6个字符不同的外部名称。而且这个定义中并没有区分大写字母与其对应的小写字母。
因此,编写可移植程序必须小心这一点。

2.字符是有符号的整数,还是无符号的整数
只有把一个字符值转换为一个较大的整数时,才重要。在其他情况下,结果都是:多余的位被简单的“丢弃”。

在转换过程中:应该将字符作为有符号数还是无符号数?
如果有符号,编译器将char数据,扩展到int时候,应该复制符号位。
如果无符号,编译器只需在多余的位上填充0.
#include <stdio.h>

int main()
{
    char c='a';
    c=c+40;
//    printf("%c\n", -1); 
    printf("c %d\n", c);
    printf("unsigned c %u\n", (unsigned char)c);
}
结果:
c -119
unsigned c 137
说明在gcc中,将char当做有符号数。在c+40的时候,超过了-128~127范围,因此溢出。如果是无符号char,范围是0~255.应该是输出137.

如果编程者关注一个最高位是1的字符是正还是负,可以设置为无符号字符数。这样所有编译器都会转换为整数时候,填充为0.


3.一个常见错误是:如果c是一个字符变量,使用(unsigned)c可以得到与c等价的无符号整数。这是会失败的。因为在将c转换为无符号整数时候,c将首先首先被转换为int型整数。而此时可能得到非预期的结果。
正确方法是:(unsigned char )c,直接进行转换。

例如上个例子中,最后一句改为:
printf("unsigned c %u\n", (unsigned )c);

那么结果是:
c -119
unsigned c 4294967177
c被先转换为int型-119,再求他的无符号表达形式,4294967177 

4.移位运算符
   1.向右移位时,空出的位由0填充,还是由符号位的副本填充。
   2.如果是无符号数,用0填充。如果是有符号数,既可以用0也可以用符号位的副本。(如果关注右移时候空出的位,可以声明为无符号类型,那么空出的位都会被设置为0)

   如果被移位对象为n位,那么移位计数必须大于或等于0,而严格小于n.
即使C实现将符号位复制到空出的位中,有符号数的向右移位,也并不等于除以2的某次幂。例如(-1)>>1结果为-1,而不是-1/2 == 0

5.随机数最大值,RAND_MAX在limits中定义。我测试结果等于INT_MAX

6.除法运算的截断
q=a/b;
r=a%b;
假定b>0.
C语言定义只保证q*b+r=a,以及a>=0 且 b>0时,保证|r|<|b|以及r>=0.
(如果a<0, 那么r也可能小于0)
例如:
int main() {
    // Start typing your code here
    
    cout<<(-3)/2<<endl;
    return 0;
}
结果商为-1,余数也为-1

posted on 2012-06-25 07:10 Snape 阅读(303) 评论(0)  编辑 收藏 引用 所属分类: Traps


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2012年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

my

搜索

最新评论

阅读排行榜

评论排行榜