C语言中的整型数据类型(你真的了解吗)

简介: C语言中的整型数据类型(你真的了解吗)

1. 整型数据类型


C语言里面的整数数据类型

类型名称 C语言中的关键字 注释
字符型 char 表示一个很小的整数
短整型 short 表示一个不怎么大的整数
整型 int 生活中一般的整数都可以表示
长整型 long 较大的整数
加长整型 long long 非常大的整数


一个整数而已,为什么会需要定义这么多不同的类型出来呢?


计算机通过晶体管的开关状态来记录数据。它们通常8个编为一组,我们称之为字节。而晶体管有开关两种状态,一个字节有8个晶体管,因此一个字节可以拥有2的八次方个不同的状态。让每一种状态对应一个数值,这样一个字节可以表示256个不同数值。

晶体管状态 二进制数值 十进制数值
关关关关关关关关 00000000 0
关关关关关关关 00000001 1
关关关关关关 00000010 2
关关关关关关开开 00000011 3
10101010 170
开开开开开开开开 11111111 255


要表示更大的数据范围就需要更多晶体管。要知道在发明C语言的年代,计算机存储资源是非常珍贵而稀缺的。如果只想表达0到100以内的数值,那么一个字节就足够了,何必用两个字节来存储?


而如今,即使存储资源已经较为丰富了,但是大部分的强类型语言,都延续了这个传统。它们均提供了丰富的类型以供选用。而程序员在编写代码时,通常能预想到需要使用到的数据范围的大小。这样在处理一个数据时,可以从语言所提供的类型中选用最合适的类型来承载数据。


在C语言标准并未规定这些数据类型的大小范围,具体的实现交由了编译器和平台决定。


2. 用sizeof关键词来测量大小


和int一样,sizeof是C语言中的一个关键词。它是英文size of连起来的合成词。翻译成中文就是什么东西的大小的意思。它能够测量C语言各种实体所占用的字节大小。


如果我们想看int所占用的字节大小,可以这样写sizeof(int)。执行后这段代码后,它的测量结果是一个整型。我们可以借助printf函数将测量结果显示在控制台上。我们现在可以假设sizeof返回的结果是int类型的,在printf函数中使用占位符%d。而更准确的用法,应该用%zu。


测量int类型所占用的字节大小,并将结果打印在控制台上的代码如下:

printf("%d\n", sizeof(int));

sizeof后面既可以跟 类型,也可以跟 变量、常量。


跟类型,测类型所占用字节的大小。

跟变量,测变量的类型所占用字节大小。

跟常量,测常量的类型所占用字节大小。

三种情况的示例代码。

int a; 
printf("sizeof int = %d\n", sizeof(int)); // 1.测类型所占用字节的大小 
printf("sizeof a = %d\n", sizeof(a)); // 1.测变量的类型所占用字节大小 
printf("sizeof 123 = %d\n", sizeof(123)); // 1.测常量的类型所占用字节大小


测试C语言提供的各种整型类型的大小

printf("sizeof char=%d\n", sizeof(char));
printf("sizeof short=%d\n", sizeof(short)); 
printf("sizeof int=%d\n", sizeof(int));
printf("sizeof long=%d\n", sizeof(long));
printf("sizeof long long=%d\n", sizeof(long long));

1673451848808.jpg

结果:char,short,int,long,long long分别占用了1,2,4,4,8个字节。至此,我们已经得知了它们所占字节大小,并且验证了可以表示越大范围的数据类型所占用的字节越多。

值得注意的是int和long均占用4个字节。这并未违反C语言标准,C语言标准规定高级别的类型取值范围不得小于低级别的类型,但是它们可以是一致的。


3. 三位二进制表示的数值范围


char,short,int,long,long long分别占用了1,2,4,4,8个字节。而每个字节由8个晶体管组成,每个晶体管状态我们称之为位。那么char,short,int,long,long long分别占用了8,16,32,32,64位。


太多的位不利于理解原理,暂时把问题简化一下,试试看位数减少到3。然后,分析3位的组

合,它能表示多大范围的数值.

晶体管状态 二进制数据 十进制数据
关关关 000 0
关关 001 1
010 2
开开 011 3
关关 100 4
101 5
开开 110 6
开开开 111 7


三位二进制组成的数据类型,可以表达2的3次方也就是8个数值。如果从0开始,那么可以表达从0到7的

