C语言学习分享/数据的存储

本文介绍了C语言中数据的存储方式,包括整型的大小端存储模式及其判断方法,以及浮点型的存储规则。讨论了不同数据类型的存储细节,如指针加减和整型提升,并通过实例解释了不同数据类型的表示和打印差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define _CRT_SECURE_NO_WARNINGS 1


**整形存储**

#include <stdio.h>
int main()
{
    int a = 10;
    int b = -10;
    return 0;
}


调试,打开内存输入&a,地址后面的内容为00 00 00 0a;此时为十六进制;

大端(存储)模式:数据低位存到内存高地址中,数据高位存低地址中;(数据与内存相同顺序摆放)
小端(存储)模式:数据低位存到内存低地址中,数据高位存高地址中;

数据高地址--如0x11 22 33 44中11为数据高位;内存高地址--右为高位,从左到右增高

设计程序判断当前机器的字节序(大小端) 
 

#include <stdio.h>
int main()
{
    int a = 1;
    char* p = (char*)&a;     //(char*)&a--强制选取(不改变)a的地址的第一个字节(最左边的字节)
    printf("%d\n",*p);
    if (*p == 1)            //*p--根据地址找到对应的对象  
    {
        printf("小端存储");
    }
    else
    {
        printf("大端存储");
    }
    
        return 0;
}


 
指针类型的意义
1.决定了指针解引用操作符能访问几个字节
2.决定了指针+1,-1加减几个字节

#include <stdio.h>
int main()
{
    int a = 0x11223344;
    int b = 0x11223344;
    int* pa = &a;
    *pa = 0;
    char* pb = (char*)&b;
    *pb = 0;
        return 0;
}


查内存&a为00000000 b为00332211

#include <stdio.h>
int main()
{
    char a = -1;
    signed char b = -1;
    unsigned char c = -1;
    printf("a=%d b=%d c=%d",a,b,c);
    return 0;
}


输出结果为-1 -1 255
-1的整形提升后的原码--10000000000000000000000000000001
                反码--11111111111111111111111111111110
                补码--11111111111111111111111111111111
                 a,b,c定义的是char,只能存1字节,发生截断后存入补码
a,b,c--11111111 -- 补码
当要打印时%d是整形,发生整型提升再到回原码打印
char含有符号位,高位为1补1--11111111111111111111111111111111-补码
signed char,与char相同
unsigned char不含有符号位高位补0--00000000000000000000000011111111--补码
                                                  正数原反补相同--c为255

#include <stdio.h>
int main()
{
    char a = -128;
    printf("%d\n", a);
    printf("%u",a);   //%u打印十进制的无符号数字 %d打印十进制的有符号数字 
    return 0;
}


-128--100000000000000000000000010000000
    --111111111111111111111111101111111
    --111111111111111111111111110000000 补码
    打印 a-10000000
整型提升 111111111111111111111111111000000 补码
%u无符号打印,把上个补码当成无符号数,返回原码
打印 111111111111111111111111111000000(4294967168)

有符号char范围为-128~127   --char,signed char
00000000--0(补码)正数原反补相同
00000001--1
...
01111111--127
10000000--规定此补码对应原码为 -128
10000001-- 10000000(反)--11111111(原)-- -127
...
11111111--11111110--10000001-- -1
 
无符号char范围为0~255  --unsigned char
00000000--0
...
11111111--225

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


128--00000000000000000000000010000000
   --00000000000000000000000010000000
   --00000000000000000000000010000000
10000000
%d-- 11111111111111111111111110000000
     11111111111111111111111101111111
     10000000000000000000000010000000-- -128
%u-- 00000000000000000000000010000000
     00000000000000000000000001111111
     11111111111111111111111110000000-- 4294967168

#include <stdio.h>
#include <string.h>

int main()
{
    char a[1000];
    int i = 0;
    for (i = 0; i < 1000; i++)
    {
        a[i] = -1 - i;
    }
    printf("%d", strlen(a));//strlen到\0或0停止计算
    return 0;
}


当i=0时a[0]=-1,....a[127]=-128...a[128]=127...a[244]=1,a[255]=0,0前共255个数

#include <stdio.h>
int main()
{
    unsigned char a;
    for (a = 0; a <= 255; a++)
    {
        printf("hello\n");
    }
    return 0;
} //死循环


**浮点型存储**


十进制9.0 -- 二进制1001.0 --(-1)^0 * 1.001 * 2^3
(-1)^S * M * 2^E
s--0 , M--1.001(1<=M<=2) , E--3  
     
对于32位(bit)的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M
对于64位(bit)的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M

因为M的第一位总是1,于是不保存,当读取时再加上去,23位的M相当于可以存储24位有效数字
E为无符号整数,如果E为8位,其取值范围为0~225,11--0~2047,但科学计数法中E可以为负数
  于是存入内存时E的真实值要加上中间数,8位E为127,11位E为1023,比如存10时要存入10001001
E为全0:规定E的真实值为-126或-1022,且有效数字M不再加上首位的1。直接以 0.xxx*2^(-126)表示
E为全1:正负无穷大

float f=5.5--二进制101.1(0.5=1*2^(-1))-- (-1)^0 * 1.101 * 2^2
S=0,M=1.101,E=2
0 10000001(存储值129) 011 00000000000000000000(补全)
0100 0000 1011 0000 0000 0000 0000 0000
化为16进制0x40b00000

#include <stdio.h>
int main()
{
    int a = 9;
    float* p = (float*)&a;         //访问4个字节
    printf("a的值为:%d\n", a);    //a--00000000 00000000 00000000 00001001
    printf("*p的值为:%f\n\n", *p);//*p--0 00000000 00000000000000000001001(补码)
                                   //E为全0,原码化为十进制前数位全为零
    *p = 9.0;                      
    printf("a的值为:%d\n", a);    //*p--0 10000010 00100000000000000000000 (补码)
    printf("*p的值为:%f\n", *p);  //a--01000001 00010000 00000000 00000000(补码)
}                                     //正数原反补相同 a的值为:1091567616​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值