C 语言中的数据类型(扩充)

该篇文章是对之前文章的一个补充。

首先,在计算机中

  • 内存是线性的
  • 内存是以字节为单位进行编址的,内存中的每个字节都对应一个地址
  • 程序的执行过程中,数据都要保存到内存当中

而数据是有类型的,计算机会根据数据类型分配连续的一段内存作为数据的存储空间,也就是说利用数据类型,就沟通了内存大小和数据之间的关系。

数据类型与内存的关系

数据类型表示数据申请的内存单元大小和访问的规则,表示了数据在内存上的一种逻辑关系。

#include <stdio.h>

int main()
{
    int a = 0xff;
    unsigned int b = 0xff;
    char c = 0xff;

    printf("%d\n",a);
    printf("%u\n",b);
    printf("%c",c);

    return 0;
}

结果为:

255
255


可以看出同样的 0xff 经过不同数据类型的解释,可能会得到不同的结果。这就是因为数据类型不同,从而在内存单元中做出了不同的解释(内存分配)。从下边的程序更能看出数据类型的含义:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    void *p = malloc(8);

    char *pc = (char *)p;
    *pc = 'a';
    printf("%c",*pc);
    putchar(10);

    unsigned *pu = (unsigned *)p;
    *pu = 100;
    printf("%u",*pu);
    putchar(10);

    int *pi = (int *)p;
    *pi = 100;
    printf("%d",*pi);
    putchar(10);

    double *pd = (double *)p;
    *pd = 100;
    printf("%f",*pd);
    putchar(10);

    free(p);
}

结果为:

a
100
100
100.000000

上边的程序中,我们利用 malloc 函数获取了堆上的内存空间,malloc 的函数头为:

void *malloc(size_t _Size);

这意味着该函数的返回值是 void * 类型,该类型只是一个单纯的指针,只指向堆上的一个地址。而通过用 char *,unsigned *,int *,double * 对该指针进行重新解释,就相当于获得了以该指针指向的地址起始的连续空间,从而拥有了数据类型。

用一句话来说,就是数据本身并不重要,而是看你怎么对数据进行解释。

类型转化

在之前提到的文章中也写到了类型转化,不过着重说了算数转化,对于单纯的赋值行为来说会有一些不同。

短字节数据赋给长字节变量

数据的短字节和长字节说明的是数据本身的数值大小,因为数据在拥有数据类型之前是没有字节长度的,因此这里数据的长度并不具有实际意义。

此时不会造成数据的丢失,还进行符号扩充。

#include <stdio.h>

int main()
{
    char c1 = 0xff;
    char c2 = 0x7f;
    char c3 = 0x80;
    int a1 = c1, a2 = c2, a3 = c3;
    printf("%d,%d,%d",c1,c2,c3);
    putchar(10);
    printf("%d,%d,%d",a1,a2,a3);
}

结果为:

-1,127,-128
-1,127,-128

上边的结果中,三个字符变量转化前后的值为:

1111 11111111 1111 1111 1111 1111 1111 1111 1111
0111 11110000 0000 0000 0000 0000 0000 0111 1111
1000 00001111 1111 1111 1111 1111 1111 1000 0000

从上边的结果也可以看出,此时都是进行了括号扩充。

长字节数据赋给短字节变量

数据的短字节和长字节说明的是数据本身的数值大小,因为数据在拥有数据类型之前是没有字节长度的,因此这里数据的长度并不具有实际意义。

此时会发生数据截断,数据有可能会丢失。

#include <stdio.h>

int main()
{
    int a1 = 0xffffffff;
    int a2 = 0x7fffffff;
    int a3 = 0xff;
    char c1 = a1, c2 = a2, c3 = a3;
    printf("%d,%d,%d",a1,a2,a3);
    putchar(10);
    printf("%d,%d,%d",c1,c2,c3);
}

结果为:

-1,2147483647,255
-1,-1,-1

此时不考虑数据本身的长度,而只从源数据中截取符合数据类型的固定长度的位数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值