"Programming Master Proverbs" after reading # 4

zhaozj2021-02-08  240

After a few years, I have also seen a lot of things. Sometimes I want to write something, but I always feel a lot of clues, and I have not had a pen. Recently, I have turned a "programming master rumor", and suddenly wanted to write something, right to write something in the form of reading notes. The release "rumor" on the equity is the following is the I'm of myself. I hope everyone can advise, but they don't have to be, thank you. Note: This part involves the fourth chapter of "Proverbs".

It should be pointed out that GOTO in the same direction will have a great benefit. ========================================= I use index tools in Linux Kernel 2.2. I searched it a little in X, huh, too much goto, with the retrieval tool only gave me 1000. I think, since some people advocate all GOTOs, it can prove that people can demonstrate several conditional statements that can be designed with structured programming. However, "masters" written procedures will not be abandoned because many people do not have to be abandoned by goto, how they care about how to write efficient and clear code. In fact, in some cases, use GOTO to make the program clearly. For example, Linux / BSD Kernel is checked by the legality of this package after receiving an IP package from the lower layer. To know, there is still a lot of domains of the IP package, so the code checking is to repeat this process: take a domain, papers, legal, go down, not legal, clean up the site and then quit. This code looks like this: // sanity checkgetfield_1 (); checkfield_1 (); if (failed) goto Abortpoint;

Getfield_2 (); Checkfield_2 (); if (failed) goto abortpoint; ... getfield_n (); checkfield_n (); if (failed) goto abortpoint;

RETURN SUCCESS;

Abortpoint: doclean () return error;

Let's see, is this code that uses GOTO's code very clear? If you want to use those IF / switch, it is not beautiful, huh, huh.

In the PASCAL and C language, the relationship between data and code is blurred. ============================================================================================================================================================================================================= Oh, Pascal is my first language, C has been used for so many years, how did you feel that the relationship between the data and the code is blurred? Not understand.

With the re-entry, the operating system is well designed, you can implement multiple tasks. ============================================================================================================================================================================================================= = This kind of saying is really a first time I heard. As long as you use global variables with a global variable, the reusability of a function is still easier. Some of the operating system does need a re-entry function, but it is really not seen before the importance of retrieving it alone :-) In addition, the basis of multitasking is impressed, I am afraid nothing to enter the function? C is a working mode, i.e., bundling data and code that operates. This can be used as a structure, and the memory is allocated and used. In C , the function is used inside the dynamic researrable variable, and C is working in its own independent data area and code area. ============================================================================================================================================================================================================= ==================== C is not in one place, at least VC generated code is like this, I wrote a few small below. Procedure, everyone can run, naturally it will come out of his conclusion. In addition, the retrnight variable in the C function is normal, and C is also like this. As for the C , it is confused in the independent data area and the code area. It is unclear that the author wants to tell us what. In fact, a C Class If there is only a public member variable without a method, then it is not different from a Struct, even if there is a normal method, the memory of C Class is still no change, but the compiler will find another place to store another place. Method code itself. The following two Class:

Class a {public: int value;};

Class B {public: int value; void self value () << "B :: SayHello () << Endl;}}; if you use sizeof () to make each Class, you will find that The size is the same, B does not cause its size to become large because of a method. (Of course, if you use the Virtual to use Virtual as the false method, then add a so-called vTable in front of your class, actually a 32-bit pointer, which will cause your Class to get bigger, if you use Virtual to modify Sayhello, Class B will be more than Class A, which is more than Class A. In addition, for the method in the class, as long as it is defined in the program, then in the run, no matter where you have the instance of this class, these method code already exists. , Even we can use some "dirty" code to call: #include using namespace std;

Class a {public: int A; void syhello () {cout << "A :: SayHello ()" << endl;}};

INT main () {a * pa;

PA = null; // Note that the following statement is erroneous, in VC and GCC, PASS PA-> SayHello ();

Return 0;} Everyone can compile it. If you run, you will play "A :: SayHello ()", huh, we have existed the instance A of A. The compiler will "understand" our purpose, see (a *) -> SayHello, will call the appropriate function for us. Of course, Sayhello can't use your own member variables, such as int A, otherwise it will be wrong because the this pointer is wrong, after all we did not generate a case. BTW, pay attention to the following code: struct a {int a; int b; int C;};

& ((Struct A *) NULL) -> b)); / / This is the offset of b in the structure, and some OS Kernel code will implement some universal data structures, such as one-way linked list, this will take this technology. For details, you can look at DDK, or search in the Linux Kernel code, these implementations are quite intrinsic.

