A basic tutorial on using variables in programming the C language

  • 2020-05-09 18:56:12
  • OfStack

The C language explicitly divides number variables into two categories, integer and floating point, which correspond to real-world integers and decimals.

First, integers. After all this C language, whenever you use an integer, think of it as a base 2 rather than a base 10. The reason is that this is the nature of the program. If you do a little research on how the compiler works, you will find that good compilers try to speed up the program when the compiler is dealing with multiplication and even division. There is no doubt that the shift operation is the fastest "multiplication" and "division" among all operations:


1<<2 == 4 ,8>>2 == 2

However, a normal multiplication is equivalent to the time consumption of addition operation for 10 times, while a shift is not (division is more expensive, but with the progress of CPU, these gaps are gradually narrowing. At present, there is still a large gap, but no matter how optimized, the multiplication time will be greater than addition). As mentioned earlier, the C language was designed to give programmers all the power, and all programmers have to do is to control everything they can, even the calculation of Numbers. For example, from the point of view of a good compiler:


2*7 ====> (2<<3) - 2
5*31 ====> (5<<5) - 5

There is no doubt that compiler-optimized code is much faster. This is why we want to see the number 1 as 2 base, this is not just the surface, but want to be in deep thought it is 2 into the system, overall C integer is very clear and concise language generally divided into signed and unsigned, is easy to understand only need to be careful not to let the operation of unsigned number is negative, there is a principle, can very good around this has no intention of, don't put the unsigned types and signed type variables on with 1 operation, always remember to keep formula type 1 is the guarantee of the design.

Floating point Numbers, because the real field can be regarded as dense, so in addition to the integer, there are countless decimal, and decimal in the computer how to represent? An infinite state is one that cannot be accurately represented in a computer, so there is a floating point method, about which you can refer to the book "understanding computer systems in depth".
This is how do we use floating point Numbers correctly in C? Many people (including me) at the time of the early as always take it for granted that the computer is omnipotent, human beings are unable to fully express the decimal computer 1 can, in fact is not the case, here I can say that the computer is approximate expression, but the biggest taboo is compares two floating point Numbers, here introduces a kind of floating point comparison methods, accuracy method:


 #define DISTANCE 0.00000001
 ...
 float f_x_1 = 20.5;
 float f_x_2 = 19.5;
 if(f_x_1 - f_x_2 < DISTANCE)
   printf("They are Equal\n");
 else
   printf("Different\n");

So, for the most part, when you use floating point Numbers in your programs, and you compare them directly to floating point Numbers, and you don't get the results you want, you can check 1 to see if that's the case. At that point, you have to say that C is a flaw.

A pointer variable is a special variable that is always treated as special. Here are a few principles:

Adding and subtracting two unrelated Pointers is meaningless Always make sure you can find the allocated memory Whenever, wherever, and in any case, remember not to use uninitialized Pointers and not to let unused memory persist.

Pointers in different level of the size of the operating system is not 1 sample, but with an operating system, no matter what type of a pointer is the same size, this involves pointer to addressing problems, (digression: C language addressing actually USES the assembly language of indirect addressing, interested can try this, method 1, using gcc compilers compile options, generate assembly code, than 11), for addressing a general statement is 1


4Byte = 32bit
2^32 = 4G

So C language pointer under 32-bit operating system:


 ...
 size_t what = sizeof(void*);
 printf("%d", what);
 ...

Output:


$root@mine: 4

For most users, Pointers are mainly used to reduce memory consumption and improve computing efficiency. There is a lot of knowledge here, and I can't show it. Two interesting and common things are increment and syntax sugar :++, - >


 ...
 int dupli_of_me[10] = {0};// You can also use library functions memset() To buy 0
 int *point_to_me = dupli_of_me;
 int me = 100;
 while(point_to_me < (dupli_of_me + 10))
   *point_to_me++ = me;

Where *point_to_me++ = me; The C language is widely used and it is equivalent to:


 *point_to_me = me;
 point_to_me++;

For ++, if it is not necessary, please use prefix increment instead of suffix increment, because of the consumption problem. What is the difference between the two kinds of increment?
Prefix increment always increments on the original number, but what about suffix increment? It copies a copy of the original number somewhere else and increments the copy. After the operation of the original number is completed, it copies the copy into the original number to replace it.
- > It is widely used in the structure:


 typedef struct data{
   int test;
   struct data* next;
 }my_struct;
 ...
 my_struct temp;
 my_struct *ptemp = &temp;
 ptemp->test = 100;
 ptemp->next = NULL;
 if(temp.test == 100)
   printf("Correctly!\n");
 else
   printf("That is impossible!\n");
 ...

It's pretty clear that ptemp- > test is the grammatical sugar of (*ptemp).test

The variable limit

const is the most commonly used variable qualifier, which tells the compiler that the variable or object cannot be changed after initialization and is used to protect the necessary return values, parameters, and definitions of constants.

The keyword volatile is often ignored in C language textbooks. It is mysterious. In fact, this is true, and its role is rather mysterious: once a variable is used, it tells the compiler that its value may change even if it is not used or modified by other memory units. In layman's terms, tell the compiler not to use your optimization strategy on me.


   /*  At this point we raise the compiler optimization level to  -O2 */
   int     test_num  = 100; // test 1 Iterative addition 
   int     nor_result = 0;
   volatile int vol_result = 0;
   /*  The test no volatile Limit the time the program takes  */     
   for(int i = 0;i < 10000;++i)
     for(int j = 0;j < 10000;++j)
         nor_result += test_num;

The next step is to test the code defined by volatile


2*7 ====> (2<<3) - 2
5*31 ====> (5<<5) - 5
0

After using 1 method, the operating time is obtained, and the difference can be clearly seen. On my machine, i5-4CPU, the result is that the latter is about 105 times slower than the former. In some ways, it proves that volatile is useful for some purposes, like debugging, or for some special purposes. Not much involvement, so not recorded.

Variable declaration

extern is used to reference externally linked variables from different files to this file. The so-called external linkability refers to variables that can be "seen" by other files besides this file, such as global variables.


2*7 ====> (2<<3) - 2
5*31 ====> (5<<5) - 5
1

auto can be ignored because it makes no practical sense.

Variable gain

Formatting input and output is frequently used in the beginning of the C language, but later it will be found that the I/O operation will consume too much resources, in other words, greatly affect the execution efficiency of the program, and will gradually be eliminated in the distribution program.

Common formatted input standard functions: sacnf, fscanf, sscanf

For common usage, there are two less common formats: '%[]' and '%*',
The former is used to restrict the read type, and is often used for filtering strings (not really filtering)


2*7 ====> (2<<3) - 2
5*31 ====> (5<<5) - 5
2

Suppose you enter: 22 hello,string to me!
The readings are :22 hello and 22 hello,str and 22 hello
The latter ignores the first input:


    scanf("%*d %d", &tmp);

Suppose the input is: 22, 33
It reads: 33
The input ignored at the beginning of %*d must match its type; for example, input: string 33 will fail to read.
It can also be interpreted as file width, for example when formatting output using printf:


2*7 ====> (2<<3) - 2
5*31 ====> (5<<5) - 5
4

But in fact, scanf is not very easy to use. The so-called "easy to use" refers to the defects in the function and design, which always makes many people confused and make mistakes, and it is often difficult to debug. For example, it will keep the \n input per 1 line in the input stream. This defect leads to errors if it is mismatched with other input functions, such as fgets or gets, by unknown users.


Related articles: