C语言数据的存储

1数组类型

char         // 字符数据类型  占一个字节
short       // 短整型             占2个字节
int         // 整形                   占4个字节
long         // 长整型              32位占4个字节,64位占8个字节
long long   // 更长的整形    占8个字节
float       // 单精度浮点数    占4个字节
double       // 双精度浮点数  占8个字节
  • 类型的意义

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

2. 如何看待内存空间的视角。
整形家族:
char
        unsigned char
        signed char
short
         unsigned short [ int ]
         signed short [ int ]
int
       unsigned int
       signed int
long
     unsigned long [ int ]
     signed long [ int ]
字符的本质是ASCII,是整形,所以划分到整形家族。
char分为 signed char和unsigned char,具体是哪个,标准未定义,取决于编译器,一般是signed char。
构造类型
  结构体类型 struct
  枚举类型 enum
  联合类型 union
void 表示空类型(无类型)
通常应用于函数的返回类型、函数的参数、指针类型

例子1

第一个void 表示函数不会返回值
第二个void 表示函数不需要传任何参数
void test(void)
{
printf("hehe\n");
}
int main()
{
 test();
 return 0;
}

2整形在内存中的存储

一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。
接下来谈谈数据在所开辟内存中到底是如何存储的
2.1 原码、反码、补码
计算机中的整数有三种 2 进制表示方法,即原码、反码和补码。
三种表示方法均有 符号位 数值位 两部分,符号位都是用 0 表示 ,用 1 表示 ,而数值位
正数的原、反、补码都相同。
负整数的三种表示方法各不相同。
原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码。
反码
将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码
反码 +1 就得到补码。
对于整形来说:数据存放内存中其实存放的是补码。
为什么呢?
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统
一处理;
同时,加法和减法也可以统一处理( CPU 只有加法器 )此外,补码与原码相互转换,其运算过程
是相同的,不需要额外的硬件电路。
         1-1变成1加上负1,用补码进行计算。

 补码变成原码,可以先取反,再加1.

2.2 大小端介绍
什么大端小端:
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址
中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位 , ,保存在内存的高地
址中。
为什么有大端和小端:
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元
都对应着一个字节,一个字节为 8 bit 。但是在 C 语言中除了 8 bit char 之外,还有 16 bit short
型, 32 bit long 型(要看具体的编译器),另外,对于位数大于 8 位的处理器,例如 16 位或者 32
位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因
此就导致了大端存储模式和小端存储模式。
例如:一个 16bit short x ,在内存中的地址为 0x0010 x 的值为 0x1122 ,那么 0x11
高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中, 0x22 放在高
地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51
为大端模式。很多的 ARM DSP 都为小端模式。有些 ARM 处理器还可以由硬件来选择是大端模式
还是小端模式

 

笔试题 

请简述大端字节序和小端字节序的概念,设计一个小程序来判断当前机器的字节序

int check_sys()
{
    int a = 1;
    return *(char*)&a;
}

int main()
{
    printf("小端\n");//err

    int ret = check_sys();
    if (ret == 1)
        printf("小端\n");
    else
        printf("大端\n");

    return 0;
}

 练习

1.
// 输出什么?
#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
2.
#include <stdio.h>
int main ()
{
    char a = - 128 ;
    printf ( "%u\n" , a );
    return 0 ;
}
答案:4,294,967,168
3.
#include <stdio.h>
int main ()
{
    char a = 128 ;
    printf ( "%u\n" , a );
    return 0 ;
}
答案:4,294,967,168
4.
int i = - 20 ;
unsigned   int   j = 10 ;
printf ( "%d\n" , i + j );
// 按照补码的形式进行运算,最后格式化成为有符号整数
​​​​​​​答案:-10

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南种北李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值