The function in this class does not remove the correct address because it is generated to dynamically assign an address. ============================================================================================================================================================================================================= ================================ This is actually wrong, and in the VC can use the "dirty" code below. Get the address of a class member function, and call it: #include #include using namespace std;

Class a {public: int A; void syhello () {cout << "A :: SayHello ()" << endl;}};

Typedef void (); // unclear comrades to see "Thinking In C " typedef void (* p_sayhello) (); // Unclear Comrade to check a book of C language

Int main () {char str [100]; PFN PFN; P_SAYHELLO PSAYHELLO

PFN = & a :: Sayhello; Sprintf (STR, "% D", PFN); psayhello = (p_sayhello) ATOI (STR); (* psayhello) ();

Return 0;}

OK, compile operation, at least in the VC environment "A :: SayHello ()". The reason why Sprintf and ATOI is because I don't know how to put the PFN transformation P_SAYHELLO, I have to use this "unclean" code, huh, huh :-)

Because the code and data are floating because the C class is defined. However, code floating is meaningless. ============================================================================================================================================================================================================= ============ I don't understand what it means. As for the floating code, it is not right. Compiled programs will not know where they will be loaded into virtual space, so they are some offset relative to the start address of the program, some Loaders is even loaded. When you dynamically modify these code, complete the final positioning. Let's take a look at John R. Levine's "Linkers & Loaders" understands anything.

For the same process, the code can only have one, because the code will not change your own. So, add a limit that cannot be acquired in C . ============================================================================================================================================================================================================= ======================================== The code given above describes the function addresses. As for the causal relationship between the above sentence, I still have not been able to be guided. Does the code will change themselves? In most cases, this is the case, however, some special procedures, such as viruses, it is entirely possible to modify themselves. In fact, from the perspective of the CPU, as long as you change the property of the code in Ring0 to write, then you can change you :-) C design concept is that the data and code are floating, so you can pass the entire object to A process is active as a data type and transmits this object from this process into another process. On this basis, the distribution object is developed. ============================================================================================================================================================================================================= ================================ Oh, I really don't know when I was designing C , the name is a bit strange. The big cattle has problems with the transfer of objects and distributed objects.

Put the object in another computer to make an operation, and after the operation is complete, only the result of the return operation is required. This model of this theory is not possible now, that is, the operating system will not do this. ============================================================================================================================================================================================================= ================================= can't do it? No. I want to pack, pass, unpack, instantiate, calculate, and return results, these no matter how it seems to be difficult to cross the gap. I am very small in the Dongdong of my distributed object, I hope that my comrades will talk to posts with posts. At that time, I took this time when I design C , but in fact this model is too ideal, it is impossible to implement it in practice. ============================================================================================================================================================================================================= ================================ I can't see how standard C supports object delivery and distributed objects. I think that the object delivery and distributed objects look like a software platform that should be provided, hard to make C to bear not afraid of C burden too heavy, huh, :-)

Later, a C language was generated on the basis of Pascal. ================================= Is it generated on the basis of Pascal? Although the Pascal is two years earlier, but directly causing the B language born in C. It seems to be more early than PASCAL? C Should be a Bell Lab B-language, and these languages ​​are closely related to Algol 60.

