数据类型介绍:

int                        //整型 占4个字节

short                    //短整型  占两个字节

long                  //长整型 占4个字节(vs2022中的数据)c语言标准中规定:

long long             //更长的整型 占8个字节         sizeof(long)>=sizeof(int)

char                     //字符数据类型 占1个字节

float                     //单精度浮点数 占4个字节

double                 //双精度浮点数  占8个字节

数据类型的意义:

1.使用这个类型开辟内存空间大小(大小决定使用范围

2.如何去看待空间的视角(同样是4个字节,里面储存的是浮点数还是整数)

整型家族有:

char                                     char在储存的时候储存的是ASCll码值,ASCll码

       unsigned char         是整数,所以归类的时候,字符属于整型家族。    

       signed char

short

        unsigned short [int]        short int num=0与short num=0 等价,int  

        signed short [int]         可以省略。short num=0与signed short num

int                                        等价。int和long类似。但char 是 signed char

    unsigned int                     还是unsigned char取决于编译器,常见的编译

    signed int                         器中char == signed char.

long 

      unsigned long

      signed long

浮点数家族有:

        float

        double

构造类型(自定义类型):

数组类型       //数组类型为啥是自定义呢?  我们会根据需要改变数组的元素个数,这个时候方括号中的数值也随之改变,类型也就发生了改变。举个列子:int arr[10]的类型为int [10],而int arr[11]的类型则为int [11]

结构体类型 struct     

枚举类型 enum         

联合类型 union          


空类型:

void表示空类型

通常用于函数的返回类型、函数的参数、指针类型。


void add()     表示该函数无返回值

{}

void add(void)      表示该函数不需要参数,不用给它传

{}

void *p            表示无类型指针

{}

对于整型来说,数据存放内存中其实存放的是补码

为什么储存补码呢?

           使用补码,可以将符号位和数值域统一的处理,同时,加法和减法也可以统一处理(CPU只有加法器),此外,补码和原码的相互转换,其运算过程是相同的,不需要额外的硬件电路

正数   原码(直接按照该数值翻译成二进制形式就得到了原码)反码补码相同

负数    反码: 原码除符号位以外,其他位次按位取反得到反码

          补码:反码+1

举个例子:

int a=-10

int b=20

//-10

//10000000000000000000000000001010 -原码

//11111111111111111111111111110101 -反码

//11111111 11111111 11111111 11110110 -补码

//0xff ff ff f6

//20

//00000000000000000000000000010100 -原码

//00000000000000000000000000010100 -反码

//00000000 00000000 00000000 00010100 -补码

//0x00 00 00 14

利用原反码进行计算的一个过程:

 char a=-1

signed char b=-1

unsigned char c=-1

printf("a=%d b=%d c=%d",a,b,c);

答案是 ;你写对了吗?让我们分析一下它的一个过程;

//-1是整数

//10000000000000000000000000000001-原码

//11111111111111111111111111111110-反码

//11111111111111111111111111111111-补码


由于char a只有8个比特位,所以截取后八位存入

//11111111-a

//%d打印的是有符号的整数,但a不是,所以我们要提升(高位按符号位的数字来补够32位,无符号则以0补)成整数

//a有符号位,符号位为1,所以提升后为

//11111111111111111111111111111111-提升的补码

//10000000000000000000000000000001-还原得到的原码(输出的时候需要补码还原成原码进行输出)

最终输出a=-1,b也是同样的同样的,所以b=-1;

//11111111-c(c储存时的补码同a)

//00000000000000000000000011111111-提升

//00000000000000000000000011111111-原码(正数的原反码相同)

//最终c=255



负数的补码还原成原码可以有两种方式:

            第一种是直接取反(符号位除外)+1;

            第二种则是先减一,再取反;


大端小端储存是什么呢?

              大端储存:

                        把一个数据高字节的内容放到低地址,把低字节内容放到高地址。

举个例子:

         0x1234            低------------>高

                               12 34 00 00

                小端储存:

                        把一个数据低字节的内容放到低地址,把高字节内容放到高地址。

同样举个例子:

         0x1234            低------------>高

                               00 00 34 12

我可以设计一个简单的程序去检测是大端储存还是小端储存,参考代码如下下:


#include<stdio.h>
int main()
{
  int a=1;
  char *p=(char*)&a;
  if(*p==1)
    printf("小端");
  else
    printf("大端");
}

浮点数在内存中的储存方式是否于整型相同呢?

         答案是否定的。

在国际标准IEEE754,任意一个二进制浮点数v都可以表示成以下面的形式:

   1.(-1)^S*M*2^E

   2.(-1)^S表示符号位,当S=1时,v为负数,当S=0时,v为正数。

   3.M表示有效数字,大于1,小于2.

   4.2^E表示指数位

以十进制5.0举个例子:

       十进制5.0转换成二进制为101.0=1.01X2^2(可以类比十进制数15=1.5X10^1),那么以上浮点数v的形式S=0,M=1.01,E=2.

IEEE754规定:

E是一个无符号整数,对于8位的E范围0~255,对于11位的E范围0~2047,由于科学计数法中会出现负数,所以储存时真实值要加上一个中间数,对8位的E,这个中间数是127,对于11位的E,这个中间数位1023.

对于32位的浮点数,最高的一位是符号位S,接着的8位是指数E,剩下的23位是有效数字M。

对于62位的浮点数,最高的一位是符号位S,接着的11位是指数E,,剩下的52位是有效数字M。

对于E和M还有一些特殊的规定:

       IEEE规定,计算机内部保存M时,默认第一位是总是1,因此可以省去,只保存小数点后面的数值。比如1.01,省略1只保存小数点后面的01

E取出的三种情况:

    E不全为1也不全为0

            这时,浮点数的指数E的计算值减去127,得到真实值,然后再将有效数字M前面加上第一位1.

     E全为0

           这时,浮点数的指数E=1-127(或1-1023)即为真实值.

           有效数字M不再加上第一位1,而是还原成0.xxxxx的小数,这样做为了表示土0,以及接近于0很小的数。

     E全为1

           这时,有效数字M全为0,表示土无穷大(正负号取决于符号位S)