关于有符号数、无符号数和数据类型的总结
《关于C语言中各种数据类型使用场合》

《关于C语言中各种数据类型使用场合》C语言中各种数据类型使用场合有以下几种:1、整数:C语言中的整数包括字符型(char)、短整型(short int)、整型(int)、长整型(long int)和无符号整型(unsigned int),一般用于存储整形数据,如果用于存储字符型数据,那么最多只能存储256个字符,整数常用作计算机的存储指令,可以用来进行算术和逻辑运算。
2、浮点数:浮点类型有单精度(float)和双精度(double),一般用于存储有小数部分的数据,有时也可以用来存储大整数,浮点数常用作计算机的计算指令,可以用来进行实数的运算,例如加、减、乘、除等。
3、字符型:字符型数据表示成单个字符,用来存储字符常量或字符变量,字符常量是用单引号括起来的非负整数值,字符变量是指整数型的变量,最多只能存储256个字符,字符型常用作计算机的存储指令,可以用来进行字符串的操作。
4、字符串:字符串由零个或多个字符组成,有时也可以是由数字或字母字符表示的一种特殊字符串,字符串常用作计算机的存储指令,可以用来进行字符串的操作,比如字符串的拼接、搜索和调整等。
5、布尔类型:布尔类型用于表示逻辑量,只有两个状态:真(TRUE)或假(FALSE),在C语言中,一般用整数来表示布尔类型,0 表示假,非 0 表示真。
布尔类型常用作计算机的控制指令,可以用来进行逻辑判断,比如 if...else 等。
6、枚举类型:枚举类型是一种特殊的整型,其中的值仅限定在由程序员定义的一组枚举值中,每个枚举值都是一个不同的整数,枚举类型可以用来表示一系列关联的常量值。
它有助于更好地理解程序中的代码,并使得程序更易于维护和编写。
总的来说,C语言中的各种数据类型均有自己的用途,正确选择合适的数据类型可以显著提高程序的执行效率,提升程序的可读性和维护性。
因此,在编写程序时,一定要根据实际需要选择合适的数据类型。
c语言中整型数据的存储形式

