In depth analysis of data storage in memory shaping, storage in memory, and size end introduction

Deep analysis of data storage in memory

Data type introduction

Basic built-in types

char     //Character data type
short    //Short 
int     //plastic
long     //Long integer
long long  //Longer shaping
float    //Single-precision floating-point 
double    //Double precision floating point number

Meaning of type:

1. Use this type to open up the size of memory space (the size determines the scope of use)

2. Vision of memory space

Basic classification of types

Plastic family

char

​ unsigned char

​ signed char

short

​ unsigned short

​ signed short

int

​ unsigned int

​ signed int

long

​ unsigned long

​ signed long

Floating point family

float

double

Construction type - custom type

struct - structure type

array

enum - Enumeration

union - Consortium

Pointer type

int *p

char *p

float *p

void *p

Empty type

void – the return type used for the function

Function parameter -- void test(void);

Pointer -- void *p

Shaping storage in memory

The creation of a variable needs to open up space. The size of space varies according to different types. How is the data stored? Let's first look at the binary representation of integers:

For integers:

There are three binary representations of integers: original code, inverse code and complement code

**Positive integer: * * original code, inverse code and complement code are the same

**Negative integer: * * original code, inverse code and complement code to be calculated

The binary sequence written directly according to the value of the data is the original code

The sign bit of the original code remains unchanged, and the other bits are reversed by bit to obtain the inverse code

Inverse code + 1 to get complement

int main()
{
    int a = -10;
    //Original code
    //10000000000000000000000000001010
    //11111111111111111111111111111110101 - inverse code
    //11111111111111111111111111111110110 complement
    //1111 1111 1111 1111 1111 1111 1111 0110
    //F    F    F    F    F    F    F    6
    //FFFFFFF6
    return 0;
}

Memory storage of a:

The data is stored in binary form in the memory. After debugging and checking the address memory of a, it can be seen that the integer is stored in the memory as a complement

The original, inverse and complement of positive numbers are the same

For plastic surgery: data storage is complement

Why is the complement stored?

In the computer system, numerical values are represented and stored by complement. The reason is that by using complement, the symbol bit and value field can be processed uniformly; At the same time, addition and subtraction can also be processed uniformly (CPU only has adder). In addition, the complement and original code are converted to each other, and the operation process is the same, without additional hardware circuit.

int main()
{
    //1-1
    //1 + (- 1) / / CPU has no subtracter, only adder, which should be converted into addition calculation
    //00000000000000000000000000000001
    //10000000000000000000000000000001
    //10000000000000000000000000000010
    //-The original code is - 2 after adding
    
    //000000000 01 -- complement of 1
    //111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    //100000000000000000000000000000000
    Only 32 can be stored in memory bit The one who goes in can't save it. It's lost
    //000000000000000000000000000000000000000 -- 0 / / more appropriate
    return 0;
}

We find that the memory of a is stored upside down. Next, let's look at the size end of a knowledge point

Large and small end introduction

Large end byte order and small end byte order

int main()
{
    int a=0x11223344;
    return 0;
}

Address high ----------- > address high

44332211 small end byte order

11223344 big endian byte order

Big endian byte order:

Store the contents of the low byte order of the data at the high address and the contents of the high byte order at the low address

Small end byte order:

Store the contents of the low byte order of the data at the low address and the contents of the high byte order at the high address

The current compiler is a small endian storage mode

Baidu written test questions

Please briefly describe the concepts of large end byte order and small end byte order, and design a small program to judge the byte order of the current machine.

#include<stdio.h>
int main()
{
    //Write code to judge the byte order of the current machine
    int a=1;
    char* p=(char*)&a;
    if(*p==1)
    {
        printf("Small end\n");
    }
    else
    {
        printf("Big end\n");
    }
    return 0;
}

Judging by function

