short变量赋值为32768, 实际为什么是-32768?不同语言的不同进制字面量?字面量?编程语言的基本类型?
目录
short变量赋值为32768, 实际为什么是-32768?
不同语言的不同进制字面量
字面量包含非法字符
字面量
字面量使用广泛
字面量默认类型
超过默认类型范围的字面量
编程语言的基本类型
类型标志
short变量赋值为32768, 实际为什么是-32768?
如上假设short类型为2字节。一般而言,编译器计算32768是按照当前值乘10加当前位计算十进制字面量。32768实际上是32767 + 1,即0x7FFF + 1 == 0x8000,即-32768.
- C/C++/ObjC从不会对溢出的计算在运行期报任何错误,编译期根据警告级别可能会提示。不要责怪它们,它们甚至觉得这样的溢出是程序员的预期。
不同语言的不同进制字面量
常见的是十进制,另外为了方便不同场景下使用,八进制和十六进制可以更好的表达二进制,也被大部分编程语言支持,二进制字面量支持程度差异较大。一般而言,0开头(数值位不止一个0)或者0o/0O为八进制,0x或0X开头为十六进制, 二进制如下:
Swift/Ruby/Perl/Rust/Go/Kotlin默认支持0b开头的二进制表示法,除此之外:
- C/ObjC没有默认二进制的表示方法,0开头是八进制,0x/0X开头十六进制。
- C++11之前(不包含),和C/ObjC类似,C++11之后,支持0b或0B二进制表示法。
- Python 2.6开始支持0b或0B的二进制表示法。
- C# 7.0 开始支持0b或0B的二进制表示法。
- Java 7 开始支持0b或0B的二进制表示法。
- PHP 5.4 开始支持0b或0B的二进制表示法。
- JS ES6+支持0b或0B开头的二进制表示法。
- Swift支持2、8、10、16四种进制。0b开头为二进制,0o开头为八进制,0x开头为十六进制。
- VB十六进制是以&H或&h开头,八进制以&O开头,而非其他语言的0x或0开头。
字面量包含非法字符
一般一个八进制字面量中包含超过8的数字,显然是不合法的。编译器默认的行为就提示错误。
- GCC对于八进制字面量 019 会提示:error: invalid digit "9" in octal constant
不过也存在特例:
- JS以0开头(不是0x)的字面量会当做八进制,但是如果数字有超过7且在十进制范围,不会当做错误,而是被二次解析为十进制。
029是十进制的29.
字面量
顾名思义,字面量代表从字面即可看到具体值的变量。100, 'a', "hello", 1.25都是字面量,与标识符a, sum相反,标识符变量字面看不到它的值,是指代关系。字面量英文名literal.
字面量使用广泛
几乎所有编程语言都支持字面量,包括但不止整型、字符型、浮点数和字符串,有的编程语言还支持布尔类型字面量,大部分支持数组、结构体和类对象的编程语言也支持字面量。字面量已经表达了数值,只能当做右值。
字面量默认类型
一般而言,整数默认是int,浮点数默认是双精度浮点数。如果有后缀,按后缀指示的含义,比如后缀u代表无符号,C#后缀m代表decimal类型。
- C/ObjC/C++ 整数默认是int, 浮点数默认是double.
- 仓颉 整数默认是Int64, 浮点数默认是Float64.
- C# 整数默认是int, 浮点数默认是double.
超过默认类型范围的字面量
- C/ObjC/C++ 的处理相对暴力,超过就超过,按溢出的数值来算。
- C# 会提示字面量超出范围,并报错希望程序员换成更大类型。
例如2147483648超过int范围,编译器提示:无法将类型“uint”隐式转换为“int”
编程语言的基本类型
编程语言基本类型大同小异,有符号和无符号也是类型修饰符,但不改变类型主体含义,为避免列出类型名太多,喧宾夺主,如下先忽略有无符号类型的区别。
- C/ObjC/C++
char / short / int / long (long) / float / (long) double- C++: bool
string是STL类,不算基本类型 - C99引入_Bool,C++也可用,本质上_Bool和bool都被当做整型。
- ObjC 额外提供BOOL等类型。
- C++: bool
- Fortran
integer / real / complex / character / logical- kind参数可指定浮点数精度:real(kind=4)和real(kind=8)分别是32位和64位浮点数。
- 仓颉
Int8 / Int16 / Int32 / Int64 / IntNative / Float16 / Float32 / Float64 / Rune(字符类型) / String / Bool / 元组 / 区间 / Nothing / Unit- Rune代表Unicode字符,早期曾使用Char类型,此类型会逐渐phase out.
- Unit类型是一种避免一些副作用表达式有返回值的做法。例如i++在C语言的返回值也是i类型,但仓颉会把它当做Unit类型,即 () 类型,本质是编译器想要程序员不要用这种类型。
- Nothing类型是所有类型的子类型,没有任何值。
- JavaScript
五种基本类型:Undefined、Null、Boolean、Number、String- Undefined类型类似于C语言的未声明或者声明未初始化的变量
- Null类型有唯一字面量null, 和C#或Java的null类似,本质是object类型
- Rust
bool / char / i8 / i16 / i32 / i64 / i128 / f32 / f64 - Go
整型、布尔、字符串类型
int / int8 / int16 / int32 / int64 / byte / rune / float32 / float64 / complex64 / complex128- byte 等同于uint8, rune 等同于int32
- C#
基本类型又被称为预定义类型或基元类型,基类型都有短名称和完整名称(对应BCL)。
byte short int long float double decimal bool null void - Pascal
- 整型 (byte word shortint integer longint) 实数 (real single double extended comp)
real类型可以运行在软件仿真环境,其它实数类型需要运行在处理器浮点模式。 - 布尔 boolean 字符 char
- 整型 (byte word shortint integer longint) 实数 (real single double extended comp)
- PHP
- integer float/double boolean string
- Kotlin
- Kotlin不再区分基本类型和引用类型,任何类型都继承Any类型。可以被认为是"基本"类型有如下:
- 数值类型、布尔类型、字符
- Byte Short Int Long Float Double Boolean Char
- 注意:这些类型均继承Any类,例如,都可以调用Any类hashCode方法。
- 数值类型、布尔类型、字符
- Kotlin不再区分基本类型和引用类型,任何类型都继承Any类型。可以被认为是"基本"类型有如下:
- VB
- Byte Integer Long Single Double Boolean String Currency Date Object Variant
- Byte是无符号1字节,Integer和Long分别是2字节和4字节有符号数,Boolean是2字节。
- Single是4字节,Double是8字节。
- Byte Integer Long Single Double Boolean String Currency Date Object Variant
- VB.NET
- 除了VB的类型,VB.NET引入了SByte, Short, UShort, ULong, UInteger等类型,为了适配.NET平台。
类型标志
- VB是鲜有的提供类型标志的语言,例如%代表Integer类型,#代表Double类型。
- 90和90%同样代表整型90.
若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。