It is now all programming languages ​​to be people-centered, people's thinking is a starting point, so writing procedures will be separated from the implementation of the machine. This leads to many people who look up programs, but the programs written have such a problem, or the efficiency is extremely low. Such a programmer can't fundamentally solve such problems. Because he does not understand the relationship and principles of machines and programming languages. ============================================================================================================================================================================================================= ================================ I don't know how to read the above, the CPU designer will not say those use The guy who compiles programming is a starting point, so the program opportunity to be written is separated from the CPU logic design, which causes many people to look up, but the program, such as the problem, or efficiency low. Such a programmer can't fundamentally solve such problems. Because he does not understand the relationship and principles of CPU logic design and assembly language. :-)

The entrance and exit of the program ================ Whether it is a Windows PE format file or a Linux / BSD ELF file, the entry point of the program is recorded in the corresponding file head. Typically, the link program will fill in the appropriate entry point for your appropriate entry. And, in general, we don't need to intervene, otherwise it may cause the program operating environment to be not initialized correctly, and the global object does not have a correct construct. Of course, it is not absolute. When writing a pure Unicode program in the VC, in addition to the default macro definition _mbCS is changed to _unicode, it is important to modify the entry point of the program. If the console program is WMAINCRTSTARTUP, if it is a Windows program, It is wwinmainCrtStartup, otherwise it will be reported. As for the exit, under normal circumstances, the exit of the C / C program is the return point of the main function, however, if the program is not normal to exit, it cannot assume the position of the export point.

Part of the assembly language is the code, and the other is data, which is very clear in the assembly. ============================================================================================================================================================================================================= ========= I think it is not clear that the data and code in assembly code are unclear, because it depends entirely on how you let the CPU explain these 0,1 strings you generated. In fact, everyone understands that there is too much example in the assembly code to define some numbers as the code. A little program link is discussed in the last part of 4.1.1 in the "Proverbs". ============================================================================================================================================================================================================= ========== The link and loading of the program is much more complicated, and it is not over using a book description. Recommend you to see John R. Levine's "Linkers & Loaders". This book, which, you will understand one tenth, will be more harvest.

There must be a good habit when programming, that is, data and code put in different places, not to insert some variables in the data. Only in this way can you make the compiler very easy to process data ... This is less than the error generated by the cause of compilation. ============================================================================================================================================================================================================= ==================================== huh, the compiler doesn't care about your program, as long as you Compliance with the corresponding rules :-) The first time I saw a programming principle is used to prevent the compiler from erroneous. If your program is in line with the language of the language, and it is logically correct, then if the compilation is wrong, I suggest you to change a compiler. You have no compiler code, how can you know what code will make the compiler "comfortable"?

In fact, in Windows, TextOut has two functions. ========================================= Windows various versions of Windows built with NT technology The kernel is Unicode, if the ANSI version of the API is called, the system will switch in the background, so we can use the pure Unicode version of the API when Coding should have a little bit of performance, huh, huh :-) [ Example]: Customizer entry point ============================ In assembly language, the entry point of the program is actually a label. There is no special requirement such as Main, Winmain, which is in our C / C . The reason for this C / C is that in fact, the entry point of a C / C program is not our program, but a small piece of code defined by the environment, and the last small code will call our function. So how do this small code know where our functions are? It is necessary to solve this problem, and the easiest is to give us a function name and prototype. This is also the cause of main, or Winmain in the C / C program. A question of this program given by "Proverbs" is that there is no correct operational environment like WinMainCrtStartup.

If C is compared to C , C will wrap a large circle for a problem, so the code will be relatively large, and there are some unused code. ============================================================================================================================================================================================================= ====================================== Unfortunately "rumor" does not give an example showing how C is Wrought around a big circle. The C object mechanism should be a higher level of abstraction to the problem. As a general law, every upward abstraction in the computer will make the people's interface friendly, and this is the cost of the space and time. C objects are clearly rich in semantics than C, so C's structure can not require things such as constructor, destructive functions, and C needs them many times. If you use it, you are useless, I can only regret. This can only explain C with C , rather than watching C with C . For example, the C code written by the process of structural pointers will be complicated, because there are many structures inside, refer to it. ============================================================================================================================================================================================================= ================================ If you have a clear concept of your pointer, don't feel that the pointer is more complicated in general . Just a programmer that is not well trained may make mistakes in an inadvertent situation, and sometimes this mistake is hard. Many times, pointer helps express problems, such as the implementation of the binary tree, I think some language that does not support pointers, such as the implementation of Basic is not very clear, at least I think this. I think, if there is no pointer in C, it is estimated that C has died early ;-)

