What is a good programmer? Is it a lot of technical details? Or do you understand the underlying programming? Or is the programming speed is faster? I don't think it is. For some technical details and the underlying technology, as long as you see help, check the information can be found. For speed fast, as long as you make more, you will be able to happen. I think a good programmer should have the following qualities: 1. There is a spirit of research, diligent good, and give a non-three. 2, positive attitude, creative thinking. 3. The ability to actively communicate with people, there is team spirit. 4, modesty and cautious, arrogance and arrogance. 5, the code written is high. Including: Code stability, easy reading, standardization, easy maintenance, professional. These are the cultivation of programmers. Here I want to talk about "programming cultivation", which is the 5th point in the above. I think, if I want to know a author, I will see what he wrote. If I want to know a painter, I will see the drawing he draws. If I want to know a worker, I will see what he makes it. Similarly, if I want to understand a programmer, I want to first think that his program code, the program code can see a programmer's quality and cultivation, the program is like a work, qualified procedures The work must be a beautiful picture, a wonderful song, a pleasing novel. I have seen many programs, there is no comment, there is no narrow, the name of the variable name, etc.,,,, No, it is completely destroyed. They are said to be programs, but it is better to "encrypt" on the source program. This kind of programmer should be expelled, because he edited the value, It is far less than the value that needs to be maintained above. Programmers should have programmers, so afraid of tired, no time, but also to be responsible for their own procedures. I would rather want the programmer that is slow, technical, but there is a good writing program style, or the programmer of "destroying" skills. There is a saying that "the word is like a person", I want to see a programmer from the program. Because the program is a programmer's work, the quality of the work is related to the reputation and quality of the programmer. The "cultivation" good programmer must make good procedures and software. There is a idiom called "alone", meaning what you have to do very professional, very careful, if you have to be a "craft", it is a deep person, then, from a very simple work. It seems that you have the characteristics of "craftsman", I think it is not difficult to do a programmer, but it is not easy to do a "programmer". The programming is very simple, but it is difficult to compose quality procedures. I don't discuss excessive technology here, I just want to say something that is easy to ignore, although these things may be fine, if you don't pay attention to these subtle, then he will be very big. The impact of your entire software quality, as well as the implementation of the entire software, the so-called "Thousand Miles of Bius, Destroyed in Ant Accent". "Seeing the truth in the wealth", I can really embody the bottom of a program is just in these subtle. This is the programmer - programming cultivation. I summed up 32 "cultivation" on the program writing with C / C language (mainly C language). Through these, you can write a high quality program, and you will also let the human stains you have Stains, those who have seen your procedure will definitely say: "This person's programming is not bad."
------------------------ 01, copyright and version 02, indentation, space, wrap, blank line, align 03, program notes 04, functions [In] [OUT] Parameters 05, the return of the system call is determined 06, if statement pairs the error 07, the #ifndef 08 in the header file, allocates the memory 09 on the heap, the initialization of the variable 10, H, and C files Use 11, error information 12, common function, and naming number of named 14, function name, and variable name in the circulatory statement, the pass value of the variable name, the passage of the function, and modify the cultivation of the person program 16, put the same or near The same code forms function and macro 17, brackets in the expression, the number of Const 19 in the function parameters, the number of parameters of the function 20, the return type of the function, do not omit 21, the use of the GOTO statement 22, macro use 23, Static Use the code size 25 in the function, the use of TypeDef 26, for the constant declaration macro 27, do not perform order 29, ||, and &&'s statement to execute the order 29, try to use for for why , Please sizeOf type instead of variable 31, don't ignore Warning 32, write debug and release version of programs 1, copyright and version ----- good programmer gives yourself, each file, Note copyright and version.
For C / C files, the file head should have a comment like this: / ******************************** *************************************** * * file name: network name: network.c * * file Description: Network Communication Function Set * * Create: Hao Chen, February 3, 2003 * * Version Number: 1.0 * * Modify Record: * * ****************** *********************************************************** **** / and for functions, there should also be similar to such a comment: / * ============================= ============================================= * * function name: xxx * * parameter: * * Type Name [ IN]: descripts * * description: * * * * .............. return value: success TRUE, FALSE * * failure to throw an exception: * * author: ChenHao 2003/4 / 2 * ================================================== ================ * / Such a description can make people have a function, one file has a general understanding, which is very easy to read, and easy maintenance. benefit. This is a good start. 2, indent, space, wrap, blank line, alignment -------------- i) indentation should be done every program, as long as the program is programs, you should know This, but I still have seen the procedure that does not indent, or the procedure that is indent, if your company also has a programmer who writes the program, please open him without hesitation, and destroys the sin of the source Prosecution of him, but he still compensates that the mental loss fees for those who have read his procedures. Indent, this is an incumbent rule, and I will retrieve it, a indentation is generally a Tab key or 4 spaces. (Best use of Tab) ii) space. Does the space will give the program? No, effective use of spaces can make your program read more and pleasing. Not a pile of expressions are squeezed together.
Take a look at the code below: HA = (HA * 128 * Key )% Tabptr-> size; ha = (ha * 128 * key )% tabptr-> size; there is a space and no space feeling different. In general, the statement is equipped between the individual operations, and when the function is called, it is equipped with each parameter. Such a banitary and non-added: IF ((HPROC = OpenProcess) {} == NULL) {== NULL) {== NULL) {== NULL) {== NULL) {== NULL) {} III) Retained. Don't write the statement on a line, this is very bad. Such as: for (i = 0; i '9) && (a [i] <'a' || a [i]> 'z')) Break; I copy, this is no space, no wrap What is the program written? Plus spaces and wraps. For (i = 0; i IF ((A [i] <'0' || a [i]> '9') && (a [i] <'a' || a [i]> 'z') How much is it? Sometimes, when the function parameters are more, it is best to go, such as: CreateProcess (Null, Cmdbuf, Null, Null, Binh, Dwcrtflags, Envbuf, Null, & SistartInfo, & Prinfo); Conditions The statement should also be wrap when necessary when necessary: if (CH> = '0' || CH <= '9' || CH> = 'A' || CH <= 'Z' || CH> = 'A' || CH <= 'z') iv) blank line. Don't spoil, the blank line can distinguish between different blocks, blocks, and best to add space lines. Such as: HANDLE hProcess; PROCESS_T procInfo; / * open the process handle * / if ((hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid)) == NULL) {return LSE_MISC_SYS;} memset (& procInfo, 0, sizeof (procInfo)) procinfo.idproc = PID; procinfo.hdproc = hprocess; procinfo.misc | = mscava_proc; return (0); v) alignment. Use the Tab keys to the declaration or comment of your variables, you will make your program look good.
Such as: typedef struct _pt_man_t_ {int numProc; / * Number of processes * / int maxProc; / * Max Number of processes * / int numEvnt; / * Number of events * / int maxEvnt; / * Max Number of events * / HANDLE * Phndevnt; / * array of events * / dword timeout; / * time out interval * / handle hpipe; / * namedpipe * / tchar usr [maxusr]; / * user name of the process * / int Nummsg; / * Number of Message * / int msg [maxmsg]; / * Space for intro process communicate * /} Pt_man_t; how? It feels good. Here mainly tells the story, if you write a pleasing code, the good-looking code will make people feel happy, read the code, not tired, work, neat program code, usually more welcome, more people. Now the hard disk space is so big, don't let your code squeeze together so they will complain that you abuse them. Ok, use "indentation, space, wrap, blank, align" to decorate your code, let them get a row of ordinary organs from there is no order. 3, program comments ------ Develop the habit of writing the program annotation, this is the work that each programmer must do. I have seen that thousands of lines, but there is no row of comments. This is like driving on the road, but there is no road sign. How long does it take? I don't know my intention, I have to spend a few times, I understand that this kind of people who waste others and their own time are the most compussia. Yes, you may say, you will write a comment, really? The writing of the comment can also see a programmer's skill. Generally speaking, you need to write a note at least in these places: The annotation of the file, the comment of the function, the comment of the variable, the comment of the algorithm, the program comment of the function block. Mainly to record what is your program? What is your intent? What is your variable used? and many more. Don't think about it, there are some algorithms that it is difficult or written. It can only be aimed. I admit that there is this situation, but you have to write it, just can train your own expression. The ability to express the technicians of the kind of technicians who are stuffy, you have a high technology, if you express your ability, your technology will not be able to get full. Because this is a team's era. Ok, say the technical details of several comments: i) I don't agree with the row bet ("//") than the block annotation ("/ * * /"). Because some old versions of the C compiler do not support row notes, for your program's portability, please try to use block comments. II) You may not be nested by the block annotation, then you can use the precompilation to complete this feature. Use the code enclosed in "#IF 0" and "#ndif", will not be compiled, and it can be nested. 4, function [in] [out] parameter ----------- I often see this program: funcname (char * str) {int LEN = strlen (str); ..... } char * getUsername (struct user * puse) {return PUSER-> name;} no! Please don't do this. You should first judge that the pointer to come in is empty.
If the pointer passed is empty, then a big system will crash because of this small function. A better technology is to use assertions (Assert), here I don't have much to say these technical details. Of course, if it is in C , reference is much better than the pointer, but you also need to check each parameter. When writing a function of parameters, the primary work is to perform all the parameters that come in and perform legality checks. The parameters of the outgoing parameters should also be checked. This action should of course be external to the function, that is, after the call is completed, the value it will be checked. Of course, check will be wasted, but for the entire system, "illegal operation" or "Core Dump" error, how many spends this time is still worth it. 5, the return to the system call to determine -------------- Continue the previous one, for some system calls, such as opening the file, I often see that many programmers return to FOPEN not Do any judgment, use it directly. Then find that the content of the file is not read, or you can't write it. Or just judge: fp = fopen ("log.txt", "a"); if (fp == null) {printf ("error: open file error / n"); return false;} There are still many others. For example: Socket returned to the Socket number, Malloc returned by Mall. Please judge what these system calls returned. 6, the IF statement to the error process ----------- I saw you said, this is good to say. Still first look at a program code. IF (CH> = '0' && ch <= '9') {/ * Normal processing code * /} else {/ * Output error message * / printf ("error ... / n"); Return (False); this structure is very bad, especially if "normal processing code" is long, it is best not to use ELSE for this situation. First judge the error, such as: if (CH <'0' || CH> '9') {/ * Output Error message * / printf ("error ... / n"); return (false);} / * Normal processing code * / ... this structure is not very clear? Highlight the wrong condition, let others use your function, you can see unhanectation conditions, so you will be more conscious. 7, #ifndef in the header file ---------- Don't ignore the #ifndef in the first part, this is a very critical thing. For example, you have two C files, both C files include the same header file. When compiling, these two C files should be compiled into a run file, so there is a problem, a large number of statements conflicts. Still put the contents of the header files in #1ndef and #ndif. Whether your header will be referenced by multiple files, you have to add this. The general format is like this: #ifndef
#define
...... #endif
In theory, it can be freely named, but this "identification" of each header file should be unique. The name rules that identify are generally the header file name, and the scribe is added before and after, and "". "In the file is also underline, such as: stdio.h #ifndef _stdio_h_ #define _stdio_h_ ... #ENDIF BTW: Pre-transdermation is very useful. Do you use precompile?) 8 "HEAP" is not very clear. People who include some barborses are not understanding these two concepts. I don't want to say more about these two things. Simply put, the memory system allocated on the Stack is automatically released, the memory allocated on the HEAP is not released, even if the program exits, the memory is still there. Stack is typically static allocation of memory, and HEAP is generally dynamically allocated. The memory allocated by the Malloc system is allocated from the heap. The memory allocated from the pile must be released by himself. Use free release, or the term - "Memory Leak" (or "Memory Vulnerability") - Memory Leak. Thus, the system's allocated memory will be less and less Mallo, until the system crashes. Let's take a look at the difference between "stack memory" and "stack memory". Stack memory allocation ----- char * allocstrfromstack () {char pstr [100]; return pstr;} 内 分 ----- char * allocstrfromheap (int LEN) {char * pstr; if (len <= 0 Return Null; Return (Char *) Malloc (LEN);} For the first function, the internal presence of the PSTR is released when the function returns. So the return of the char * is nothing. For the second function, it is allocated from the heap, so even if the program is exited, it is not released, so the memory returned by the second function is no problem, which can be used. But must call free release, otherwise Memory Leak! The distribution of memory is easy to cause memory leaks, which is the largest "gith" of C / C . If your program is stable, then Do not appear Memory Leak. So, I still have to pay a thousands of people here, be careful when using the Malloc system function (including Calloc, Realloc). Remember to have a service application on UNIX, there are a few hundred C files compiled, run a good test, etc., the system is Down every three months, and many people can't find the problem. . I have to manually restart the system every two months. This problem is that MeMery Leak is strange, and this problem in C / C will always happen, so you must be careful. A Rational's Detection Work - Purify, you can help you test your programs do not have memory leaks. I promise that the programmer of many C / C projects will have some cold in Malloc or New. When you use Malloc and New, there is a light tight and fearful feeling, you have this kind of cultivation. For Malloc and Free operations: 1) Pairing, there is a malloc, there should be a free.
(C corresponds to new and delete) 2) Try to use on the same layer, do not like the above, Malloc in the function, and free outside the function. It is best to use these two functions on the same call layer. 3) Malloc allocated memory must initialize. The pointer behind free must be set to NULL. Note: Although the current operating system (such as Unix and Win2K / NT) have process memory tracking mechanism, that is, if you have released memory, the operating system will help you release it. However, the operating system still does not release all the memory of Memory Leak in your program, so it is best to do this work. (Sometimes I don't know anything, there is a Memory Leak, and I find a non-sea cut pin in the code of millions of rows. Rational has a tool called Purify, which may be good to check the Memory Leak in the program. 9, the initialization of the variable -------- Joined the above, the variable must be initialized and reused. The C / C compiler will not help you initialize like Java, all need you, if you use no initialized variables, the result is unknown. Good programmers have never initialized the variables before using variables. Such as: 1) MemSet clear operation is performed on the memory allocated by Malloc. (You can use the Calloc assigning a total memory) 2) Initialize the Struct or array assigned on some stacks. (It is best to clearly), but also said that it is back, initialization will also cause a certain overhead of the system running time, so don't initialize all variables, this is meaningless. A good programmer knows which variables need to be initialized, which is not required. Such as: The following situations are not required. Char * pstr; / * A string * / pstr = (char *) malloc (50); if (pstr == null) exit (0); strcpy (pstr, "hello wrold); but if it is one of the following The situation is preferably initialized. (The pointer is a dangerous thing, must initialize) Char ** pstr; / * A string array * / pstr = (char **) Malloc (50); if (pstr == null) exit (0); / * Make pointers in arrays to null * / memset (pstr, 0, 50 * sizeof (char *)); and for global variables, and static variables, they must be initialized when declaring. Because you don't know where it will be used for the first time. So the initial use before use is more unrealistic, so you must initialize them when declaring. Such as: links * plnk = null; / * How to use for the use of NULL * / 10, H and C files for global variables PLNK --------- H files and C files? In general, the H file is a Declare, which is define in the C file. Because the C file should be compiled into the library file (Windows is .Obj / .lib, UNIX is .o / .a), if others want to use your function, then reference your H file, so h file Generally, variables, macro definitions, enumeration, structures, and function interfaces, just like an interface description file. The C file is a detail. The maximum use of H files and C files is declaration and implementation.
This feature should be recognized, but I still see some people like to write the function in the H file, this habit is very bad. (If it is C , for its template function, only the implementation and declarations in the VC are written in a file because the VC does not support the export keyword). Moreover, if the implementation of the function is written in the H file, you have to add the dependency of the header file in makefile, which will make your makefile unregistered. Finally, there is a place that is most important to pay attention to: the global variable with initialization should not be put in the H file! For example, there is a structure for processing error information: char * errmsg [] = {/ * 0 * / "no error", / * 1 * / "open file error", / * 2 * / "failed in sending / received a message ", / * 3 * /" bad arguments ", / * 4 * /" memeroy is not enough ", / * 5 * /" service is down; try limited, / * 6 * / "unknow information", / * 7 * / "a socket Operation Has Failed", / * 8 * / "permission Denied", / * 9 * / "Bad Configuration File Format", / * 10 * / "Communication Time Out", ...... ...}; Please don't put this thing in the header file, because if your header is used by 5 functions (.lib or .a), he is linked in this 5 In .lib or .a, if your program uses a function in these five functions, and these functions have been used in an error message. Then this information will have 5 copies existing in your executter. If your Errmsg is big, and your execution file will become bigger. The correct way to write it into the C file, and then add external declaration on each of the Errmsg's C file headers, let the compiler will take him when the compiler is in the link. Come, there will only be an errmsg exists in the execution file, and so that this is good to package. The most crazy thing I have encountered is that in my target file, this errmsg has a total of 112 copies, and the execution file is about 8m. When I put errmsg in the C file, and after more than a thousand C files with Extern declaration, all the function library files decreased by about 20%, and my executive file was only 5m. There is a little less than 3m. [Note] ----- There is a friend to tell me, this is just a special case, because if errmsg exists in the execution file, speed up the program running speed, the reason is that the multiple copies of errmsg will make the system The memory change is reduced and the efficiency is improved. There is only one errmsg we mentioned here. When a function is to use Errmsg, if the memory is far apart, it will generate a change, but the efficiency is not high.
This statement is not reasonable, but in general, for a relatively large system, errmsg is relatively large, so that the copy caused the size of the execution file to become large, not only adding the system loading time, but also a program in memory More page. For ERRMSG such data, in general, it will not be used frequently when the system is running, so the memory switching is not frequent. Under the trade-off, there is only one efficiency of Errmsg. Even if it is used frequently like LogMSG, the operating system's memory scheduled algorithm will allow such frequently used pages to be stored, so there will be no memory change issues. 11, the process of error information --------- Do you handle error information? Oh, it is not a simple output. Look at the following example: if (p == null) {printf ("Err: The Pointer is Null / N);} Say goodbye to the programming of the student era. This programming is very disadvantageous for maintenance and management, error information, or prompt information, should be unified, not like the above, write into a "hard coded". Article 10 describes a part of this in this regard.
If you want to manage the error message, you have the following processing: / * Declaration error code * / #define err_no_error 0 / * no error * / #define err_open_file 1 / * Open file error * / #define err_send_mesg 2 / * sending a message error * / #define ERR_BAD_ARGS 3 / * Bad arguments * / #define ERR_MEM_NONE 4 / * Memeroy is not enough * / #define ERR_SERV_DOWN 5 / * Service down try later * / #define ERR_UNKNOW_INFO 6 / * Unknow information * / #define ERR_SOCKET_ERR 7 / * Socket operation failed * / #define ERR_PERMISSION 8 / * Permission denied * / #define ERR_BAD_formAT 9 / * Bad configuration file * / #define ERR_TIME_OUT 10 / * Communication time out * / / * declaration error message * / char * Errmsg [] = {/ * 0 * / "no error", / * 1 * / "open file error", / * 2 * / "failed in sending / receiving a message", / * 3 * / "bad arguments" , / * 4 * / "Memeroy Is Not Enough", / * 5 * / "Service is Down; Try Later", / * 6 * / "Unknow Information", / * 7 * / "a socket Operation Has Failed", / * 8 * / "permission denied", / * 9 * / "bad configuration file format", / * 10 * / "communication time out",}; / * declares error code global variable * / Long errno = 0; / * Print error information function * / void perror (char * info) {if (info) {Printf ("% s:% s / n", info, errmsg [errno]); return;} printf ("Error:% S / N", errmsg [errno]);} This is basically ANSI's error handling detail, so you can do this when you have an error in your program: BOOL Checkpermission (Char * Username) {IF (STRCPY (UserName, "Root")! = 0) {errno = err_permission_ndenied; return (false);} ...} main () {... if (! Checkpermission (username)) {PERROR ("mainror () ");} ...} A common, and personally error message processing, so that the same error is the same, the unified user interface, not because the file is opened, and the programmer has a programmer Information, the programmer has an information. And do this, it is very easy to maintain. The code is also easy to read.