189 8069 5689

【C语言进阶】数据存储-创新互联

数据类型分类 整形家族

字符在存储时,以ascii码值形式存储,因此归类时字符属于整形家族

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站制作、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的辽中网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴! 浮点数家族

1、float double

2、构造类型(指定义类型)

数组 结构体 枚举 联合体4

ps:int arr[10]类型为int[10] 而int arr[20]类型为 int[20]

char ch[10]类型为 char[10]

数组的元素个数和元素类型在变化时数组类型在发生变化

指针类型

int* char* float*

空类型

void

主要包括三种情况:

1.函数返回类型 void test()

2.函数参数 void test(void)

3.指针类型 void* p;->无具体类型的指针

整形的存储 1、包括符号位和数值位(占1位)

[1]符号位0表示正 1表示负

[2]数值位(整形占31位)

4个二进制位可转化为1个十六进制位【前缀 0x】

eg:二进制1001 0000 0010 0001 1010 0010 0000 1000
转化为16进制为 0x90 21 a2 08
2、存储形式:以补码的形式存储

[1]正数 正数的原码,反码,补码相同

[2]负数 int b=-10;

原码10000000000000000000000000001010

反码111111111111111111111111111111110101 符号位不变其他位按位取反

补码111111111111 11111111 111111110110 =反码+1

0xFF FF FF F6

为什么要用补码存储负数?

1.因为CPU中只有加法计数器,没有减法计数器,用补码形式方便计算

而当我们在用负数的原码计算会出现问题,因此负数应先转化为补码形式再计算

int a=1; int b=-1; int c=a+b;
a 00000000000000000000000000000001
b 11111111111111111111111111111111补码
c 000000000000000000000000000000000
当c变为33位,发生整形截断高位为0为正数,原码反码补码相同,c=0

2.原码与反码的转换形式是一样的,比较方便处理

3.signed与unsigned统一用补码处理,便于符号位与数值位统一处理

大小端(负数按照补码的字节序存储)

1、大端存储(大端字节序存储)以字节为单位存储

按顺序存储(从高位到低位)把高位放在低地址,低位放在高地址

2、小端存储(小端字节序存储)

数据倒放(从低位到高位)把高位放在高地址,低位放在低地址

而x86操作系统通常是小端

来看一道金典题目:写一段程序判断大小端

基本思路:定义变量a,再通过char类型指针取出一个字节的数据,通过结果判断是大端存储还是小端存储

代码实现:

int main()
{
int a = 1;
char* p = (char*)&a;
if (*p == 1)
printf("是小端存储");
else
printf("是大端存储");
return 0;
}

用一个函数实现:

int check_sys(int* ch)
{

if (*((char*)ch) == 4)
return 1;
else
return 0;

}
int main()
{
int a = 4;
int ret = check_sys(&a);
if (ret == 1)
printf("是小端存储\n");
else
printf("是大端存储\n");
return 0;
}
整形提升

%d 打印有符号整数

有符号 正数补0 负数补1 前边按符号位补齐

无符号 补0

char类型第一位是符号位嘛?

char类型最高位为符号位

计算机在进行相应的二进制计算的时候,signed和unsigned相加转换成unsigned算

练习:

【1】

int main()
{
char a = -1;
//-1是整数
//原码:10000000000000000000000000000001
//反码:11111111111111111111111111111110
//补码:11111111111111111111111111111111
//由于a是char类型,发生截断11111111
//%d是打印有符号整数,因此整形提升变为
// 11111111111111111111111111111111
//符号位为1是负数转化为原码为
// 10000000000000000000000000000001
//a=-1,b=-1
//而c为无符号数字,发生整形提升时变为
// 00000000000000000000000011111111
//符号位为0,是正数,原码反码补码相同
//因此c=255
signed char b = -1;
unsigned char c = -1;
printf("%d %d %d", a, b, c);
return 0;
}

【2】

int main()
{
    unsigned int;
    for(int i=9;i>=0;i--)//条件恒成立
    {
        printf("%d\n",i);            
    }
    return 0;
}

【3】

int main()
{
char a[1000];
int i;
for (i = 0; i< 1000; i++)
{
a[i] = -1 - i;
}
printf("%d", strlen(a));//遇到\0停止
return 0;
}
//根据圆环可知,i=-1 -2 -3 -4 ... -128 127 126 ... 2 1 0 -1
//'\0'之前一共有255个数字

【4】

int main()
{
unsigned char i = 0;//unsigned char的取值范围:0-255
for (i = 0; i<= 255; i++)//条件恒成立,陷入死循环
{
printf("hello world\n");
}
return 0;
}
浮点型在内存中的存储 1、浮点数表示

整形取值范围:limits.h查看

浮点型取值范围:float.h查看

在电脑文件中可以查看

根据IEEE 754标准:

  • 任意的浮点数V=(-1)^S*M*2^E

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

  • M为有效数字(1<=M<2)

  • 2^E表示指数位

2、在内存中存储形式

对于32位浮点数存储形式:

    • 注意:

1、M为1.xxxxxx的形式,而M存储时只存储小数点后面的数据

2、E为无符号整数,如果E为8位,取值范围为0-255,如果E为11位,取值范围为0-2047可以出现负数。但根据IEEE 754标准,必须在真实值基础上加上一个中间数,如果E为8位+127,如果E为11位+1023

指数E取出时分为3种情况:

【1】E不全为0或1: E为8位-127,E为11位-1023

【2】E为全0:表示指数部分为1-127(1-1023),为一个接近于0的数字,还原时为0.xxxxxxxx的小数,不需要加上第一位的1

【3】E全为1:表示指数部 分为128,为一个接近无穷的数字,表示+-∞

举例:

int main()
{
int n = 9;
float* m = (float*)&n;
printf("*m=%f,n=%d\n",*m, n);//0 9
*m = 9.0;
printf("*m=%f,n=%d\n", *m, n);//9.0 1091567616
return 0;
}


总结:
  1. 整型与浮点型数据在内存中存储形式不同,在对不同类型数据操作时需要谨慎

  1. 在数据由不同形式转化时,可能涉及整形提升与截断

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享名称:【C语言进阶】数据存储-创新互联
网站网址:http://cdxtjz.cn/article/cshodh.html

其他资讯