数据在内存中的存储(C语言)(上)

简介: 数据在内存中的存储(C语言)

1.数据类型

1.1类型分类

整型:

提示1:

字符在内存中存储的是ASCII码

而ASCII码值是整型,所以字符类型也是整型

提示2:

signed 类型,即有符号数在存储时,有一位符号位

符号位0为正,

符号位1为负

提示3:

int 默认为signed int

想写无符号整型,必须写unsigned int

提示4:

C语言标准并未规定:

char是否是signed char

这取决于编译器

绝大多数编译器为signed char

浮点型:

构造类型(自定义类型)

指针类型:

提示:

void* pv 是无具体类型的指针

空类型:

2.整型在内存中的存储

计算机能处理的是二进制数据

整型和浮点型数据在内存中存储的也都是以二进制的形式进行存储

整数在内存中存储的是二进制序列

整型在二进制中的表现形式有3种:

原、反、补码

2.1原码、反码、补码

正整数:原、反、补码相同

负整数:原、反、补码之间要换算

原、反、补码均有符号位和数值位

原码符号位不变,其余为按位取反为反码

反码加一为补码

最高位(第一位)为符号位:

符号位0为正,

符号位1为负

其余为数值位

2.2存储补码的原因

使用补码可以将符号位和数值位统一处理

加减法统一处理(CPU只有加法器),补码和原码相互转换的计算过程相同,更方便

举例:

1+(-1)

如果用原码计算,其结果为

100000000000000000000000000000010

-2

用补码

结果为:

00000000000000000000000000000000

正确

2.3大小端

相关趣事:

格列夫游记中的剥鸡蛋:

端模式(Endian)起源于《格列佛游记》, 书中根据鸡蛋敲开的方式不同将所有人分为2类,从圆头开始敲的人被归为Big Endian,从尖头开始敲的被归为 Little Endian。小人国的内战就是源于吃鸡蛋是是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开。

大端与小端的存储

  1. 以字节为单位进行存储 两个十六进制位为1个字节
  2. 大端字节序存储 int a = 0x11223344 把一个数据低位字节处的数据,存放在高地址处
    把一个数据高位字节处的数据,存放在低地址处
  3. 小端字节序存储 int a = 0x11223344 把一个数据低位字节处的数据,存放在低地址处

###为什么有大端与小端之分

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为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处理器还可以由硬件来选择是大端模式还是小端模式。

百度2015年系统工程师笔试题:

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

//代码1
#include <stdio.h> 
int check_sys()
{
    int i = 1;
    return (*(char *)&i);
}
int main() {
    int ret = check_sys();
    if(ret == 1)
    {
      printf("小端\n"); 
    }
    else
    {
      printf("大端\n");
     }
return 0; 
}
//代码2
int check_sys() 
{
    union{
         int i;
         char c; 
         }un;
    un.i = 1;
    return un.c;
}


相关文章
|
22天前
|
监控 算法 应用服务中间件
“四两拨千斤” —— 1.2MB 数据如何吃掉 10GB 内存
一个特殊请求引发服务器内存用量暴涨进而导致进程 OOM 的惨案。
|
21天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
42 1
|
25天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。
|
22天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
19 0
|
存储 程序员 C语言
程序员之路:C语言中存储类别
程序员之路:C语言中存储类别
133 0
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
33 3
|
6天前
|
C语言
c语言调用的函数的声明
被调用的函数的声明: 一个函数调用另一个函数需具备的条件: 首先被调用的函数必须是已经存在的函数,即头文件中存在或已经定义过; 如果使用库函数,一般应该在本文件开头用#include命令将调用有关库函数时在所需要用到的信息“包含”到本文件中。.h文件是头文件所用的后缀。 如果使用用户自己定义的函数,而且该函数与使用它的函数在同一个文件中,一般还应该在主调函数中对被调用的函数做声明。 如果被调用的函数定义出现在主调函数之前可以不必声明。 如果已在所有函数定义之前,在函数的外部已做了函数声明,则在各个主调函数中不必多所调用的函数在做声明
21 6
|
25天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
34 10
|
19天前
|
存储 算法 程序员
C语言:库函数
C语言的库函数是预定义的函数,用于执行常见的编程任务,如输入输出、字符串处理、数学运算等。使用库函数可以简化编程工作,提高开发效率。C标准库提供了丰富的函数,满足各种需求。
|
24天前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
53 7