当前位置:网站首页>[C language] data type storage, original code, inverse code and complement code

[C language] data type storage, original code, inverse code and complement code

2022-06-11 23:22:00 InfoQ

​ Today, I will take you to master data type storage 、 Original code , Inverse code , Complement code *⌒(*^-゜)v THX!!

The meaning of type :

The amount of memory space created using this type , So the size also determines the range .

  • It is this type that determines the size of its memory space once it is determined , It also determines how big its scope is . For example, it's like : When you put a variable a The value of is assigned to int plastic , So its storage size is 4 The range of bytes is  -32768~32767.
  • Be careful , Various types of storage sizes are related to the number of system bits , But the current 64 Bit system is the main .

C The types of languages are divided into

Basic types :
They are arithmetic types , There are two types : Integer and floating point types .
Enumeration type :
They are also arithmetic types , It is used to define a variable that can only be given a certain discrete integer value in a program .
void  type :
Type specifier  void  Indicates that no value is available .
Derived type :
They include : Pointer types 、 An array type 、 Structure type 、 Common body type and function type . How to see a memory space clearly , This is actually assuming that you

How to look at the perspective of memory space :
int
Create a variable of type (a), Account for the 4 Bytes , float Type to create a variable (b), It also only accounts for only 4 Bytes of space . But give variables a Is the formatter %d It's a plastic , And give variables b Is the formatter %f Is a single precision floating-point type .

Note that they are stored in different ways , You can use debugging content on the compiler, and you can see that their memory is different

use
 
int a = 5;float b = 5.0;
 
Debug to memory with .

  • Memory is a major component of a computer ,  It is used to save the program and data when the process is running , Also called executable memory . In the computer , Memory space generally refers to the main memory space ( Physical address space ) Or the system allocates memory space for a user program . Methods to expand memory space generally include increasing memory size and virtual memory .

I won't explain other types here , Let's talk about the construction type , And pointer types .

Construction type

  • An array type :
    Why is an array type a construction type ? Because of the assumption
     int arr[20], So it's an array type, isn't it . that int [20]  It's the type , Then I'll make another change int [10]  This type is changing   So what if you're a different type? Character type , Floating point type like this , Therefore, array is also a custom type and a construction type .
  • Type of structure :
    struct,
      Member types are changing , Then its structure is also changing . If you don't know the structure, you can see the content of this structure in my article .
  • Enumeration type :
    enum,
      This is C A key word of language , At that time, I will take out and write an article to focus on the enumeration type in C What role does language play .
  • Consortium type :
    union
    , This is also called a community , We won't talk about this now .

Pointer types

  • The purpose of a pointer is actually to store an address assigned to a variable in it , And the bytes of the pointer are 4 Bytes .
  • In this way, we use a piece of code to let you intuitively see if the pointer is 4 Bytes , Because the blogger told you about the content of the wild pointer, but the content of the pointer has not been told you yet ,
    At that time, bloggers will also write an article about pointers ,
      Thus, pointer type is a special type . Pay attention to the , The pointer is defined with *

#include<stdio.h>
int main(void)
{
 int a = 10;
 int* p = &a; // Shaping pointer variables p receive a The address of
 // Here, all data types are defined as pointers -- 32 position  4byte 64 position  8byte
 printf(&quot;%d\n&quot;, sizeof(int*));
 printf(&quot;%d\n&quot;, sizeof(short*));
 printf(&quot;%d\n&quot;, sizeof(double*));
 printf(&quot;%d\n&quot;, sizeof(char*));
}


  • Running results :

null

Empty type

  • A special return type , Represents an empty function , That is, a function without a return value . Empty type ( No type )&nbsp;void  Used to show that a function does not return any value . It can also point to  void  Pointer to type , After explanation , This pointer can point to various types of data objects
  • void There is no reference , When you add no parameters when defining a program , Although the program will run . But there will be a waring Hints are unnecessary parameters

The return type of the function

#include<stdio.h>
void print()
{
 printf(&quot;hello word\n&quot;);
}
int main(void)
{
 print();
}

The parameters of the function

