这个int8_t范围到底是啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这个int8_t范围到底是啥?相关的知识,希望对你有一定的参考价值。
代码是这样的
#include<stdio.h>
#include<inttypes.h>
int main(void)
int8_t a=127;
printf("\"short\"a=%hhd", a );
return 0;
显示是127,而把“int8_t a=127”的127改为128就变-128了。
当改为256时,显示“隐式常量转换溢出”显示是0。
255时没溢出,显示是-1.
我有点搞不懂。。。
int8_t是在C语言中C99标准规定的,恰好8位(1个字节)的有符号整型数的别名。规定将其定义在<stdint.h>,通常为:范围-128~127。(类比于16、32、64位可记成是-2^7~2^7-1)
C语言是一门通用计算机编程语言,应用广泛。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的国际标准语法,称为ANSI C,作为C语言最初的标准。
int8_t是在C语言中C99标准规定的,恰好8位(1个字节)的有符号整型数的别名。
规定将其定义在<stdint.h>,通常为:
typedef signed char int8_t;
范围-128~127。(类比于16、32、64位可记成是-2^7~2^7-1)
——
下面解释你的问题。
256是0x100超出8位了,把后边8位剩下,就是8个0,按有符号数读出来是0。
255是0xff,8位全是1,按有符号读,所以是-1(有符号数所有位全是1的就是-1啊,1.取反加一逆运算,2.也可以理解成全是0再减去1借一位就全是1)
127是0x7f没可解释的。
128是0x80,最高位1,视作符号,剩下七位是0000000,取反加一逆运算得到10000000(0x80),就是-128。
——
如果没懂可以参考以下网址:
http://en.cppreference.com/w/c/types/integer
把网址的en换成zh可以得到机翻的简体中文版本:
http://zh.cppreference.com/w/c/types/integer
添一句,包含<inttypes.h>是自动包含<stdint.h>的。
在隐含的上下文中,“比更具体”到底是啥意思?
【中文标题】在隐含的上下文中,“比更具体”到底是啥意思?【英文标题】:What exactly does 'is more specific than' mean in the context of implicits?在隐含的上下文中,“比更具体”到底是什么意思? 【发布时间】:2021-12-26 04:38:17 【问题描述】:因此,隐式优先级基于两个因素:一个是关于声明本身具有优先级的范围(范围 A 扩展范围/特征 B,或范围 A 是从具有范围 B 的类型扩展的类型的伴生对象它的伴生对象)。另一个简单地提到 declaration A 比 declaration B 更具体。现在,当我第一次阅读它时,我想到了几种可能的解释,特别是考虑到隐式方法和类型参数的潜在参数(隐式和非隐式)。经验似乎告诉我,这意味着声明 A 的返回值的类型,毕竟类型推断/tapply,是声明 B 的返回类型的子类型。所以,这很好:
class A
class B extends A
implicit val A = new A
implicit val B = new B
implicitly[A]
那为什么不编译呢?
implicit class A(val toInt :Int)
def ! = (1 /: (2 to toInt))(_ * _)
implicit class B(i :Int) extends A(i)
1.!
什么时候做?
class A(val toInt :Int)
def ! = (1 /: (2 to toInt))(_ * _)
class B(i :Int) extends A(i)
implicit val A = i :Int => new A(i)
implicit val B = i :Int => new B(i)
1.!
这是“编译器以神秘方式工作”的另一种情况吗?
【问题讨论】:
【参考方案1】:基于SIP-13 - IMPLICIT CLASSES 提议您的声明:
implicit class A(val toInt :Int)
def ! = (1 /: (2 to toInt))(_ * _)
将被转换为:
class A(toInt: Int)
...
implicit final def A(toInt: Int): A = new A(toInt);
而您的B
又将转换为:
class B(i: Int) extends A(i)
...
implicit final def B(i: Int): B = new B(i);
因此,您基本上是在声明 2 个具有相同参数但不明确的隐式转换方法。虽然由于已经提到隐式参数解析的“最具体”规则,最后一个并不模棱两可。
【讨论】:
恐怕我不明白为什么最后一个不是模棱两可的。一个隐式方法被具体化为一个隐式函数(在 Scala 2 中),所以我看不出语义上的区别到底在哪里。此外,如果我将隐式类声明放在单独的上下文中,然后导入它们(因此它们是本地语法上下文中可用的 borh 标识符,没有前缀),失败的示例有效:***.com/questions/69966645/… @Turin “恐怕我不明白为什么最后一个不是模棱两可的。” - 这是根据你在问题中提到的规则(分辨率隐式参数)。第一个类似于根据参数类型选择方法重载。另请参阅this 问题的答案,那里提到了您的解决方法..以上是关于这个int8_t范围到底是啥?的主要内容,如果未能解决你的问题,请参考以下文章
将这个模板函数专门用于 int8_t 和 uint8_t 的更好方法是啥?