数据范围。得出结论:如果不考虑负数,那么整型数据类型可以表达的数据范围是 假设,位数为n,则数据范围从【0】开始,到【2的n次方-1】的数值范围。


那负数怎么办?我们需要拿出一个位来作为符号位。用来表示这个数据是正数还是负数。在IEEE标准中,这个符号位存在于二进制的最高位。用三位二进制来示范这种情况。

晶体管状态 二进制数据 十进制数据
关关关 000 0
关关 001 1
010 2
开开 011 3
开关关 100 -4
开关 101 -3
110 -2
开开 111 -1


加上符号之后,现在取值范围变为负4到3了。红色字体的为最高位,最高位为1的表示负数。你可能会觉得有点奇怪,为什么3的二进制是011,而负3却是101呢?如果简单的加一个符号位,为什么不用111呢?那我们看看如图中所示的3与负3相加的运算结果。

1673451880225.jpg

会惊奇地发现,用101来表示负3与用011表示的正3相加。结果为1000,但是由于仅有3位二进制来保

存数据,最高位1被丢弃了。结果为000,居然得到了正确的结果0。


4.数值的补码表示法


1673451891616.jpg

时钟是一个圆被分成了12个点,让我们假设这个时钟一步只能走一个整点。那么这个时钟只有12种不同的模式,我们把12称之为时钟的模。


现在指针指向了5点,我们要让指针回到0点。一个办法是直接回退5个小时(5-5)。

另一个办法是继续往前走7个小时(5+7)。


在第二种办法中,5+7=12,而12刚好为时钟的模,时钟指向12的同时,也正好指向了0。

要让指针回到0点,只需要让它加上模与当前的时间的差即可。


因此,指针回退5小时与指针前进7小时是等价的。我们可以用指针前进来代替指针后退。


将这种思想带入到上面讨论的三位二进制当中。三位二进制能表示8中不同的模式,因此它的 模 为8。要让3回到0,我们可以让3减去3,也可以让3加上 模与3的差,即8-3=5。因此,我们可以把-3在三位二进制中用5的二进制101表示。


这种将用加法来等效减法的二进制表示法被称之为补码表示法。


正数的补码就是其二进制本身。

而正数对应的负数的补码为:(模 - 正数)的二进制。


000
0
001 1
010 2
负数 模减去正数 补码 011 3
-4 8-4=4 100 100 -4
-3 8-3=5 101 101 -3
-2 8-2=6 110 110 -2
-1 8-1=7 111 111 -1


补码表示法既通过最高位,区别了正数和负数。并且,巧妙地应用了溢出,所得到的计算结果也是正确的。类似于钟表仅需要向前走就可以实现减法,计算机的电路设计中,也只需要设计加法电路。极大地简化了计算机内部电路的复杂程度。

求一个正数对应的负数的补码的第二种办法:


先写出这个正数的二进制。

从二进制的右边开始,遇到第一个1之前,全都填0。

遇到第一个1之后,把1填下来。

1之后的全部取反。

从右往左:未遇到1填0,遇到1填1,然后全部取反

十进制 0 -1 -2 -3 -4
整数二进制 000 001 010 011 100
补码 000 111 110 101 100


5.各种整型类型的数值范围是多少

类型 sizeof大小 二进制位数 取值范围算式 取值范围
char 1 1×8 = 8位 -[2的7次方] ~ +[2的七次方 - 1] -128 ~ +127
short 2 2×8 = 16位 -[2的15次方] ~ +[2的15次方 - 1] -32,768 ~ +32,767
int 4 4×8 = 32位 -[2的31次方] ~ +[2的31次方 - 1] -2,147,483,648 ~ +2,147,483,647
long 4 4×8 = 32位 -[2的31次方] ~ +[2的31次方 - 1] -2,147,483,648 ~ +2,147,483,647
long long 8 8×8 = 64位 -[2的63次方] ~ +[2的63次方 - 1] -9,223,372,036,854,775,808 ~ +9,223,372,036,854,775,807


次方数比位数少一,是因为最高位被用去做符号位了。


6. 无符号整型


如果你确定你不会用到负数,那么请使用unsigned关键词。表明这个数据类型,是不带有符号位的。既然不带有符号位了,那么原本留给符号位的那一个二进制位,可以用来表示数值。