C mainly solves a problem of re-entry, and the re-entry is also an objective problem ... The early operating system is done with the structure, otherwise there is no way to solve the problem. ============================================================================================================================================================================================================= ====================================== don't understand. Cannot solve the file problem without the structure? What is the structure? Is the structure not an abstraction of data organization? As long as the CPU's instructions support indirect addressing, the implementation structure and its simple. Besides, a bunch of data is placed there, do you think he regard him as a structure is completely your own business. Then, when you really link in your code, you only contain the Data and Text districts, and the BSS area is to assign space when the program is installed. ============================================================================================================================================================================================================= ===================================================================== The size of the generated executable program will be understood. Program 1: #include long array [10 * 1024 * 1024]; int main () {Printf ("Hello World! / N");} Procedure 2: #include long array [10 *   1024 * 1024] = {0xccccccccc}; int main () {Printf ("Hello World! / N");}

So, I see why I want to understand the platform. Any program is compiled out and related to the platform. If it is separated from the platform, there is no meaning in any language. ============================================================================================================================================================================================================= ======================================== Oh, the slogan of Sun pushes Java is the slogan of SUN The platform is independent. Although this Sun is not perfect, many small procedures have no problem across platforms. The local variable is completely implemented in the stack. ============================= What do you mean? We can take a look at a small VC program anti-assembly result Push EBPMOV EBP, ESPSUB ESP, 44H ... POP EBP Sub ESP, 44h is to reserve space in the stack to local variables, later The PUSH / POP operation will only start from the ESP minus 44h. The space between EBP and ESP-44H is the space of local variables. In "Proverbs", the function cannot pass his local variable to the upper function. We understand the above principles: After returning to the upper function, the stack pointer will go, no one knows the stack. What is the value. In fact, transmitting function local variables to the upper layer function can lead to a very hidden bug, because in some procedures, the value inside is not destroyed, then the program "seems" can still work, and if in additional process The value is destroyed, then the program is not right. So you must be careful about this problem.

