C语言初步认识-不同数据类型的存储方式(1)

C语言中常见数据类型及其存储方式

认识前的说明(必看):

        在说存不同数据类型储方式之前我们首先来说说计算机的分类:

        大体上计算机现在分为32位和64位计算机(当然现在大多数都是64位),那么32位和64位是什么意思呢?

        如果在百度百科的中我们去查32位操作系统针对的32位的CPU设计。CPU内部寄存器和寻址总线是32位,指令集可以运行32位数据指令,也就是说一次可以提取32位数据(4个字节,32bit=4Byte)。32位CPU有4G的内存寻址空间
64位操作系统是指特别为64位架构计算机系统而设计的操作系统,在计算机架构中,64位整数、内存地址或其他数据单元,是指它们最高达到64位(8字节)宽。此外,64位CPU和算术逻辑单元架构是以寄存器、内存总线或者数据总线的大小为基准。64 位CPU在1960年代,便已存在于超级计算机,且早在1990年代,就有以 RISC 为基础的工作站和服务器。2003年才以 x86-64 和 64 位 PowerPC 处理器架构的形式引入到(在此之前是 32 位)个人计算机领域的主流。

        可能回答的有点官方(当然是我个人这么觉得)。我个人觉得的:32位和64位可以这么理解会好一点:

        我们计算机中有地址线,可以想成一根一根的,32位机器就有32根地址线,64位机器就有64根地址线,类似于图一(32位)。由于计算机只能处理二进制,所以每根地址线上只能输入0或者1,类似于如图二,我们由此可以知道,对于32根地址线来说应该有2^{32}种可能(也就是从32个全0,一直到32个全1)(如果大家排列搞不清楚,可以在纸上试试看),也就是对于32位计算机来说,可以生成2^{32}个地址以供使用,每个地址都是32位由0和1组成的编号。

     

图一
图二

   每个可以使用的地址可以存放一个字节(byte)大小的数据,那一个字节是多大呢?

这里有一个大小关系需要说明一下:

1字节(byte) = 8比特(bit)

1KB = 1024字节(byte)

1MB = 1024KB

1GB = 1024MB

1T = 1024GB

       也就是说一个地址可以存放8比特大小的数据,那门问题又来了,8比特究竟是多大呢?

这又涉及到数据是怎么存放在地址中的呢?拿最简单数字来说,比如你输入8,8是10进制数字,要让计算机去存它,就要将其转换为2进制数字就会变为1000(具体二进制转换等我会在下一章详细去说明),只转换为1000还不行,对于32位和64位计算机,都是将10进制数字转换为2进制,刚刚1000相当于是4位2进制,那么转换为32位也很简单就变成00000000000000000000000000001000。

        此时转换出来的二进制一共有32位,每一位就算是一个比特位。

        这就是比特位的大小,那知道了这个,接下来继续来说计算机一个地址能够存一个字节大小的数据,对于32位机器来说,一共能产生2^{32}个地址,也就是一功能存放2^{32}个字节大小的数据,

这里就可以转换一下2^{32}字节转换成GB,那等于多少个GB呢?

大家可以自己算算!

2^{32}byte = 2^{32}/1024 = 2^{32}/2^{10} = 2^{22}KB

2^{22}KB = 2^{22}/1024 = 2^{22}/2^{10} = 2^{12}MB

2^{12}MB = 2^{12}/1024 = 2^{12}/2^{10} = 4GB

也就是说32为计算机可以一次处理4GB的数据,当然64位计算机的话就可以处理8GB的数据(大家可以下去自己算一算)

一、整形

1、int型

        int型变量,也就是整形变量在内存中占多大空间,我们可以用sizeof()关键字测试一下,发现运行结果为4,单位呢是字节,也就是说整型变量在内存中存储占4个字节大小,也就是需要4个地址来存储它(前面已经说明地址和存储的关系),那具体是怎么存的呢,我是在VS 中可以找到内存的存储图,,计算机在这显示的是16进制数字,前面的0x003EFC5CS是地址,000000a0是16进制,相当于10进制的数字10(关于进制的说明和转换我会在下一章中说明),下一个地址0X003EFC60是下一个数据的,所以可以看出,从0X003EFC5C到0X003EFC60相差4个地址,也就是说一个整形的存储需要4个字节的大小,也就是需要4个地址去存储。

       

#include<stdio.h>
int main()
{
	int a = 10;
	printf("%d\n", sizeof(int));
	return 0;
}

int型变量可存放的最大最小值

         那么问题又来了,一个整型数据到底最大是多少,前面说过,计算机存放的32个2进制数据进去,所以最大能存放32个全一进去,那32个全1,转换为10进制是多少呢?

        这里我给大家算算。这里给出32个全1,转换为10进制是DEC = 4294967295,最大时这个数,那我们可以把这个是用机算计存起来,并且打印出来看看。

