C语言——数据的存储

发布于:2022-12-02 ⋅ 阅读:(396) ⋅ 点赞:(0)

一.数据类型

        基本类型

        打印类型

所占大小(字节)

char         字符型

       %c

    1

short        短整型

       %d  

    2

int           整形

       %d         

    4

long        长整形

       %ld  

    4

long long 更长整形 

       %lld        

    8

float      单精度浮点型

        %f             

    4

double 双精度浮点型

       %lf   

    8

类型的意义:

  1. 使用这个类型开辟内存空间的大小(大小决定了使用范围)。
  2. 如何看待内存空间的视角。

简单归类:

整型家族
char
//(直接使用char类型,不确定它是unsigned还是signed,取决于编译器,一般为signed型)
//char存储的时候,存的是它的ASCII码值,也是个整数,故归于整形家族
  unsigned char
  signed char

short(signed short)
  unsigned short [int]
  signed short [int]

int(signed int)
  unsigned int
  signed int

long(signed long)
  unsigned long [int]
  signed long [int]

浮点型家族
  float  单精度浮点型
  double  双精度浮点型

构造类型-自定义类型
  > 数组类型
  > 结构体类型 struct
  > 枚举类型 enum
  > 联合类型 union

 
指针类型
  int *pi;
  char *pc;
  float* pf;
  void* pv;

空类型
  void
  void 表示空类型(无类型)
(用于函数的返回类型、函数的参数、指针类型)

二.整形在内存中的存储

(补码在内存中是倒序存储)

整数在内存中存储形式之前讲过,在此就不多说

图中的是十六进制形式,4个二进制位换一个十六进制位

a的补码的十六进制形式为FFFFFFF6

注意:对于整形:

   1.数据存放的是补码

   2.整形表达式计算是用补码计算的

   3.打印出的是原码

例子:

#include<stdio.h>
int main()
{
  char a = -1
  //由于char是1个字节
  //所以是11111111 存储到a中
  signed char b = -1;
  //11111111
  unsigned char c = -1;
  //11111111
  printf("a=%d,b=%d,c=%d", a, b, c);//a=-1,b=-1,c=255
  //打印的是%d,会整型提升
  //整形提升看的是原符号位
  //a由于是char所以按符号位来提升
  //a:1111111111111111111111111111111 内存中补码
  //以%d打印的时候看的是其原码,所以为10000000000000000000000000000001
  //a与b类似
  //有符号整型提升的时候会把符号位当作最高位
  //a b:1000 0000 0000 0000 0000 0000 0000 0001 -1的原码
  //c:无符号整型提升后面补0
  //c:00000000000000000000000011111111-->无符号c的补码
  //c:00000000000000000000000011111111-->无符号c的原码
  return 0;
}

1.*****

%u是打印无符号整型,%d是打印有符号整型

#include <stdio.h>
int main()
{
  char a = -128;
  //a的补码 :1111 1111 1111 1111 1111 1111 1000 0000
  //截断后为:1000 0000
  //由于是%u打印,发生整形提升,又为有符号char,高位补1
  //提升后内存中放的是补码,且是无符号数补码,高位不是符号数,其补码,原码相同---> 1111 1111 1111 
   1111 1111 1111 1000 0000
  printf("%u\n", a);//4294967168//当为%d是结果为-128
  return 0;
}

2.char的取值范围

   a:有符号的char的取值范围:-128~127

127为最大值,加1不会变成128,而会是-128

   

b:无符号的char的取值范围0~255

(无符号整形减为0时还能再减,但不会减成负数,而是到无符号最大数,像个循环。而无符号最大数加1变成0)

例子:


#include<stdio.h>
int main()
{
  unsigned int i;//无符号说明i值都不为负数
  for (i = 9; i >= 0; i--)//恒成立
  {
    printf("%u\n", i);//当为%d是会认为内存中储存的是一个有符号的数字
  }
  return 0;
}

三.大小端字节序介绍及判断

大端(存储)模式,是指数据的低位存放在内存的高地址中,而数据的高位存放在内存的低地址中;

小端(存储)模式,是指数据的低位存放在内存的低地址中,而数据的高位存放在内存的高地址中。

  注意:存储中靠右的是低地址,靠左是高地址

           在0x11223344中44是低地址

#include<stdio.h>
int main()
{
  int a = 0x11223344;
  return 0;
}
 //a: 11 22 33 44 将其存到内存中可分为两种:

 //1: 低 11 22 33 44 高 --->大端字节序
 //2: 低 44 33 22 11 高 --->小端字节序

例题:判断当前机器的字节序

//可以通过获取第一个字节来判断
#include<stdio.h>
int main()
{
  int a = 1;
  char* p = (char*)&a;
  if (*p == 1)
    printf("小端\n");
  else
    printf("大端\n");
  return 0;
}


 
//函数法
#include<stdio.h>
int check_sys()
{
  int a = 1;
  //0000 0000 0000 0000 0000 0000 0000 0001
  //大端存储:0x 00 00 00 01 解引用->0
  //小端存储:0x 01 00 00 00 解引用->1
  return (*(char*)&a);
  //&a取出a的地址,然后把这个int*类型的地址转化为char*,最后解引用
  //为大端存储,返回0;小端存储,返回1
}

int main()
{
  int ret = check_sys();
  if (ret == 1)
     printf("小端\n");
  else
     printf("大端\n");
  return 0;
}

四.浮点型在内存中的存储

浮点数家族:float 、double 、long double类型

#include<stdio.h>
int main()
{
int n = 9;
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);//9
printf("*pFloat的值为:%f\n", *pFloat);//0.000000
//当以*pFloat是以 浮点数 的视角考的,以%f打印

*pFloat = 9.0;
printf("num的值为:%d\n", n);//1091567616
//以浮点型放进去,以整数视角拿的

//说明浮点数和整数在内存中存储方式是有区别的

printf("*pFloat的值为:%f\n", *pFloat);//9.000000
return 0;
}

任意一个二进制浮点数V的存储形式规则(-1)^S*M*2^E

     (-1)^S表示符号位,当S=0时,V为整数,当S=1时,V为负数

      M表示有效数字,1<=M<2

      2^E表示指数位

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到