Automatic means automatic allocation and clearance, and the initial value is also random. ============================================================================================================================================================================================================= ===== In the VC DEBUG version, the values ​​allocated in the stack will be processed with 0xcccccccccccc, so everyone will find a value such as 0xccccccc in the debug mode, indicating a value attempting to use a no initialization . This is one of the benefits of debugging in Debug mode. If in Release mode, the system will not use 0xcccccccc to process it. As for why I choose 0xccccccccc probably because the endpoint interrupt INT 3 corresponds to 0xcc, I am not very confident. With a fixed address is the data that can be accessed by the pointer. But in general, Windows may report illegal operations. ============================================================================================================================================================================================================= ================================== 一 一 程序 程序 程序 程序 程序 程序 程序 程序 程序 情况 程序. Especially in Windows, accessing physical memory and I / O ports cannot be done directly in DOS. There is a winio library (http://www.internals.com) to access physical memory and I / O port, but it is actually implemented with a WDM Device Driver. The interface DLL of this library will automatically load a .sys driver, then pass the physical address and I / O information you need to access to the kernel, and return to the application after the operation is complete.

However, during the call of the function, reference and pointer are different, the reference is often in the compiler's code, plus an automatic movement process, that is, move that value. ============================================================================================================================================================================================================= ================================================ or watch Simple example. The assembly code is copied in the compilation view of the VC in DEBUG mode. #include using namespace std;

Struct a {Int a; long b;};

Void Handle_1 (Struct A * a) {a-> a = 0x1234; A-> B = 0x4321;}

Void Handle_2 (STRUCT A) {a.a = 0x1234; A.B = 0x4321;}

Void Handle_3 (Struct A & A) {a.a = 0x1234; A.B = 0x4321;}

INT Main (int Argc, char * argv []) {a a; handle_1 (& a); // biography address Lea Eax, [EBP-8] Push Eax Call @ ilt 0 (Handle_1) (00401005) Add ESP, 4 Handle_2 (a); // Passage MOV ECX, DWORD PTR [EBP-4] PUSH ECX MOV EDX, DWORD PTR [EBP-8] Push Edx Call @ ilt 10 (Handle_2) (0040100F) Add ESP, 8 Handle_3 ( a); // pass reference Lea Eax, [EBP-8] PUSH EAX CALL @ ilt 5 (Handle_3) (0040100A) Add ESP, 4

Return 0;} Everyone saw it, the transfer shift and delivery address (the structure of the structure) have nothing different after the assembly, in fact, we only need to use the definition of the reference, the C compiler will be interpreted according to the context at the time.

In the compilation, in fact, many unpredictable factors have been introduced. The compiler is the code that helps you turn your thoughts into machines, that is, turn your thoughts into the corresponding mappings in memory. If you really understand this, the compiler is not very important ... Many people do not know the role of the platform, in fact the platform is the most important. Some people think that they understand VC, I understand the computer, actually there is more than 100,000 miles away from the computer. ============================================================================================================================================================================================================= ============================================================================================================================================================================================================= === Oh, as long as you know the language, then you should know the specific meaning of your code, unless the compiler has bugs. Honestly, in these development languages ​​on Windows, the threshold of VC is still relatively high. I think that as long as it is a person who really understands VC, I am afraid I don't think I know my computer. Don't say that the computer is so big, you will be proficient in VC, the Windows source code is not given to you, you still have countless question marks! Understand the computer? What is easy.

If you look out, you will find a pile of vTable pointers, this pointer is again jmp to a function of the address. ============================================================================================================================================================================================================= ====================== In fact, if a class does not have a virtual function, the compiler is too lazy to generate VTABLE. The code generated by VC is after Call, however, the program compiled with G is direct Call without a JMP process. The role of VTABLE is to solve the so-called "post-binding", just this. And if a class does not have a Virtual Function, then this class is almost equivalent to a struct plus a bunch of functions, and there is no necessary "post-binding", so there is no need to bring a VTABLE. This is different from Java, and Java Impressions seem to be binding. In fact, these concepts are important, and VTABLE is important, especially when watching Microsoft COM. I would like to study "Thinking In C ", because it is very clear, huh, huh ~~~ If you use the function in the class, it is not static allocation, but is dynamic allocation, when the program has made a lot of memory After the operation, if there is a problem with a certain place, a CALL address error will appear. ============================================================================================================================================================================================================= ============================================================================================================================================================================================================= ========= Oh, this ten eight or nine is the stack. Sometimes, in your function calls some library functions, if you have some inexplicable questions, you should pay attention to whether you don't pay attention to the details of those library functions, causing the variables assigned on the stack to pass to these library functions After that, it has been modified by these library functions with different methods that you think, resulting in the destruction of the stack.

Older compiler When writing struct, you can use the member function and variables together, the structure and classes are the same. However, this structure is equivalent to all PUBLICs. ============================================================================================================================================================================================================= ============================================================================================================================================================================================================= ======= MSDN Similar to this initialization COM code struct xxx_ole_init {coinitialize (null);} ~ xxx_ole_init () {counitialize ();}} xxx_ole_init;

You can always pass the pass of the VC, and Struct XXX_OLE_INIT is equivalent to all members of all members of public Class.

When the compiler is called, a corresponding CALL? Add @@ yahhh @ z or call? Add @@ yammmm @ z. ============================================================================================================================================================================================================= ======================== encountered this "mysterious" instructions, we can use the Platform SDK to find a tool undname.exe to find out These seem to be a seven-eight strings to define what.