#include<stdio.h>
int main()
{
    int a = 4294967295;
	printf("%d\n", a);
	return 0;
}

        哎,奇了怪了,打印出来为什么是-1。此时出现了问题。经过多次尝试与查找,原来计算机存整形数据是,一共有32位,把最高位一般是作为符号位去处理了,最高位如果是1则为负数,第一位若为0,则为正数,那问题又来了,如果最高位为1那为负数,那应该打印的是-2147483647,就是不算后面的值加上负号,那为什么打印的是-1,这个问题涉及到负数和正数在内存中的存储,我会放在下一章去讲。

        但是我如果把第一位不要当作符号位,那应该打印的是正确结果。那我们如何去做:

只需要在该整形前面加上(unsigned)是无符号的意思,然后我们用%u去打印。

#include<stdio.h>
int main()
{
    unsigned int a = 4294967295;
	printf("%u\n", a);
	return 0;
}

打印结果确实为4294967295.

        综上,我们总结一下,如果不加unsigned编译器会默认为有符号去做,所以所int型变量的范围是-2147483648 ~ +2147483647也就是只用31位可以使用。

2、long int型(长整型)

通过讲解int型变量,一下大家其实都可以以此类推出来

    取值范围:-2147483648 ~ +2147483647,也可以存4个字节大小的数据。

#include<stdio.h>
int main()
{
	long int a = 10;
	printf("%d\n", sizeof(long int));
	return 0;
}

3、long long int型(长长整形)

        取值范围:9223372036854775807~-9223372036854775808,它的大小是8字节,也就是64个比特位,也就是在计算机中最多可以存放61位数据,第一位同样也为符号位。61个全1结果为9223372036854775807

#include<stdio.h>
int main()
{
	long int a = 10;
	printf("%d\n", sizeof(long long int));
	return 0;
}

4、short int型(短整型)

        大小为2个字节,也就是16个比特位,所以它的取值范围是32767~-32768,也就是15个全1。

#include<stdio.h>
int main()
{
	long int a = 10;
	printf("%d\n", sizeof(short int));
	return 0;
}

二、浮点型

        刚刚介绍了整型在内存中的存储,那如果这个数是个小数,我们应该怎样存储,接下来我们就来探讨探讨。

1、单精度浮点型

        单精度浮点型即float类型。首先我们可以来观察一下它的大小:

#include<stdio.h>
int main()
{
    float a =3.14 ;
	printf("%d\n", sizeof(float));
	return 0;
}

        打印结果为4,说明它的存储大小是4个字节。接下来让我们打印一下这个数(注意在打印float类型时,我们用%f去打印

int main()
{
    float a =3.14 ;
	printf("%f\n", a);
	return 0;
}

        其中最高位为符号位,紧接着8位为指数位,剩下的23位为尾数位(具体是怎么实现的我会在下一章节说明)。

2、双精度浮点型

        即double类型,双精度相较于单精度更加精确,它的大小8个字节大小。

        打印3.14看看有什么不同。

#include<stdio.h>
int main()
{
    double a =3.14;
	printf("%lf\n", a);
	return 0;
}

结果发现还是只是精确到了小数点后六位,为什么呢?

double确实是可以存储8字节大小的,按理说精确度应该比float高,但是计算机默认只打印到小数点后六位,这是计算机默认的,但是如果我们就像让其精确到后8位后10位我们可以在lf前面加.m

(m为想打印小数点后几位),比如这样,我想打打印后8位,我可以用%.8lf打印,结果如下:

最高位为符号位,紧接着8位为指数位,剩下的52位为尾数位。

三、字符型

        上述的数据类型都是和数字有关,可是我这会想要存一个字符,比如*、%、#、!等等的一些字符,此时我们用变量char去存储想要打印的字符。

1、字符在内存中存储

        首先我们可以还是先来看一下char类型的变量占多大内存:

#include<stdio.h>
int main()
{

printf("%d\n",sizeof(char));
return 0;
}

        运行结果为1个字节,也就是8个比特位大小,那么这8个比特位存的是什么呢,不用说肯定是0或者是1,所以由此可以推断出,一个字符肯定是和一个数字有关系,因为计算机之呢个存0或者1,此时引出一个ASCIIAscii完整码表(256个)_ascii码表-CSDN博客码表,该表上的每一个字符都对应着一个字符(由于我比较懒,稍微偷个懒大家可以点进链接去看其他up整理的)。

        这个表上每一个字符都对应的一个ASCII值,电脑中存的就是这个值。当然我也可以用%d京不同字符的ASCII值打印一下,比如我想要知道‘!’的ASCII值,我可以用如下代码。

#include<stdio.h>
int main()
{
	char a = '!';
	printf("%d\n",a);
	return 0;
}

        当然如果想输入33然后输出对应的字符也可以做到,就是先把33存在int整形变量里面,然后用%c去打印出来。代码如下:

#include<stdio.h>
int main()
{
	int a = 33;
	printf("%c\n", a);
}

        

        结果如上,大家也可以试试。

        至于其他类型竟会在下章继续分享,大家也可以想想如果是字符串例如“abcdef”该怎么存储!!

        当然如果是有什么说得不对的,大家也可以多多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值