#include<stdio.h>
void print()// It is also possible to transfer parameters without parameters , But not here, so we C Language does not receive
{
 printf(&quot;hello word\n&quot;);
}
int main(void)
{
 print(10);// stay print Give arguments to the function 10
}

Shaping the storage space in memory

If you want to understand this content , I use a piece of code to show you :

#include<stdio.h>
int main(void)
{
 int a = 5;
 int b = -3;
}

a
Stored results

null

b
Stored results

null
  • Did you find out , The storage results of these two are different , Next, I'll tell you how plastic is stored in memory .
  • In fact, it is necessary to understand the original code first , Inverse code , And the concept of complement .
  • In the computer
    Signed number ( plastic )
      There are three ways to express it, namely : Original code , Inverse and complement . The three representations have two parts: sign bit and numeric bit ,
    The sign bit is used 0 Representation bit &quot; just &quot;, use 1 Expressed as &quot; negative &quot;,
      The three representations of numerical bits are different . notes : Unsigned source code, inverse code and complement code are the same .
  • There are two kinds of signed numbers. One is called positive number , The other is called a negative number . It's the same in positive numbers , However, in negative numbers, these three expressions are different

  • Above are three cases of negative numbers ,........... This is omitted if it's a plastic front 32 Digit number , Note that the highest position here is 1, So there are three forms of negative numbers .

Original code

  • Directly convert the number into binary according to the positive or negative form

int a = 5;//4 Bytes  —— 32bit position
//0( The highest positive number )0000000000000000000000000000101
int b = -3;
//1( The highest negative number )1111111111111111111111111111101

In fact, there is another way to calculate the complement. That's what I did at the beginning :

1、 Suppose it's negative 1 You first think of the complement as a negative number 1 The number of the original code —10001(
Note that the highest position here is 1, It's a negative number
)

2、 Then directly reverse the code. Note that the highest bit does not need to reverse the code ——11110

3、 The key step is to complement. Remember to add the last digit of the complement 1 yes 1 Just go to the first digit 1, The result is ——11111

Of course, this is a stupid way , If you can't understand, it's OK to use this. I was like this from the beginning

Inverse code

Leave your sign bit unchanged , That is, the highest position remains unchanged , Secondly, reverse the order of bits , Get the inverse .

such as  int = - 10; The opposite of —11111111111111111111111111110101

Complement code

The complement is   Inverse code +1  You can get the complement , Note that the premise is to add one to the inverse code

still &nbsp; such as  int = - 10; The complement of is —11111111111111111111111111110110

Notice here that it's full 2 Into the 1, Don't get it wrong ~!
If it's a positive number : Original code 、 Complement and inverse are the same !
If it's negative, that's what I said above ! For plastic surgery, all stored are complements , Bear in mind !
A byte =8 individual bit

Why is the complement stored in the computer ?

In a computer system , Values are stored in complement . The reason lies in , Use complement , Symbol bits and numeric fields can be processed uniformly ; meanwhile , In addition and subtraction
Complement code
It can also be handled uniformly (CPU There is only an adder ), Besides , In particular, the operation process of complement and original code can be converted to each other !

So let me focus on telling you about this adder , This adder is actually one of them CPU The use of addition , OK, let me give you an example, for example :1 - 1  What if you want to convert it into an adder ? It's actually very simple, just :1 + (-1)  That's all right. , So what if you want to use the original code now ?

1 The original code of : 00000000000000000000000000000001

-1 The original code of :&nbsp;10000000000000000000000000000001

result :&nbsp; &nbsp; 10000000000000000000000000000010&nbsp; &nbsp; &nbsp;  therefore ,1+(-1) = -2 Do you ? The answer is obviously not

good ! Now what if we use complement

1 Complement :&nbsp;&nbsp;1000 0000&nbsp;0000&nbsp;0000&nbsp;0000&nbsp;0000&nbsp;0000&nbsp;0001

-1 Complement :&nbsp;&nbsp;1111 1111 1111 1111 1111 1111 1111 1111 1111

result :&nbsp; &nbsp;~~1&nbsp;~~0000 0000 0000 0000 0000 0000 0000 0000

