C + + depth analysis (i)

Source: Internet
Author: User

chapter I C-language arrays

TABLE PAGE[10]

{

{"First section", "ABCDEFGHIJKLMN", add},

{"Second section", "Opqrstuvwxyz", NULL}

};

int main ()

{

VALUE AddValue;

Addvalue.val_1 = 2;

addvalue.val_2 = 4;

int result = 0;

result = Page[0]-> Unisetfunc (&addvalue);

printf ("The result of Add is%d\n", result);

return 0;

}

At this point the array is transformed into a structure similar to the dictionary in the Python language, allowing for subsequent development and additional upgrades and maintenance.

Code Analysis: First we know that the function name can be used as the entry address of the function (similar to the name of the array to represent the address of the array), so in the table struct we define a member function int (*unisetfunc) (value*); Here Unisetfunc as the entry parameter of the function, value* represents the formal parameter type of the function, an array of table type PAGE[10] that contains the structure of the data and the function's entry address, you can call Page[0]-> Unisetfunc (& AddValue) to invoke the Add function indirectly and to implement the sum of Addvalue.val_1 and addvalue.val_1 two numbers in AddValue.

Memory hit ratio issues:

In order to improve the efficiency of code operation, to make full use of memory space, you should continuously access the memory area.

We know that the location of the array in memory is a whole block of area, and is continuously stored, for the defined array array[2][2], assuming that the address of array[0][0] is 0x04030, then array[0][1],array[1][0],array[1 ][1] Addresses are 0x04031, 0x04032, 0x04033; increasing the memory hit rate should be as contiguous as possible to access the area of memory space, rather than jumping access; Let's look at a matrix multiplication problem.

for (int i = 0; i < 2; ++i)

{

for (int j = 0; j < 2; ++j)

{

for (int k = 0; k < 3; ++k)

{

MATRIX[I][J] + = matrix1[i][k] * Matrix2[k][j];

}

}

}

The above code is commonly used to multiply the matrix matrix1 and matrix2 and then assign to the matrix method, that is, using the matrix1 matrix to get the row vector multiplied by the matrix matrix2 column vector, and then assigned to the matrix, so because the matrix in memory storage structure, We can clearly know that access to the MATRIX2 is not the use of continuous access, so the memory hit rate is low. Next we look at a high memory hit rate method.

for (int i = 0; i < 2; ++i)

{

for (int k = 0; k < 3; ++k)

{

for (int j = 0; j < 2; ++j)

{

MATRIX[I][J] + = matrix1[i][k] * Matrix2[k][j];

}

}

}

It can be seen that the code simply swaps the second for loop with the third for loop, while the rest does not change, but the memory hit rate is greatly increased, and we use the matrix1 and matrix2 matrix to multiply and then add the elements in sequence, For the purpose of multiplying matrices so that no memory misses occur when accessing the matrix1 and matrix2 matrices, thus increasing the probability of memory hits.

The relationship between Volatile,const and static:

The Const keyword is a constant keyword, it acts as a constant, does not allow the program to change the value of the constant, such as the const int value = 12; This constant value does not allow the program to change it, and the Const keyword is often used in the development process.  In order to prevent the program from accidentally changing a fixed constant, we should give it a const keyword in a timely manner, and the Const keyword must be initialized directly to the constant when it is used for constants, because it is not allowed to be changed during the whole program operation, so it must be initialized immediately, for example: const INT Value = 12 is correct, while the const int value; value = 12; Such a syntax is wrong! Let's look at a slightly more difficult question, constant pointers and pointer constants. Look at the code first:

#define SWITCH 1

int main ()

{

int val_1 = 5;

int val_2 = 10;

const int *P1 = &val_1;

int const *P2 = &val_1;

int *const P3 = &val_1;

#ifdef Switch//This is a switch

*P1 = 20;

*P2 = 21;

*P3 = 22;

#endif

#ifndef SWITCH

P1 = &val_2;

P2 = &val_2;

P3 = &val_2;

#endif

printf ("%d\n", *P1);

printf ("%d\n", *P2);

printf ("%d\n", *P3);

return 0;

}

Executed under the Cygwin compiler, we can see an error like this:

We can clearly see that the pointer P1 and P2 can only read the value in Val_1 as a pointer constant, that is, the contents of the variable it refers to cannot be changed, so *p1 = 20; *P2 = 21; two commands are wrong! (#ifdef switch ... #endif for conditional compilation is a macro switch). Then we comment out the # define SWITCH 1 statement and run the second block of code to get the result as follows:

From the error can be seen P3 as a constant pointer, it can only point to a fixed address, and not change the direction it refers to, so P3 = &val_2; operation is wrong, so the correct code is as follows:

int main ()

{

int val_1 = 5;

int val_2 = 10;

const int *P1 = &val_1;

int const *P2 = &val_1;

int *const P3 = &val_1;

printf ("frist\n");

printf ("%d\n", *P1);

printf ("%d\n", *P2);

printf ("%d\n", *P3);

P1 = &val_2;

P2 = &val_2;

*P3 = 22;

printf ("second\n");

printf ("%d\n", *P1);

printf ("%d\n", *P2);

printf ("%d\n", *P3);

return 0;

}

The result of the operation is:

Final end: The constant pointer (const int *P or int const *p) indicates that the pointer p cannot change the value that it points to in the address, but can change the address it points to, and the pointer constant (int *const p) indicates that the pointer p cannot change the address it points to. That is, the pointer cannot change the position it points to, but it can change the content in the position it refers to. If you want the pointer to not change the position you are pointing at, and you cannot change the content, you can define:

const INT * Const P = &a; or int const *CONST p = &a; When defining a function, if the entry parameter does not wish to be changed during the execution of the program, it must be decorated with a const, which prevents the program from changing it, and, for the formal parameter, an argument whether or not a const modifier can pass it into a const-shaped parameter. A const-shaped argument cannot be passed into a non-const formal parameter, so to make the compilation error when defining a function, be sure to modify the amount that you do not want to change with the const keyword.

The static keyword, which has the function of storing the variable in memory instead of depositing it in the register (the variable is stored in the heap instead of the stack), and the variable of the action holds only the last acquired value. Next, let's look at a piece of code.

void Countfun ()

{

static int count = 0;

++count;

printf ("This is%d number, enter to this function!\n", count);

}

int main ()

{

for (int i = 0; i < 5; ++i)

{

Countfun ();

}

return 0;

}

The result of this code operation is as follows:

If the static keyword is removed, the result of the run is as follows:

From this we can clearly see that the static function of the variable count will only be deposited into the current results, so the loop call Countfun () function when the time does not reset the count variable to 0, but save the previous value.

The static keyword is widely used in projects, not only with the features described above, but also if you want to define a global variable that is only present in the entire project. c file, the global variable should also be modified with static, so that in other files can not access the variable, thereby reducing the coupling between the modules, improve the cohesion of the module, to prevent other files to change it, thus more secure.

The volatile keyword is a very important keyword in the embedded world, especially in hardware-related or multi-threaded programming. Volatile keyword-Modified variable description It can be changed at any time, we do not want the compiler to optimize some code, we need to modify this variable with the volatile keyword, so that every time the program accesses the variable is directly from the memory extracted, Instead of extracting a copy of the variable from a temporary register, use it! For example, when we want to implement an interrupt processing, the marker that is used to make the judgment condition should be modified with the volatile, so that when the interrupt is triggered elsewhere, it can be detected in real time, so that the interrupt is not ignored because of optimization. Next we look at a piece of code:

int main ()

{

volatile int i = 10;

int a = i;

printf ("i =%d\n", a);

__asm

{

mov DWORD ptr[ebp-4], 0x10

}

int b = i;

printf ("i =%d\n", b);

return 0;

}

This program outputs the result for i = 10;i = 16; If the volatile keyword is removed, the result is i = 10;i = 10; That is, the assembly code is ignored without the keyword, so in order to prevent code optimization and to detect changes to the variable by the external program in a timely manner, we must add the variable to the volatile keyword. We know that the volatile keyword indicates that the amount is variable, the const keyword indicates that the amount is constant cannot be changed, then whether volatile and const can be modified together with the same amount, the answer is yes, for example, in hardware programming rom stored data is not allowed to change the user, That is, the pointer to the data must be a constant pointer (const int *P = &ram_data), but the developer can change it unexpectedly, in order to prevent the contents of the ROM is accidentally changed, and the user program did not find in time, it must be modified with the amount of volatile, So the pointer should be defined like this (volatile const int *p = &rom_data).

C + + depth analysis (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.