c语言中整型数据的存储形式在C语言中,整型数据(Integer)在内存中的存储形式是固定长度的二进制数。
它们可以是带符号数或无符号数,以及不同的长度和大小。
先说一下带符号数。
带符号整型数据可以表示负值。
在C语言中,最常用的带符号整型数据类型是int(整型),它占用4个字节(32位),可以表示从-2147483648到2147483647的整数值。
在存储带符号整型数据时,使用的是“二进制补码”(Two's Complement)表示法。
这种表示法是如此普遍的原因是它符合自然的加减运算法则,同时可以在CPU中用简单的电路实现。
比如,如果要存储-5这个数,首先将它的绝对值转化成二进制:5的二进制是101,接着将所有位取反得到010,最后加1得到011,这就是-5以二进制补码形式的存储形式:11111111 1111 1011。
再说说无符号整型数据(Unsigned Integer)。
它只能表示正整数,但在同样大小的空间内可以存储更大的值。
在C语言中,最常用的无符号整型数据类型是unsigned(无符号整数),它占用4个字节(32位),可以表示从0到4294967295的正整数值。
在存储无符号整型数据时,直接使用二进制表示这个数即可。
比如,如果要存储123这个数,直接将它转化成二进制即可:0111 1011。
除了int和unsigned,还有short(短整型)和long(长整型)等整型数据类型。
它们分别占用2个字节和8个字节。
这些数据类型在不同的编译器中占用的字节数可能不同。
无论用哪种整型数据类型,在内存中存储一个整型数据需要使用一块固定长度的内存空间。
对于32位的int,就需要4个字节的内存空间。
每个字节(Byte)由8个比特(Bit)组成,因此int变量会占用32个比特的空间。
这32个比特的位序(Bit Order)在不同的编译器和计算机体系结构中可能不同。
在存储整型数据时,常常需要考虑大小端(Endianness)的问题。
c++11各个类型最大数函数

一、Introduction在进行C++编程时,经常会遇到需要找出各个类型的最大数的情景。
C++11引入了一些新的类型和函数,使得查找各个类型的最大数变得更加方便和高效。
本文将对C++11中各个类型的最大数函数进行详细介绍。
二、Integral types(整数类型)1.对于8位有符号整数(int8_t)和无符号整数(uint8_t),可以使用numeric_limits来获取最大值。
2.对于16位整数(int16_t)和无符号整数(uint16_t),也可以使用numeric_limits来获取最大值。
3.对于32位整数(int32_t)和无符号整数(uint32_t),同样可以使用numeric_limits来获取最大值。
4.对于64位整数(int64_t)和无符号整数(uint64_t),同样可以使用numeric_limits来获取最大值。
5.对于long类型,可以使用LONG_MAX来获取最大值。
三、Floating-point types(浮点数类型)1.对于float类型,可以使用FLT_MAX来获取最大值。
2.对于double类型,可以使用DBL_MAX来获取最大值。
3.对于long double类型,可以使用LDBL_MAX来获取最大值。
四、Other types(其他类型)1.对于指针类型,可以使用PTRDIFF_MAX来获取最大值。
2.对于布尔类型,最大值为true。
3.对于字符类型,最大值为127(对于有符号字符)或255(对于无符号字符)。
五、Conclusion通过C++11中新增加的类型和函数,我们可以更加方便地获取各种类型的最大数。
这些新的特性使得C++编程更加高效和便捷。
在实际编程中,我们可以根据具体的需求选择合适的类型和函数来获取最大数,从而提高程序的性能和可读性。
希望本文对大家有所帮助。
C++11中关于各个数据类型最大数函数的介绍仅仅是C++11引入的一系列新特性之一。
无符号数、有符号数、原码、反码、补码——数据在计算机内部的表示

数据在计算机内部的表示与存储作者:刘英皓2013/4/17 今天在做单片机实验的时候,突然对一个问题产生了浓厚的兴趣:数据在计算机内部是怎么表示的?晚上查阅了大量的资料,终于把其中的玄机弄明白了。
资料来源甚广,在此就不一一声明了,感谢!!数据是什么?它是用来表示信息的。
是信息的载体。
比如数值、文字、语言、图形、影像等都是不同形式的数据。
而在计算机中,无论是数值型数据还是非数值型数据,它们都被表示成了0和1。
既然都变成了0和1,那计算机怎么区别这些不同的信息呢?别担心,它们各在有各自的编码规则。
非数值型数据的编码主要有ASCII 码和汉字编码。
这里不深究。
数值型数据:它主要有两种形式,有符号数和无符号数1、有符号数和无符号数它们的定义估计你都听腻了,我就不重复了,我只强调两点:a.计算机不区分有符号数和无符号数。
b.只有有符号数才有原码、反码和补码。
2、原码、反码和补码还是两点:a.正数的原码、反码和补码都一样。
b.负数的反码为原码除符号位的按位取反,补码为反码加1.注意两点:b1.反码1111 1111的补码是0000 0000.b2.补码1000 0000没有对应的原码和反码,它表示-128,这是规定3、计算机存储单元中的数据这个要分两种情况:a.无符号数:直接以对应的二进制表示。
b.有符号数:补码形式表示,无论是计算还是存取。
比如在内存单元中有一个数据为FEH,那么它到底是表示什么?254还是-2?没关系,你说是什么就是什么。
因为计算机是不会区分这个数是有符号数还是无符号数的。
在你写程序的时候,指定这个量是有符号的,FEH就是一个补码,可以计算得它的真值就是-2,如果指定它是无符号的,那么它就是254。
不同的形式在程序中便会有不同的体现。
要注意的是在计算中不要超出了数值的范围,以免发生错误。
如有疑问请联系:yinghao1991@。
计算机原码、反码、补码、机器数、真值、有符号数、无符号数等的区分与运算

在计算机的存储器中统一采用二进制数的方式进行数据存储。
而编程中则综合使用二进制、八进制、十进制与十六进制的数据表示方法,程序编译后一般生成十六进制的可烧写文件,而烧写到存储器后最终在存储单元中存放的还是二进制形式。
而二进制又有真值,原码,反码,补码,机器数,有符号数,无符号数,等诸多概念之分。
故下面主要就二进制数(以整数为例,后面提到的数据皆指整数)的存储与运算过程中涉及到的一些概念与规则进行梳理。
讲的主要是在计算机中的,以8位单片机为例,后面以32位ARM单片机指令举例。
1有符号数和无符号数。
数据首先分为有符号数和无符号数。
对于无符号数来说,肯定指的0与正数,无负数之说,自然也无原码、反码、补码之说,一般也不针对于无符号数讨论机器数、真值等概念。
其存储方式与有符号数存储也无特别之处,具体的将在“存储单元中的数据”一节讲述。
有符号数,有正负与0三种,由于在计算机中无法表示负号,或者说用专门的符号表示负号很不方便,于是就采用对正负号进行数值编码的方式,用“0”代表非负数,“1”代表负数。
根据不同的编码方式,对有符号数一般可以有原码、反码、补码三种最常见的编码形式。
2 真值真值就是所表示的数的大小,一般用10进制表征。
3 原码、反码、补码具体概念我就不重复了,只重申下相关结论:a.正数的原码、反码、补码都相同。
b.负数的反码为原码的按位取反(保持符号位不变),补码为反码加1.4 机器数原码、反码、补码都是机器数的一种表示形式,或说都属于机器数。
5 存储单元中的数据(存储单元包括存储器中的存储单元和寄存器)在计算机的存储器的存储单元中的数据均以补码形式存放的,于是在计算机中的数据表示有下面结论:a不使用原码与反码。
但原码与反码可以作为计算真值的中间媒介。
b存储单元中的数据以补码形式存在。
c 数据的存取与运算都以补码形式进行。
d补码就是机器数,机器数就是补码。
解释:掌握一个基本原则——简单,存储单元是个很有原则的家伙,他只管存01序列,才不管该序列是表示指令编码还是数据呢,更不会管是有符号数还是无符号数,也不管是数据的原码、反码还是补码。
c语言有符号数和无符号数运算

c语言有符号数和无符号数运算ห้องสมุดไป่ตู้
3. 运算规则: - 加法和减法:有符号数和无符号数之间可以进行加法和减法运算。在这种情况下,C
语言会将有符号数视为无符号数进行运算,结果也是无符号数。如果结果超出了无符号数的 表示范围,则会发生溢出。
- 乘法和除法:有符号数和无符号数之间可以进行乘法和除法运算。在这种情况下,C 语言会将有符号数视为无符号数进行运算,结果也是无符号数。
- 比较运算:有符号数和无符号数之间可以进行比较运算。在这种情况下,C语言会将 有符号数视为无符号数进行比较。
c语言有符号数和无符号数运算
4. 注意事项: - 混合运算:在有符号数和无符号数之间进行混合运算时,C语言会将有符号数转换为
无符号数进行运算。这可能导致一些意外的结果,特别是当有符号数为负数时。 - 无符号数的溢出:无符号数在发生溢出时会进行模运算,即超出表示范围的值会被截
断为非负数。
总之,有符号数和无符号数之间的运算在C语言中有一些差异。在进行混合运算时,需要 注意数据类型的转换和溢出的处理,以避免产生意外的结果。
c语言有符号数和无符号数运算
在C语言中,有符号数和无符号数之间的运算有一些区别。以下是关于有符号数和无符号 数运算的一些要点:
1. 数据类型:有符号数使用带符号的数据类型,如int、short、long等;无符号数使用无 符号的数据类型,如unsigned int、unsigned short、unsigned long等。
数据类型

数据类型一、整型1、整型数说明加上不同的修饰符, 整型数有以下几种类型;signed short int有符号短整型数说明。
简写为short或int, 字长为2字节共16位二进制数, 数的范围是-32768~32767。
signed long int有符号长整型数说明。
简写为long, 字长为4字节共32位二进制数, 数的范围是-2147483648~2147483647。
unsigned short int无符号短整型数说明。
简写为unsigned int, 字长为2字节共16位二进制数, 数的范围是0~65535。
unsigned long int无符号长整型数说明。
简写为unsigned long, 字长为4字节共32位二进制数, 数的范围是0~4294967295。
2、整型变量定义可以用下列语句定义整型变量int a, b; /*a、b被定义为有符号短整型变量*/unsigned long c; /*c被定义为无符号长整型变量*/3、整型常数表示按不同的进制区分, 整型常数有三种表示方法:十进制数: 以非0开始的数如:220, -560, 45900八进制数: 以0开始的数如:06; 0106十六进制数:以0X或0x开始的数如:0X0D, 0XFF, 0x4e另外, 可在整型常数后添加一个"L"或"l"字母表示该数为长整型数, 如22L, 0773L, 0Xae4l。
二、浮点型1、浮点数说明float单浮点数。
字长为4 个字节共32 位二进制数, 数的范围是3.4x10-38E~3.4x10+38E。
double 双浮点数。
字长为8个字节共64 位二进制数, 数的范围是1.7x10-308E~1.7x10+308E。
说明:浮点数均为有符号浮点数, 没有无符号浮点数。
2、浮点型变量定义可以用下列语句定义浮点型变量:float a, f; /*a, f被定义为单浮点型变量*/double b; /*b被定义为双浮点型变量*/3、浮点常数表示例如: +29.56, -56.33, -6.8e-18, 6.365说明:1. 浮点常数只有一种进制(十进制)。
北京大学《微机原理与接口技术》无符号数有符号数运算中cfof标志位的使用

无符号数/有符号数运算中CF与OF标志位的使用(以8位为例)一、无符号数与有符号数的表示范围8位无符号数的表示范围:0~255,8个数据位全部用于表示数值。
8位有符号数的表示范围(补码):-128~127,最高位为符号位,其余7位用于表示数值。
溢出:当8位无符号数的运算结果超过8位无符号数的表示范围0~255时,或当8位有符号数的运算结果超过8位有符号数的表示范围-128~127时,出现溢出错误,即运算结果不能用8位数据进行正确表示。
二、进位标志位与溢出标志位的定义CF:进位标志位,用于指示无符号数的运算结果是否出现溢出,溢出,CF=1。
对于无符号数的加减法运算,如果两数之和大于255,超出了无符号数的表示范围,运算结果溢出,同时最高位产生进位;如果两数之差小于0,超出了无符号数的表示范围,运算结果溢出,同时最高位产生借位;因此对于加减法运算,可根据最高位是否产生进位或者借位来判断是否发生溢出。
OF:溢出标志位,用于指示有符号数的运算结果是否出现溢出,溢出,OF=1。
对于有符号数的加减法运算,可根据最高位以及次高位的进位情况来判断运算结果的溢出情况。
如果最高位与次高位的进位状态相同,运算结果正确,未发生溢出;如果最高位与次高位的进位状态不同,发生溢出,运算结果错误。
两点说明:●无符号数运算后,应检查CF标志位,判断是否出现溢出;OF标志位对于无符号数运算无意义,因为根据OF标志位无法判断无符号数的运算结果是否发生溢出。
●有符号数运算后,应检查OF标志位,判断是否出现溢出;CF标志位对于有符号数运算无意义,因为根据CF标志位无法判断有符号数的运算结果是否发生溢出。
三、CPU对CF和OF的置位方式CPU对CF和OF的置位方式如下,以8位加法为例:●在进行加法运算的过程中,不区分参与运算的数据有无符号(加法指令不区分操作数有无符号),8个数据位全部参与运算,根据运算结果对CF和OF进行置位。
●如果运算过程中,最高位产生进位,CF置1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、
CPU只会根据输入信号进行逻辑运算,在硬件级别是没有有符号无符号的概念,运算结束会根据运算前的信号和输出信号来设置一些标志位,是不是有符号由写程序的人决定,标志位要看你把操作数当有符号还是无符号来选择,就像内存中的数据,你可以按照需要来解析,原始数据在那里,你要按什么数据格式来解析在于自己的选择,所以玩汇编的要做到心里有数,加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。
下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
举例来说:内存里有一个字节x 为:0x EC ,一个字节y 为:0x 02 。
当把x,y当作有符号数来看时,x = -20 ,y = +2 。
当作无符号数看时,x = 236 ,y = 2 。
下面进行加运算,用add 指令,得到的结果为:0x EE ,那么这个0x EE 当作有符号数就是:-18 ,无符号数就是238 。
所以,add 一个指令可以适用有符号和无符号两种情况。
(呵呵,其实为什么要补码啊,就是为了这个呗,:-))
乘法运算就不行了,必须用两套指令,有符号的情况下用imul 得到的结果是:0x FF D8 就是-40 。
无符号的情况下用mul ,得到:0x 01 D8 就是472 。
二、
C又是可怕的,因为它把机器层面的所有的东西都反应了出来,像这个有没有符号的问题就是一例(java就不存在这个问题,因为它被设计成所有的整数都是有符号的)。
为了说明c的可怕特举一例:
#include <stdio.h>
#include <string.h>
int main()
{
int x = 2;
char * str = "abcd";
int y = (x - strlen(str) ) / 2;
printf("%d\n",y);
}
结果应该是-1 但是却得到:2147483647 。
为什么?因为strlen的返回值,类型是size_t,也就是unsigned int ,与int 混合计算时类型被自动转换了,结果自然出乎意料。
观察编译后的代码,除法指令为div ,意味无符号除法,即将-2看做无符号数了。
解决办法就是强制转换,变成int y = (int)(x - strlen(str) ) / 2; 强制向有符号方向转换(编译器默认正好相反),这样一来,除法指令编译成idiv 了。
我们知道,就是同样状态的两个内存单位,用有符号处理指令imul ,idiv 等得到的结果,与用无符号处理指令mul,div等得到的结果,是截然不同的!所以牵扯到有符号无符号计算的问题,特别是存在讨厌的自动转换时,要倍加小心!(这里自动转换时,无论gcc还是cl都不提示!!!)
为了避免这些错误,建议,凡是在运算的时候,确保你的变量都是signed 的。
三、自动类型转化时的,短字节向长字节转化时,有符号数会符号扩展,无符号数会0扩展;长字节向短字节转化时,会自动截取高位,留下低位字节。
特别在做算术运算时,比如乘除法,就可能涉及到有符号数自动转化为无符号数,从而采用不同的指令处理。
例如:下面的代码输出是什么,为什么?
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts("> 6") : puts("<= 6");
}
这个问题测试你是否懂得C语言中的整数自动转换原则,我发现有些开发者懂得极少这些东西。
不管如何,这无符号整型问题的答案是输出是”>6”。
原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。
因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。
这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。
如果你答错了这个问题,你也就到了得不到这份工作的边缘。
扩展一下,如果是这段代码呢?
void foo(void)
{
unsigned int a = 6;
int b = -20;
printf("%d\n",a+b);
(a+b > 6) ? puts("> 6") : puts("<= 6");
}
结果是输出:-14 >6
为什么?我们要注意,在printf()中,a+b也是转换为unsigned int(0xF2)的,但是%d 要求又是按照有符号数输出,所以0xf2当成有符号数输出了-14。
四。
特别注意在有常数的算数表达式中,往往有隐含的数据类型转化,因为整数常量并没有明确的被指出其的数据类型,
整常数在不加特别说明时总是正值。
如果需要的是负值,则负号“-”必须放置于常数表达式的前面。
每个常数依其值要给出一种类型。
当整常数应用于一表达式时,或出现有负号时,常数类型自动执行相应的转换,十进制常数可等价于带符号的整型或长整型,这取决于所需的常数的尺寸。
八进制和十六进制常数可对应整型、无符号整型、长整型或无符号长整型,具体类型也取决于常数的大小。
如果常数可用整型表示,则使用整型。
如果常数值大于一个整型所能表示的最大值,但又小于整型位数所能表示的最大数,则使用无符号整型。
同理,如果一个常数比无符号整型所表示的值还大,则它为长整型。
如果需要,当然也可用无符号长整型。
但是,可以在一个常数后面加一个字母l或L强制其数据类型,则认为是长整型。
如1 0 L、7 9 L、0 1 2 L、0 11 5 L、0 X A L、0 x 4 f L等。
L, U, LU,叫类型后缀,.
一般在程序中出现3种数据.我把它们叫,变量,常量,字面量.
变量,常量一般都已经规定了类型了的,所以后缀针对的是字面量.
由于语言默认,整数是int型.即字面量12 是int型的.
如果要表示长整型的12 就得加后缀12L,无符号的12U,无符号长整型的12UL.
具体这些有什么用,你需要了解整数在内存中的存放形式...存放长度(位)...。