首页 > 其他分享 >C语言中的整型数据类型(你真的了解吗)

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

时间:2023-01-19 10:05:22浏览次数:48  
标签:字节 二进制 关关 数据类型 long C语言 int 整型 sizeof


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​​后面既可以跟 类型,也可以跟 变量、常量。

  1. 类型,测类型所占用字节的大小。
  2. 变量,测变量的类型所占用字节大小。
  3. 常量,测常量的类型所占用字节大小。

三种情况的示例代码。

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));

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


结果: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相加的运算结果。

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

会惊奇地发现,用101来表示负3与用011表示的正3相加。结果为1000,但是由于仅有3位二进制来保
存数据,最高位1被丢弃了。结果为000,居然得到了正确的结果0。

4.数值的补码表示法

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

时钟是一个圆被分成了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. 先写出这个正数的二进制。
  2. 从二进制的右边开始,遇到第一个1之前,全都填0。
  3. 遇到第一个1之后,把1填下来。
  4. 1之后的全部取反。

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

十进制0-1-2-3-4整数二进制000001010011100补码000111110101100

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


标签:字节,二进制,关关,数据类型,long,C语言,int,整型,sizeof
From: https://blog.51cto.com/u_14452299/6019779

相关文章

  • 第一个C语言程序(从Hello World开始)
    程序员之间有一个约定俗成的习惯,我们在学习任何编程语言时,所写的第一个程序,就是在显示屏上打印一行字符​​“HelloWorld”​​。这个习惯出自哪里呢,首先回顾C语言的历史,就......
  • 浅谈Redis基本数据类型底层编码(含C源码)
    文章目录​​一、String​​​​1、int​​​​2、embstr​​​​3、raw​​​​4、bitmap​​​​5、hyperloglog​​​​二、List​​​​1、ziplist​​​​2、quicklist......
  • C语言基础--函数
    目录一、什么是函数二、函数的创建三、函数的使用四、返回值的使用五、什么是形参和实参六、默认值形参七、函数的递归一、什么是函数编程中的函数是将一些需要复用的代......
  • C语言基础--数组详细说明
    目录一.什么是数组二、一维数组1.一维数组创建2.一维数组的使用2.1索引值2.2遍历数组2.3如何使用sizeof()计算出数组的长度三、二维数组1.二维数组的创建2.二维数组的使......
  • C语言高校实验室预约登记系统[2023-01-18]
    C语言高校实验室预约登记系统[2023-01-18]23、高校实验室预约登记系统功能:(1)显示实验室能够提供的实验名称、编号、实验内容、实验联系人等信息;(2)管理员能够对系统中各实......
  • C语言《高级语言程序设计课程设计》[2023-01-18]
    C语言《高级语言程序设计课程设计》[2023-01-18]2022级3班高级语言程序设计课程设计说明书一、设计任务与要求《高级语言程序设计课程设计》是在完成《高级语言程序设计......
  • [Code-Palace] 各种数据类型在当前系统的存储
    #include<stdio.h>#include<stdlib.h>#include<float.h>#include<limits.h>intmain(){printf("Smallestchar:%hhd\n",CHAR_MIN);printf("Biggest......
  • [Code-Palace] 各种数据类型的二进制表示
    生成的二进制码被保存在"data.exe"文件请用VSCode中的HexEditor或其他二进制编辑器查看#include<stdio.h>#include<stdlib.h>voidchar_out();voidunsigned_c......
  • C语言:哥德巴赫猜想例子
      #include<stdio.h>intzs(intn){inta;for(a=2;a<n;a++)if(n%a==0)return0;return1;}main(){inta,b,c=0;scanf("%d",&a......
  • 数据类型的转换
    #数据类型转换#万物皆可转字符串,字符串要想转成数字必须确保字符串里面的内容均是数字才行x=6int(x)#将数字类型转换成字符串num_str=str(11)print(type(num......