类型 sizeof大小 二进制位数 取值访问算式 取值范围
unsigned char 1 1×8 = 8位 0 ~ +[2的8次方 - 1] 0 ~ +255
unsigned short 2 2×8 = 16位 0 ~ +[2的16次方 - 1] 0 ~ +65,535
unsigned int 4 4×8 = 32位 0 ~ +[2的32次方 - 1] 0 ~ +4,294,967,295
unsigned long 4 4×8 = 32位 0 ~ +[2的32次方 - 1] 0 ~ +4,294,967,295
unsigned long long 8 8×8 = 64位 0 ~ +[2的64次方 - 1] 0 ~ +18,446,744,073,709,551,615


相关文章
|
18天前
|
存储 程序员 编译器
C 语言中的数据类型转换:连接不同数据世界的桥梁
C语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
|
18天前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
40 8
|
2月前
|
存储 C语言
【c语言】数据类型和变量
本文介绍了C语言中的数据类型和变量。数据类型分为内置类型和自定义类型,内置类型包括字符型、整型、浮点型等,每种类型有不同的内存大小和取值范围。变量分为全局变量和局部变量,它们在内存中的存储位置也有所不同,分别位于静态区和栈区。通过示例代码和图解,详细阐述了这些概念及其应用。
51 1
|
2月前
|
存储 C语言
C语言:设置地址为 0x67a9 的整型变量的值为 0xaa66
在C语言中,可以通过指针操作来实现对特定地址的访问和赋值。要将地址为 0x67a9 的整型变量值设为 0xaa66,可以先定义一个指向该地址的指针,并通过该指针对该内存位置进行赋值操作。需要注意的是,直接操作内存地址具有一定风险,必须确保地址合法且可写。代码示例应考虑字节序及内存对齐问题。
|
2月前
|
C语言
3.4 C语言基本数据类型2
在C语言中,声明一个整型(int)变量时,需先写入'int'关键字,后跟变量名并以分号结尾。若同时声明多个变量,可在'int'后用逗号分隔列出所有变量名。例如,`int erns;` 或 `int hogs, cows, goats;` 都是合法声明。变量声明后需通过赋值语句如 `cows = 112;` 或使用函数如 `scanf()` 来初始化其值。
47 10
|
2月前
|
存储 程序员 C语言
3.1 C语言基本数据类型
在C语言中,整数类型如`int`类型是很有用的,它属于有符号整型,意味着该类型的值必须是整数,并且可以是正整数、负整数或者零。`int`类型的数值范围依据计算机系统有所不同,通常取决于系统的位宽。例如,在早期16位的IBM PC兼容机上,`int`类型使用16位存储,取值范围为-32768至32767;而在当前32位系统中,使用32位存储,拥有更宽泛的取值范围。随着64位处理器的普及,`int`类型能够存储的整数范围将进一步扩大。根据ISO C标准,`int`类型的最小取值范围被规定为-32768到32767。系统通常会利用一个特殊的位来表示整数的正负。
43 10
|
2月前
|
C语言
3.1C语言基本数据类型
在C语言中,初始化变量是指为变量设定初始值,通常在声明时直接完成,例如 `int cows=32;`。应注意避免在同一语句中混合初始化与未初始化的变量,如 `int dogs, cats=94;` 这样的写法容易引起误解。此外,整型常量如21、32等在C语言中被视为int类型,但非常大的整数则不然,且带有小数点或指数的数值不属于整型常量。
34 9
|
2月前
|
存储 C语言
初识C语言:常量与变量中寻找数据类型
初识C语言:常量与变量中寻找数据类型
|
3月前
|
存储 C语言
【C语言基础考研向】02 数据类型-常量-变量
本文介绍了编程中的基本概念,包括数据类型分类、常量与变量的定义及使用。首先概述了四大类数据类型:基本类型(整型、浮点、字符型)、构造类型(数组、结构体)、指针类型和空类型。接着阐述了常量与变量的区别及命名规则,并详细说明了整型、浮点型和字符型数据的特点与应用。最后总结了常见的易错点,如字符串与字符常量的区别及浮点数的默认输出格式。
|
3月前
|
存储 C语言
【C语言基础考研向】04整型进制转换
本文介绍了计算机中整型常量的不同进制表示,包括二进制、八进制、十六进制和十进制,并解释了它们之间的转换方法。以一个32位整型数为例,展示了其在不同进制下的表示形式及计算方法,特别指出在内存观察中常用十六进制,同时提到了小端存储方式对数据的影响。