当前位置:网站首页>C专家编程 第1章 C:穿越时空的迷雾 1.10 “安静的改变”究竟有多少安静
C专家编程 第1章 C:穿越时空的迷雾 1.10 “安静的改变”究竟有多少安静
2022-08-03 16:09:00 【weixin_客子光阴】
/*1.10 "安静的改变"究竟有多少安静*/
/*目的是使C语言更加可靠*/
/*算术转换(K&R C)
*操作数 转换类型
*寻常算术转换(usual arithmetic conversion)
*操作数为char或short会转变成int
*操作数为float会转变成double
*首先,其中一个操作数为double,其他类型会转换成double,结果类型也为double(优先级较高)
*其次,其中一个操作数为long,其他类型会转换成long,结果类型也为long类型
*最后,其中一个操作数为unsigned,其他类型会转换成unsigned, 结果类型为unsigned类型
*其他情况,如果两个操作数的类型都为int,计算结果的类型也是int
*/
/*算术转换(ANSI C)
*字符和整型(整型升级)
*char、short int或者int型位段(bit-field),包括它们的有符号或无符号变体,以及枚举
*类型,可以使用在需要int或unsigned int的表达式中。如果int可以完整表示源类型的所有值
*那么该源类型的值就被转换为int,否则转换为unsigned int。这称为整型升级。
*寻常算术转换
*许多操作数类型为算术类型的双目会引发转换,并以类似的方式产生结果类型。
*它的目的是产生一个普通类型,同时也是结果的类型。这个模式称为“寻常算术转换”
*首先,一个操作数类型为long double,另一个操作数类型也被转换成long double
*其次,一个操作数类型为double, 另一个操作数类型也被转换成double
*最后,一个操作数类型为float, 另一个操作数类型也被转换成float
*否则,两个操作数进行整型升级,并执行下面的规则
*如果其中一个操作数的类型为unsigned long int, 那么另一个操作数也被转换成unsigned
*long int。其次,如果其中一个操作数的类型为long int, 而另一个操作数类型是unsigned int,
*如果long int能够完整表示unsigned int的所有值,那么unsigned int类型操作数被转换成long int;
*如果long int不能完整表示unsigned int的所有值,那么两个操作数都被转换成unsigned long int.
*再次,如果其中一个操作数的类型为long int, 那么另一个操作数被转换为long int。
*最后,如果其中一个操作数的类型是unsigned int, 那么另一个操作数也被转换成unsigned int.
*如果所有以上情况都不属于,那么两个操作数都为int。
*浮点操作数和浮点表达式的值可以用比类型本身所要求的更大的精度和更广的范围来表示,而它
*的类型并不因此改变。
*/
/*ANSI C标准所表示的意思大致如下:
*当执行算术运算时,操作数的类型如果不同,就会发生转换。数据类型一般朝着浮点精度更高,
*长度更长的方向转换。整型数如果转换为signed不会丢失信息,就转换为signed,否则转换为
*unsigned。
*/
/*K&R C采用无符号保留(unsigned preserving)原则,就是当一个无符号类型与int或者更小的整型混合使用时,结果类型为无符号类型。
*ANSI C标准采用值保留(value preserving)原则,就是当把几个整型操作数混合使用时(如下面的程序所示),结果类型既有可能是有符号数,也可能是无符号数,具体取决于操作数的类型的
相对大小。
*/
#include <stdio.h>
int main( void ){
if( 1u - 2 >= 0 ){
printf( "the result of unsigned int number substract signed int number is larger than or equal to zero" );
} else{
printf( "the result of unsigned int number substract signed int number is smaller than zero" );
}
return 0;
}
/* 输出:

*/
#include<stdio.h>
int main() {
if (-1 < (unsigned char) 1) { //equivalent to (int)-1 < (int)1
printf("-1 is less than (unsigned char)1: ANSI semantics");
} else { //equivalent to (unsigned int)(-1) < (unsigned int)1
printf("-1 NOT less than (unsigned char)1: K&R semantics");
}
return 0;
}
/* 输出:

*/
程序中的表达式在两种编译器下的编译器结果不同。-1的位模式是一样的,但一个编译器(ANSI C)将它解释为负数,另一个编译器(K&R C)却将它解释为无符号数,也就是变成了正数。
/*软件信条*/
#include <stdio.h>
int array[] = {23, 34, 12, 17, 204, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) //无符号整数(unsigned int)
int main() {
int d = -1, x;
// /*...*/
//error equivalent to (unsigned int)d <= (unsigned int)TOTAL_ELEMENTS - 2
if (d <= TOTAL_ELEMENTS - 2) {
x = array[d + 1];
}
// /*...*/
//correct //equivalent to (int)d <= (int)TOTAL_ELEMENTS - 2
if (d <= (int)TOTAL_ELEMENTS - 2) {
x = array[d + 1];
}
}
/*
*#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
*#define TOTAL_ELEMENTS (sizeof(array) / sizeof(int))
*因为前者可以在不修改#define语句的情况下改变数组的基本类型。
*/
/*无符号类型的建议*/
/*尽量不要在代码中使用无符号类型,以免增加不必要的复杂性。尤其是不要仅仅因为无符号
*不存在负值(如年龄、国债)就用它来表示数量
*尽管使用像int那样的有符号类型,这样在涉及升级混合类型的复杂细节时,不必担心边界
*情况(如-1被翻译为非常大的正数)。
*只有在使用位段和二进制掩码时,才可以使用无符号数。
*应该在表达式中使用强制类型转换,使操作数均为有符号数
*或者无符号数,这样不必由编译器来选择结果的类型
*/
边栏推荐
猜你喜欢

想进阿里?先来搞懂一下分布式事务

蒋松廷 荣获第六季完美童模全球总决赛 全球总冠军

2年开发经验去面试,吊打面试官,即将面试的程序员这些笔记建议复习

leetcode:202. 快乐数

罗克韦尔AB PLC RSLogix5000中创建新项目、任务、程序和例程的具体方法和步骤

MPLS的wpn实验

Common distributed theories (CAP, BASE) and consensus protocols (Gosssip, Raft)

MATLAB | 一种简易的随机曼陀罗图形生成函数

MySQL性能优化_小表驱动大表

《安富莱嵌入式周报》第276期:2022.07.25--2022.07.31
随机推荐
【Unity入门计划】基本概念(8)-瓦片地图 TileMap 02
vector类
视频人脸识别和图片人脸识别的关系
简易网络传输方法
Kubernetes 笔记 / 目录
MySQL窗口函数
全新探险者以40万的产品击穿豪华SUV价格壁垒
如何设计大电流九线导电滑环
一个文件管理系统的软硬件配置清单
纯纯粹粹纯纯粹粹
不可忽略!户外LED显示屏的特点及优势
C专家编程 第3章 分析C语言的声明 3.5 typedef可以成为你的朋友
滑环安装注意事项
ReentrantLock详解
【翻译】关于扩容一个百万级别用户系统的六个课程
下午见!2022京东云数据库新品发布会
Not to be ignored!Features and advantages of outdoor LED display
To add digital wings to education, NetEase Yunxin released the overall solution of "Internet + Education"
How to analyze the weekly activity rate?
13 and OOM simulation