关于 C 的 arithmetic conversion (进行 算术运算 时的 强制转换规则)

先上两个解释我的疑惑的链接:

http://en.cppreference.com/w/cpp/language/operator_arithmetic

https://msdn.microsoft.com/en-us/library/3t4w2bkb.aspx

开始我是看 <<Expert C programming -- Deep C Secrets>>这本书(中文译作 C专家编程), chapter 1 里面的how quite is a quite change 这一小节, 有这样一段代码:

#include <stdio.h>

int main()
{
    if(-1 < (unsigned char)1)
        printf("-1 is less than (unsigned char)1: ANSI semantics.\n");
    else
        printf("-1 is NOT less than (unsigned char)1: K&R semantics.\n");
    return 0;

}

我用了vs2013和gcc 4.9.1分别去编译运行, 都是ANSI的语义.打印第一条语句.

然后改成这样

#include <stdio.h>

int main()
{
    if(-1 < (unsigned int)1)//或者是unsigned
        printf("1111111111.\n");
    else
        printf("222222222222222.\n");
    return 0;
}

gcc 4.9.1编译运行(未加任何特殊编译选项)的结果是打印第二条. 而vs2013默认编译不通过, error:负数转变成了无符号数.

开始看 <<Expert C programming -- Deep C Secrets>>这本书这里时有点偷懒, 只记得了这两句话:

      Operands with different types get converted when you do arithmetic. Everything is converted to the type of the floatest, longest operand, signed if possible without losing bits. 

实际上完整的规则还是本文开头的哪两个链接靠谱.

我觉得 best practice应当是尽量少用强制转换,  谁想去记忆那些无聊的规则.

时间: 2024-11-06 11:33:12

关于 C 的 arithmetic conversion (进行 算术运算 时的 强制转换规则)的相关文章

各版本数据库初次登录时,强制修改密码

说明: 因为新版本的数据库加强了安全性,所以每次登录时都强制要求修改密码.'root'@'localhost'这个用户的初始密码会在安装 数据库时记录到/var/log/mysqld.log文件中,所以首次登录时,需要找到这个密码,然后登录. mysql 5.6版本登录后修改密码: mysql> SET PASSWORD = PASSWORD('mypass'); mysql 5.7版本登录后修改密码:(二进制版本数据库,非yum安装和源码安装) mysql> alter user 'root

当页面返回不刷新时进行强制刷新

disableBFCacheBeforeHistoryTravel: function() { // https://www.google.com/search?q=BFCache // 情景:将要跳转到某一被 BFCache 了的页面,希望该页面强制刷新 // 用法:在 history.go() history.back() 之前调用此方法 localStorage.setItem('bfcache_disable', true); }, preventBFCacheOnCurrentPage

C++中算术运算的隐式转换规则

1.隐式转换     C在以下四种情况下会进行隐式转换: 1.算术运算式中,低类型能够转换为高类型. 2.赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他. 3.函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参. 4.函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数. 2.算数运算的隐式转换     算数运算中,首先有如下类型转换规则: 1.字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) . 2.short型

C++ Primer 4th 读书笔记(第一部分)

虽然,有一定的c++基础(因为本科就学会了这一种,哈哈),但是还是决定系统的读一遍这本书(之前有零星看过数次..汗). 留作自己以后参考.(内容会不定期更改,不断学习(此处应为长音~~)) 大部分都是自己掌握的不够扎实的地方和以前没有注意的一些细节. 书中好多地方,详述了知识出现的缘由,最起码是指出为了解决什么问题而出现的!! 前言部分 1."...大量使用了前后交叉引用..."(挺适合自己的,我想知道原文是怎么的,希望以后有机会对原版的时候补充~) 2.作者对本书的定位是本指南性读物

svn提交时强制添加注释 (转)

SVN提交时,如果没有注释,在查阅历史时,会非常不方便.因此我们需要有一个让程序员提交代码时,强制添加注释的规则.下面看看在SVN中怎么实现. 1. 推荐使用VisualSVN作为服务端(免费下载地址:http://www.visualsvn.com/).安装完毕后,打开VisualSVN Server管理器,在版本库上点击"属性",选择"Hooks"选项,选中"Pre-commit hook"后,点击"Edit".(如下图)

WPF中ItemsControl应用虚拟化时找到子元素的方法

wpf的虚拟化技术会使UI的控件只初始化看的到的子元素, 而不是所有子元素都被初始化,这样会提高UI性能. 但是我们经常会遇到一个问题: 应用虚拟化后看不见的子元素因为没有实际产生导致ItemContainerGenerator的查找元素方法(ContainerFromIndex / ContainerFromItem)失效. 解决办法1: (1)监听ItemsControl的ItemContainerGenerator的StatusChanged事件, 当GeneratorStatus为Con

初学者常见错误1——赋值时的类型转换

猜测下面程序的输出结果,并上机尝试: 1. #include<stdio.h> #include<math.h> int main() { printf("%d",pow(5,2)); } 2. #include<stdio.h> #include<math.h> int main() { printf("%f",pow(5,2)); } 3. #include<stdio.h> #include<m

MDK常见错误详解集合

错误代码及错误信息 错误释义 error 1: Out of memory 内存溢出 error 2: Identifier expected 缺标识符 error 3: Unknown identifier 未定义的标识符 error 4: Duplicate identifier 重复定义的标识符 error 5: Syntax error 语法错误 error 6: Error in real constant 实型常量错误 error 7: Error in integer consta

《C和指针(Pointer on c)》 学习笔记(转自:http://dsqiu.iteye.com/blog/1687944)

首先本文是对参考中三个连接的博客进行的整理,非常感谢三位博主的努力,每次都感叹网友的力量实在太强大了…… 第一章 快速上手 1.  在C语言中用/*和*/来注释掉这段代码,这个实际上并不是十分的安全,要从逻辑上删除一段C代码,最好的办法是使用#if指令: #if 0 Statement #endif 2.  其他语言中,无返回值的函数称为过程(procedure). 3.  数组做参数的时候是以引用(reference)的方式传递的,即地址传递.而标量和常量都是传值调用,被调用的函数无法修改调用