首先是我们所熟知的内置类型。
char //字符数据类型 1个字节
short //短整型 2个字节
int //整形 4个字节
long //长整型 4/8个字节 在C语言中没用明确规定long的大小,只说了long>=int
long long //长长整型 8个字节
float //单精度浮点数 4个字节
double //双精度浮点数 8个字节
那么我们所熟知的这些类型有什么意义?
1、使用这些类型开辟空间大小
2、如何看待内存空间的大小
类型的基本归类
整形家族:
char
signed char //有符号的char
unsigned char //无符号的char
short
signed short //有符号的short
unsigned short //无符号的short
int
signed int //有符号的int
unsigned int //无符号的int
long
signed long //有符号的long
unsigned long //无符号的long
long long
signed long long //有符号的long long
unsigned long long //无符号的long long
这里可能会有疑问,为什么char会归类到整形里面,这是因为在字符存储的时候,是以ASCII码值的形式存储在内存中的,而ASCII码值是整形,所以归类到整型中。
浮点数家族:
float
double
构造类型(自定义类型):
> 数组类型
> 结构体类型 struct
> 枚举类型 enum
> 联合类型 union
指针类型:
int* p
char* p
float* p
void* p
空类型:
void 表示空类型(无类型)
通常用于返回类型,函数参数,指针类型
这里我们先讲整型,当我们声明一个变量时,他是怎么存储的呢?
如果我们想要知道这些值是怎么存储的,我们还需要知道一些概念。。
原码、反码、补码
在计算机中的整数有三种二进制表达形式也就是原码、反码、补码。
这三种表达方式均有符号位和数值位两部份,在符号位,0表示正,1表示负。
符号位也就是将数值翻译成二进制后的最高位。
正数的原、反、补码都相同。
负数的三种表达方式都各不相同。
原码:直接将数值按照正负翻译成二进制就可以得到原码
反码:原码符号位不变,其它位按位取反得到反码
补码:将反码加一得到补码
这里我们所声明的是int类型,int所占4个字节也就是32个比特位。
按照原反补规则所翻译后的样子就是上图了。
那么为什么我们要算补码呢?在计算机中,数据一律使用补码来表示和存储,而原因就在于,使用补码可以将数值域和符号位统一处理;
同时呢加法和减法也可以统一处理,(cpu中其实只有加法)
这里我们查看内存取num的地址可看到num的值是0a 00 00 00,看到这里你可能觉得我说错了,这里明明是使用的十六进制表示,不是二进制,这里我先说明,我使用的是vs,而vs为了方便我们查看,就使用的十六进制表示,本质上我们计算机中还是使用的二进制表示的,所以这里的0a就是1010也就是10;
那么上面我还说了cpu中只有加法,那么减法,乘法这些是怎么实现的?
虽然我们的cpu中只有加法,但是我们可以模拟实现其他运算
比如减法:虽然我们是直接输入10-10,但是在计算机中却是10+(-10)
注意!在计算机中我们使用的是补码进行计算,其他的是错误的。
这下明白了吧。
不知道你们是否发现了,我们写出来的二进制序列转换成十六进制应该是00 00 00 0a,但是存放的时候却是倒放着存储的,这是为什么?
这里给大家介绍计算机数据的存储方式:
大端字节序存储: 数值的二进制高位存低地址,低位存高地址。
小端字节序存储 数值的二进制高位存高地址,低位存低地址。
那么为什么会有顺序之分呢?在我们的计算机中,我们是以字节为单位,当我们的数据大小超过一个字节的时候,就会有顺序之分。
那么我们要怎么来查看我们电脑是那种存储方式?
大小端存储的方式无非就是位置颠倒,那么我们可以查看首尾地址的值来判断。
我们声明变量int a=1;取其地址然后将其强制转换成char*
这时候我们就可以一个字节一个字节的访问了。
这里我们来扩展一下,来看看符号对程序的影响。
先看一下,然后思考,输出结果是什么——————————————————答案是-1 -1 255
在a中,我们声明的是一个char类型的变量,但是我们想要放入一个整形,所以会发生什么?
a:
原码:10000000000000000000000000000001
反码:11111111111111111111111111111110
补码:11111111111111111111111111111111
但是char类型只能放一个字节,怎么办?——截断
我们只放后8个比特位,也就是11111111
那么为什么c是255呢?
注意!我所使用的是十进制打印,所以这里会发生整型提升
也就是按符号补全,正数补0,负数补1.
c:
原码:10000000000000000000000000000001
反码:11111111111111111111111111111110
补码:11111111111111111111111111111111
截断:11111111
整型提升:00000000000000000000000011111111
! signed表示有符号我们声明变量时默认是signed,整型提升时按符号位全。
! unsigned表示无符号,也就是永久大于0,不会为负,整型提升时补0
好了,就先讲到整型,下次继续