C ++ Gotchas Terms 1 and Terms 17

zhaozj2021-02-08  344

C Gotchas Terms 1 and Terms 17

Stephen C. Dewhurst

Gotcha Terms 1: Transition Notes

There are many comments that are actually unnecessary. It generally makes the source code difficult to read and maintain, and often introduce maintenance personnel into astray. Check out the simple statement below:

a = b; // assigning B to A

This comment cannot communicate a clearer statement meaning than the code itself, so it is useless. In fact, it is better than it is not used. It is fatal. First, the annotation is transferred to the reader's attention, adding the reader to know the number of texts to know the code meaning; second, more texts need to be maintained, because the comment must change with its corresponding code Changes to be maintained; its third, this necessary maintenance of the annotation is often not implemented.

c = b; // assigns B to A

A careful maintenance person will not simply think that the annotation is falcated, so it has to be confirmed by the tracking program to confirm whether the comment is wrong, unconventional (c is a reference to a refretence) or subtle (assignment to C) Later, the same assignment is propagated to a). This line of code should not be required:

A = B;

The code is clear enough, and it is not a notes that will be improperly maintained. This is similar to "the most efficient code is the code that does not exist". The same reason is suitable for comments: The best annotation is those who don't have to be written, because the code itself is self-documentization (if this is not the case, you will use the annotation to describe it).

Other common examples of unnecessary comments frequently appear in the category definition, or whether it is a bad result caused by a bad coding specification, or the masterpiece of the C rookie.

Class C {

// public interface

PUBLIC:

C (); // default constructor

~ C (); // destructor

//.

}

You feel like you are reading someone's child manuscript. If a maintenance person needs to be prompted to be prompting public: meaning, you must not want to maintain your code by this person. The above note does not provide any help for experienced C programmers, will only add text to the code and provide more that will be maintained.

Class C {

// public interface

protected:

C (int); // default constructor

PUBLIC:

Virtual ~ c (); // destructor

//.

}

Programmers always have a strong motive, do not want to "waste" the number of rows of source code text. It is alleged that if a construction unit (function, category public interface, etc.) can be displayed in a "page" of a "page" in a usual and reasonable format, then its code is easy to understand; if The code is extended to the second page, understanding it is twice the original; if the code is extended to the third page, understanding it is about four times the difficulty.

There is also an alive approach that inserts a change history in the first or tail of the source code file:

/ * 6/17/02 SCD Fixed the gaforniflat bug * /

Is this useful information or a cattle blowing a safeguard? This note does not have any use, no matter what happens in this two weeks, but it will terrible for many years, affecting generations of maintenance personnel. A lot of alternatives is to leave these annotations to your version control software; the C source code file is not where the list of entries is stored.

To avoid unnecessary comments, and make the code clear and easy to maintain, one of the best ways is to follow simple, defined a good naming protocol, and select a clear name to reflect the referred to the entity (function, category, Abstract meaning of variables, etc.). It is especially important to use the regular parameter name in the statement. Consider the function of receiving three recognizable arguments: / *

Perform the action from the source to the destination.

Arg1 IS Action Code, Arg2 IS Source, And Arg3 Is Destination.

The operation is performed by the source position to the target position.

The first parameter is an operation code, the second parameter is the operation source, the third parameter is the operation target.

* /

Void Perform (int, int, int);

Not too bad, but think about how if the function has seven or eight parameters instead of three times, will it be? We can do better:

Void Perform (int actioncode, int source, int desinter);

This is better, although we may still encounter a person who loves fun, tell us what the function will do (although not to tell us how to do it). The most attractive parameter name in the statement is that it is different from the comment, which is usually maintained with the rest of the code, although it does not have any effect on the meaning of the code. I can't imagine that a single programmer will be able to reverse the meaning of the second and third parameters without changing the corresponding parameter name, but I can determine that there are many programmers who have not maintained the corresponding notes. In the case of the meaning of the two.

Perhaps Kathy Stark is best in Programming in C : "If you can use a meaningful and helpful name in the program, you will only need additional annotations in an occasional situation. And if you don't use meaningful Name, then additional comments will not make the code easier to understand. "

Another method that minimizes comments is to adopt standard or well-known components:

Printf ("Hello, World!"); // Print "Hello, World" to the screen

This annotation is useless, it is difficult to keep the correctness. The key is not that the standard components must be self-documentized, but they have been properly archived and well known.

SWAP (A, A 1);

Sort (A, A MAX);

Copy (a, a max, ostream_iterator (cout, "/ n"));

SWAP, SORT, and COPY are standard components, so insert additional comments will only disturb the source code and introduce an inaccurate description of standard operations.

The comment is not natural and harmful? Notes are often necessary? But they must be maintained, and they are always more maintenance than the code of the comment. Note should not be apparent, and should not provide information that can do better maintenance elsewhere. Our goal is not an unscrupulous annotation, but to use the least amount of annotations to make the code more easily understood and maintained.

Gotcha Terms 17: Maximal Munch

What if you encounter such an expression?

P -> * MP

Have you handled "Sergeant Operator" [Translation Implication 1]?

Template

Class r {

//.

Friend Ostream & Operator <<< // a Sergeant Operator?

T> (Ostream &, Const R &);

Have you considered the legitimacy of the following expressions?

A B

Welcome to the world of Maximal Munch [Translation 2]. In the previous stage of C compilation, the task of "lexical analysis" module [Translation] "is implemented in the compiler is to open the input flow into" Words "or TOKEN. VERs). When encountered like-> * such a character sequence, the lexical analyzer can identify it into three token (-,>, and *), or two token (-> and *), or a token (-> * ). In order to avoid this unknown condition, the lexical analyzer always recognizes the longest token, and reads as much as possible - this is Maximal Munch.

Expression A B is illegal because it is broken down into A B, which is illegal to apply RVALUE such as A to POST-INCREMENT. If you originally want to do POST-INCREMENT (post-incremental operation) first, add the result of the result of PRE-Increment (initial operation), then you must add at least one space in the expression: A b. If you have a little respect for readers who read your code, you have to introduce another space, although it doesn't have to: A b; additional, no one will blame you to join several circular projections : (A ) ( b).

The problem solved by Maximal Munch is much more than what it produces, but in two common situations, it is a bit annoying. The first case is that when Templates is physically, the parameters it belongs itself is a physical Templates. For example, a person may wish to use a standard library to declare a String Vector's List:

List > lovos; // is wrong!

Unfortunately, the two adjacent right parentheses in the physical expression are interpreted as a shift operator, we will encounter a syntax error. Here you need to add spaces:

List > LOVOS;

The second situation involves the use of DEFAULT Argument Initializers for Pointer Formal Arguments:

Void Process (const char * = 0); // error!

This statement attempts to use the assignment operator * = in the Formal Argument Declaration. This is a speech error. It is a problem with "Wages of Sin", ie, if the author of the code gives this formal argument, there will be no errors. This name can not only provide the best documentation instructions, but also eliminate the Maximal Munch problem:

Void Process (const char * processid = 0);

About the author Stephen C. Dewhurst () is president of Semantics Consulting, Inc. of the southeast of Massachusetts. He specializes in the training of C consultation, high-order C programming, STL and design patterns. Steve is also one of the main lecturers of the C seminar.

annotation

[Translation 1]: Sergeant Operator, this is a very humble statement because the code is originally a Template Function statement. When the results are arranged, the Operator << and the "connected to the Template" Operator <<<, alive icon.

[Translation 2]: Maximal Munch, maximize swallow.

S. DEWHURST, C Gotchas (# 1 and # 17). C 2003 Pearson Education, Inc. All Rights Reserved.

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

New Post(0)