however : What we can only store in plastic surgery is 32 position , So what's left is 0, So when we use complement to calculate, we can calculate a correct knot , Think of this , I really think the person who created this algorithm at that time must be a fairy , Multiplication is ^ Add as much as you put it a few times , It may also be converted to an operation . But the principle is the same, that is, as long as I have addition , I can do all these things .

Introduction to big end and small end :

  • Big end : Storage mode means
    Memory
    The low order in is saved in
    Memory
    In the middle of
    High address
    among , And the high end of the data , Save in
    Memory
    Of
    Low address
    among .
  • The small end : Storage mode means
    data
    The low order in is saved in
    Memory
    Middle low address , And the high end of the data , Save in
    Memory
    Of
    Low address
    among .

  • Memory spaces are numbered , We all call the low bit of memory low address , If the number is large, it is called high address , Data can be stored in any way , But when you go back to your program, how must you store it? For example, what you shape and store is  11 22 44 33&nbsp;( Binary conversion hex  1 Bytes =4 individual bit position ), Then you also need to shape and store it in this way  11 22 44 33 ! But we don't usually store memory like this . There are usually two storage methods. One is called
    Big end
    Another storage mode is
    The small end
    The storage mode of .
  • The assumption is :0x11223344, This 44 It's low , and 11 It's the high position , Then the number of high addresses to be saved to memory , The high bit of the data is stored at the low address —— Big end
  • Suppose again :0x44332211, This 44 It's low , and 11 It's the high address , Low byte data is stored at a low address in memory , The high byte data is stored at the high address —— The small end

Judge the big end and the small end

Use code to judge the big end and small end :

Disintegration thinking
: A number
a
, Stored in memory , Suppose this
a
yes 20 Words , Without knowing it , I don't know whether it's big end or small end storage at present . however , It can be speculated whether it is a big end or a small end , As mentioned above . We can look at their first byte , Such as :

  • int a = 1;
  • The small end :0x01 00 00 00
  • Big end :0x00 00 00 01

Code demonstration

#include<stdio.h>
int main(void)
{
 int a = 1;
 char *p = (char*)&a;
 if (*p == 1)
 {
 printf(&quot; The small end \n&quot;);
 }
 else
 {
 printf(&quot; Big end \n&quot;);
 }
 return 0;
}

Custom function code

#include<stdio.h>
int Testing()
{
 int a = 1;
 char * pb = (char*)&a;
 if (*pb == 1)
 return 1;
 else
 return 0;
}
int main(void)
{
 int ret = Testing();
 // return 1 Represents the small end , return 0 It represents big end
 if (ret == 1)
 {
 printf(&quot; The small end \n&quot;);
 }
 else
 {
 printf(&quot; Big end \n&quot;);
 }
 return 0;
}


Here is the meaning of pointer type

  • The pointer type determines how many bytes the pointer dereference accesses , such as :char 
    p; So here
    p Only one byte can be accessed , According to the data type you define
  • The pointer type determines the pointer +1,-1 It's a few bytes , such as :char * p + 1; So what is skipped is a byte   Judge according to the data type  int Namely 4 byte

  • Be careful : The integer lifting complement is the highest sign bit ,'0' Being positive ,'1' Negative  

The storage of floating point in memory

Common floating point numbers :

  • 3.14 、1E10( This is actually 1.010 Of 10 Power —E)

Floating point numbers include :

  • C Floating point types in languages are float、double  and  long double  type .

Examples of notation :


  • The first 1 Columns are general notation ;
  • The first 2 Column is scientific notation ;
  • The first 3 The column is exponential notation ( Also known as e Notation );
  • This is how scientific notation is written in computers ,e The following numbers represent 10 The index of ;

Next, let's show you a code :