Class class_abc {Void FUC (int A, int b, int c);} extern "C" class_abc _fuc (void * lpthis, int a, int b) {((abc *) lpthis) -> fuc (int A, int B, INT C);} void main () {INT A = 1, b = 2, c = 3; Class_ABC ABC;

Class_ABC _FUC ((void *) & abc, a, b, c);} ================================= ============================================================================================================================================================================================================= What is it in the case of this program? The inheritance of COM is a grading pointer, because COM did not provide you with source code. ============================================================================================================================================================================================================= == Personally think that inheritance in COM should be comparable to the multiple inheritance of C . I don't know what the so-called grading pointer mean. Again COM is just a standard, rather than achieving, a bit like what J2EE in Java. The specification is free of implementation, and of course the reference is achieved. There is a third party COM implementation on the Internet, on the UNIX platform. For the user, a COM service is for you, you can call the service directly, do not need to know how the specific COM service is implemented. (Of course, I know better :-)

A global variable is in a file, in the B file, use extern to introduce this variable, if the global variable is written by two people, and the name is the same, both programs have to be a EXE, which will have problems. ============================================================================================================================================================================================================= ================================= In fact, there are several principles of the national variable in C / C , try not to The variables are defined in. H. The variable is applied in. h. The global variable is only defined in one file, and other places can only be illustrated with extern. In order to prevent .h files are repeated, with, for example, #ifndef _xxx_h_ # define _xxx_h_

#ENDIF expands the contents of the header file. In the VC environment, #pragma overce can also be put on the same purpose of the #pragma overce. In order to avoid the occurrence of these problems, some books will not use global variables, which will cause the program to conflict with each other. ============================================================================================================================================================================================================= =================================, fortunately, I didn't see this book, according to the above In principle, there should be no conflict, as long as the logic has no problem.

If it is a chain, you have to find one. If it is a parallel array, you can compare or sort it first, then look up, so speed will be much faster. ============================================================================================================================================================================================================= ================================== Is there a chain structure that can not be sorted first? A two-way linked list, in addition to not supporting random positioning like arrays, other almost no particulars are not particularly obvious. And the insertion of the array, the overhead of the deletion operation is still very large.

In the program, with a chain generally brings many instability factors. ... The readability of the program will be poor. ============================================================================================================================================================================================================= =================== Oh, Kung Fu does not have a state of data. What data structure you use will bring instability. Chained mechanisms naturally have their suitable occasions. For example, the implementation of the binary tree, I think it is very good to use a chain structure. If you don't support the language of the pointer, such as Basic, your individual feels not intuitive.

The most common Basic in the explanation method ... is actually, the interpreter is an interpreter of a string. ============================================================================================================================================================================================================= ========================= Many script languages, such as the famous Perl, Python, etc. are interpreted. These scripting languages ​​are very semantic, like Perl, Python supports object-oriented programming, so the interpretation of these scripts is very complicated, and all aspects of the compilation principle are almost involved, far from what is not a string interpreter. Split. Many books did not say why the parameters passed from right to left ... so that it is easy to assemble and debug. ============================================================================================================================================================================================================= ============

Personally feel that there should be no relationship with debugging, it is possible to have a bit related to the implementation of variable parameter functions.

The following is taken from the code provided by the VC, and VA_XXX is several important macros for variable parameter programming. #ifdef _m_ix86 # define _intsizeof ((SizeOf (N) SizeOf (Int) - 1) & ~ (INT) - 1))

#define va_start (AP, V) (AP = (VA_LIST) & V _INTSIZEOF (V)) #define VA_ARG (AP, T) (* (t *) ((AP = _INTSIZEOF (T)) - _INTSIZEOF (T) )) #define va_end (AP) (AP = (va_list) 0)

We can see that the so-called variable, in fact, using VA_ARG to take the appropriate byte from the stack every time

The number of required parameters required. If the parameter from the right left stack, then use EBP to successfully

Take out the first, second ... nth parameter, otherwise, it will not be able to take a straight simple method to take the first

The parameter is, the reason is that the EBP can only be directly positioned to the last set of parameters, and the function parameters

The number is unknown, so the position of the first parameter in the stack is not easy to locate. Of course, this is not

Absolutely, can be done with some auxiliary methods, but it is better to let the parameters are realized from the right to left.

It's easy and simple.

转载请注明原文地址:https://www.9cbs.com/read-1779.html

New Post(0)