#include<stdio.h>
int check_sys()
{
    int a=1;
    char* p=(char*)&a;
    return *p;//Return 1 small end and 0 large end
}
int main()
{
    int ret=check_sys();
    if(ret==1)
    {
        printf("Small end\n");
    }
    else
    {
        printf("Big end\n");
    }
    return 0;
}

Practice explanation

1.

int main()
{
    char a=-1;
    //10000000000000000000000000000001
    //11111111111111111111111111111110
    //11111111111111111111111111111111
    //11111111
    //Plastic lifting
    //11111111111111111111111111111111
    signed char b=-1;
    //11111111
    //Plastic lifting
    //11111111111111111111111111111111
    unsigned char c=-1;
    //11111111
    //Plastic lifting
    //00000000000011111111 -- complement
    //11111111111111111111111111111100000000 -- inverse code
    //11111111111111111111111111100000001 -- complement
    printf("a=%d b=%d c=%d",a,b,c);
    return 0;
}

Supplement:

1. Is char signed or unsigned?

The C language standard is not specified and depends on the compiler

Int is a signed int

Short is a signed short

2.

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

The explanation is as follows:

1000000000000000000000000010000000 - original code

111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

11111111111111111111111111111110000000 - complement

10000000

a is the signed char, the high bit is filled with the sign bit, and the shaping is lifted,

11111111111111111111111111111110000000 - complement

Print with% u and print in unsigned form. It is considered that it is stored in memory without symbols, so the complement is the original code

3.

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

The explanation is as follows:

00000000000000000000000010000000

01111111111111111111111101111111

011111111111111110000000 - complement

10000000

a is the signed char, the high bit is filled with the sign bit, and the shaping is lifted,

11111111111111111111111111111110000000 - complement

Print with% u and print in unsigned form. It is considered to be unsigned. The unsigned number is the same as the original inverse complement, so the complement is the original code

Supplement:

char

The value range of signed char is - 128 to 127

00000000–>0

00000001–>1

......

01111111 – > 127 – positive maximum

10000000 - -128

10000001 10000000 11111111 -127

......

11111110 11111101 10000010 -2

11111111 11111110 10000001 -1

Inverse complement original code

4.

#include<stdio.h>
int main()
{
    int i=-20;
    unsigned int j=10;
    printf("%d\n",i+j);//%d thinks that the number in memory is signed and% u thinks that the number in memory is unsigned
    return 0;
}

The explanation is as follows:

100000000000000000000000000000010100 – i original code

11111111111111111111111111111111101011 – i inverse code

11111111111111111111111111111111111101100 – i complement

00000000000000000000000000001010–j

11111111111111111111111111111110110 – i+j complement

11111111111111111111111111110101

%d thinks that the number in memory is signed and% u thinks that the number in memory is unsigned

The sign bit remains unchanged and is reversed by bit

10000000000000000000000000001010 -->-10

#include<stdio.h>
int main()
{
    unsigned int i;
    for(i=9;i>=0;i--)
    {
        printf("%u\n",i);
    }
    return 0;
}

The explanation is as follows:

i is an unsigned shape. i will never be less than 0. It's an endless loop

6.

#include<stdio.h>
int main()
{
    char a[1000];
    int i;
    for(i=0;i<1000;i++)
    {
        a[i]=-1-i;
    }
    //-1 -2 -3...... -127 -128 127 126...... 3 2 1 0 -1 -2 -3......
    printf("%d",strlen(a));//\0 is the end flag
    return 0;
}

The explanation is as follows:

Char is a signed char with a value range of - 128 to 127. Because strlen calculates the string, it stops calculating when it sees \ 0, and strlen calculates the length of the string before 0.

7.

#include<stdio.h>
int main()
{
    unsigned char i = 0;//Unsigned char value range 0-255
    for(i=0;i<=255;i++)//This condition will always be met
    {
        printf("hello world\n");
    }
    return 0;
}

Dead cycle

The explanation is as follows:

The value range of unsigned char is 0-255, and the circular judgment part is always satisfied

Keywords: C

Added by monezz on Tue, 08 Feb 2022 16:36:59 +0200