#include <stdio.h>
int main(void)

 int n = 9;
 float *pFloat = (float *)&n;
 printf(&quot;*pFloat The value of is :%d\n&quot;,n);
 printf(&quot;*pFloat The value of is :%lf\n&quot;, *pFloat);

 *pFloat = 9.0;
 printf(&quot;num Value :%d\n&quot;, n);
 printf(&quot;*pFloat The value of is :%lf\n&quot;,*pFloat);

 return 0;
}


  • Running results :

  • null

  • As can be seen from the above code : Floating point and integer memory are stored in different forms !

  • Some friends may have some questions , Why does the second line run the result *pFloat The answer is :0.000000, And the third line num The result of the operation is :1091567616, I think it should be  9.000000  and  9 ah . good , Don't worry. Now let's talk about why !

  • Print :0.000000 Because : If you take it back in the form of a floating point number when you put it in the form of a plastic number , Not getting the result we expected , Is it possible to explain how to store the result of integer and floating-point type
    It's different
    , If it's the same, it's
    The same result
  • Print :1091567616 Because :*pFloat We put it in the form of floating point numbers , And then to n The positive form of is taken as an integer ,
    Took out a wrong value

  • This explains the difference between the storage method of shaping and the storage method of floating-point type

  • Floating point binary complement
  • for example :7.0 — 0111 — 0111.0( Give... After the decimal point 0 That's all right. )  This is it. 7.0 Binary representation of
  • Any binary floating point number V It can be expressed in the following form :

  • (-1)^ M * 2 ^ E
  • (-1)^ s The sign bit , When
    s = 0 When ,V =  Positive numbers
    except 0 outside , Any number of 0 The second power equals 1
    ) When
    s=1 When ,V =  negative
  • M It represents a significant number , Greater than or equal to 1, Less than 2
  • 2 ^ E Indicates the index bit

Storage mode diagram :

null

null

  • The following example : Floating point numbers 9.0

  • 1001
  • 1001.0
  • 1.001 * 2 ^ 3&nbsp; ——  Be careful : This is binary
  • (-1) ^ 
    0
     * 
    1.001
     * 2 ^ 
    3
    &nbsp; =&nbsp;(-1)^ M * 2 ^ E
  • 0 10000010 00100000000000000000000&nbsp; —— E = 3 + 127 = 130
  • The numbers we mentioned above are printed directly as the original code  
    1091567616
  • In this way, we can be sure that  —&nbsp;s = 0 ,M = 1.001 ,E = 3 , Be careful M = 1.001  It's actually :0001

  • The following example : Floating point numbers 0.5

  • 0.5
  • 0.1 —  Be careful : This is one of the binary  -1  The first digit after the decimal point , yes 2 The negative power of is 0.5
  • 1.0 *&nbsp;&nbsp;2 ^ -1 ——  Convert to scientific counting
  • (-1 ^ 
    0
    ) * 
    1.0
     * 2 ^ 
    -1
     ——  Be careful : Index E Viewed as an unsigned number
  • s = 0,M = 1.0,E = -1
  • For eight E It is , The middle number is :127, For eleven E It is , The middle number is 1023,
    In fact, if your E If it's negative
    , take -1 Let's give you an example   Eight is :-1+127 = 126,11 It's about :-1+1023 = 1022

  • ****E Incomplete 0 Not all 1

  • Floating point numbers &nbsp;5.5
  • 101.1&nbsp; &nbsp;//  The front is 101 according to 8421 Code to , The back is 2 Negative power of   be equal to  0.5
  • (-1) ^ 0 * 1.001 * 2 ^ 2
  • s = 0 ,M = 1.011 ,E = 2 (E+127=129)
  • 0100 0000 1011 0000 0000 0000 0000 0000 —— here E The storage of is 129,E The value of the or 129-127=2, If you are double So here we have to subtract 1023 To the real E Value
  • 0x40B00000 ——  Converted binary hexadecimal digits

  • The result of debugging memory :

  • null


  • E All for 0 ( Understanding can )

At this time , The exponent of a floating point number E be equal to 1-127( perhaps 1-1023) That's the true value , Significant figures M No more first 1, But to restore bits 0.xxxxxx Decimals of , This is to show that ±0, And close to 0 A very small number .

  • E All for 1 ( Understanding can )

At this time , If the significant number M All for 0, Express ± Infinite hit ( It depends on the sign bit s)

原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203011613196480.html