This article only provides an idea, a kind of personal experience, designed to use a very vulgar and relatively grounded way, prompting cainiao, why, and how to introduce debug Macros in C language programs, develop and maintain good habits.
Asked about debugging during the interview,
I said: Early printf, later gdb,
Q: How does printf work? Directly change the program?
Answer: Yes ~!
He didn't mention it. I also know that the debug macro should be used, but I didn't want to explain much about it. I recalled the reason why I didn't need the debug macro:
I tried a lot of things in a small program. I changed my mind and program structure and parameter settings for a while. In order to conveniently test some desired C language features or running results, adds the control group to the source program without stopping the modification, which is equivalent to version 1, version 2, and Version x ~~~~ How can I do this without changing printf? print an X for me to see if it is correct-X does not exist just now ~!
Another reason for not using the debug macro is that, to some extent, the idea of the debug macro switch is the same as that of commenting out printf (personal understanding ).
However, the excuse is that the program is too small to write, and it is not realistic to use a bigger project. It is not "too high, is it an excuse for frequent changes or small programs?
I saw a C language interview question yesterday and thought that at least the answer given by the webpage was wrong. So I want to test the question as follows:
What are the following program errors? Int a [60] [250] [1000], I, j, k; for (k = 0; k <= 1000; k ++) for (j = 0; j <250; j ++) for (I = 0; I <60; I ++) a [I] [j] [k] = 0; answer: replace internal and external loop statements
In my opinion, the key to the error lies in the equal sign of k <= 1000 -- it is out of the border. It has nothing to do with the sequence.
========================================================== ========================================================== ========================================
In addition, even if the array caused by k <= 1000 is excluded, in linux, segmentation fault (core dumped), 1000*250*60 byte = 15000000B, the estimated space does not exceed, I don't know why the stack is not enough? I changed 1000 to 100 ~!
However, this is another topic or two other topics. This is a question about the above "Answer". I want to find a way to prove it is wrong, mainly to introduce the debug macro in the process.
========================================================== ========================================================== ========================================
Version 1:Paste the method provided by the "Answer" to change the order of the for Loop only:
int a[60][250][1000],i,j,k; for(i = 0;i< 60;i++) for(j=0;j < 250;j++) for(k = 0;k < =1000;k++) a[i][j][k] = 0; for(i= 0;i < 60;i++) for(j=0;j < 250;j++) for(k = 0;k < =1000;k++) printf("%d\t",a[i][j][k]);
Obviously not ~!
2.0:First, you need to change k <= 1000 to k <1000 to verify my idea and prove the "reference answer" error.
#include
main(){ inta[60][250][1000],i,j,k; for(k = 0;k< 1000;k++) for(j=0;j < 250;j++) for(i = 0; i < 60;i++) a[i][j][k] = 0; for(i = 0;i < 60;i++) for(j=0;j < 250;j++) for(k = 0;k < 1000;k++) printf("%d\t",a[i][j][k]);}
The result is segmentation fault (core dumped.
2.1:Small modification. I guessed the direction and changed 1000 to 100. The program runs normally.
Version 3:K <100, the value assignment statement is changed from 0 to I + j + k, and the for inner layer is added with braces, printing is also upgraded to a more readable format ~
inta[60][250][100],i,j,k; for(i = 0;i< 60;i++) for(j=0;j < 250;j++) for(k = 0;k < 100;k++){ a[i][j][k] = i+ j + k; printf("a[%d][%d][%d] = %d\t",i,j,k,a[i][j][k]); }
These seem natural, but ifAll are modified in a source file.It will be a lot of trouble, andThe original cannot be found., Maybe there is a better way here, that is/* Comment out the code segment */
However, it is still troublesome, the switch is slightly less flexible, and the range is incorrectly commented out. In fact, even if this problem exists, it can still be used, but since it is already so troublesome, why not try to introduce macros to develop a useful good habit? Because this is only a small test, the serious program is much larger.
Fit version:
# Include
// Use macros to activate three versions: array out-of-bounds, array out-of-bounds, but still core dump, and executable (complete) version of a small array. // # Define WRONG_H _ // # define K_EQ_1000_H _ # define K_EQ_100_H_main () {# ifdef WRONG_H _ inta [60] [250] [1000], I, j, k; for (I = 0; I <60; I ++) for (j = 0; j <250; j ++) for (k = 0; k <= 1000; k ++) {a [I] [j] [k] = I + j + k; printf ("a [% d] [% d] [% d] = % d \ t", I, j, k, a [I] [j] [k]) ;}# endif # ifdef K_EQ_1000_H _ inta [60] [250] [1000], I, j, k; for (k = 0; k <1000; k ++) for (j = 0; j <250; j ++) for (I = 0; I <60; I ++) {a [I] [j] [k] = I + j + k; printf ("a [% d] [% d] [% d] = % d \ t", I, j, k, a [I] [j] [k]) ;}# endif # ifdef K_EQ_100 int a [60] [250] [100], I, j, k; for (I = 0; I <60; I ++) for (j = 0; j <250; j ++) for (k = 0; k <100; k ++) {a [I] [j] [k] = I + j + k; printf ("a [% d] [% d] [% d] = % d \ t", I, j, k, a [I] [j] [k]);} # endif}
Although it is helpful, but the real debug may
Coupling DegreeLower, code
RepetitionIt should also be small. In this example, most of the Code is repeated (you can also replace one of the loops with # ifdef and # endif ).
Since you know the direction of improvement, why not try it, because the for sequence is obviously not affected, so it is unified to reduce the coupling degree. However, the k defined in the array is equal to 1000 and 100, which cannot be split and can only be separated. I want to reflect the advantages of the debug macro over the annotation.
First, try to split the code segment and use macro classification for different statements. Second, use | to merge different macros. But there is still a problem: the following form is not available only if there is no else:
#include
#define ORIGINAL_H_//#define K_EQ_1000_H_//#define K_EQ_100_H_#define FINAL_H_main(){#ifdef K_EQ_1000_H_||ORIGINAL_H_ inta[60][250][1000],i,j,k; for(k = 0;k< 1000;k++)#endif#ifdef K_EQ_100_H_ || FINAL_H_ inta[60][250][100],i,j,k; for(k = 0;k< 100;k++)#endif for(j=0;j < 250;j++) for(i = 0; i < 60;i++){ a[i][j][k] = i+ j + k; printf("a[%d][%d][%d] = %d\t",i,j,k,a[i][j][k]); }}
Because I, j, k, and so on all need to be declared and defined. They are in # ifdef and cannot be declared. Even if you have enabled that option, it is not allowed (about the compiler ).
For convenience, I chose a relatively simplified solution-"if with else" and cut down the condition. What should we do? We should determine our situation.
Include
// Eliminate the usage of absolute errors and minor changes. The final focus is on the k size. The full body is 100, and the test body is 1000 (assuming the goal is to find the reason for core dumped) // # define K_EQ_1000_H _ // # define K_EQ_100_H_main () {# ifdef K_EQ_1000_H _ inta [60] [250] [1000], I, j, k; for (k = 0; k <1000; k ++) # else inta [60] [250] [100], I, j, k; for (k = 0; k <100; k ++) # endif for (j = 0; j <250; j ++) for (I = 0; I <60; I ++) {a [I] [j] [k] = I + j + k; printf ("a [% d] [% d] [% d] = % d \ t", I, j, k, a [I] [j] [k]);}
This solution is not perfect either. As mentioned in the comment, I have simplified many problems. However, if you want to solve all the statements and differences, you can also, but it will be visually messy ~ It is not constructive. If you really want to do it, because the idea of splitting by sentence difference already exists (for example, the array declaration and the k Part Of The for loop ), split all the other differences you want, and then complete the process for each macro.Splitting one sentence is a bit more advantageous than commenting. If one or two sentences have many splits and hundreds of rows, then one sentence is dead.
Now, you just need to uncomment the running result of the macro version ~ In this example, the macro function can run both the wrong version to test and the "Ultimate Form" to complete the task, isn't the debug macro a switch?
Although it is a rough method of use, it is not the usage and tutorial of "original manufacturer" debug ", but it is also a way of thinking,More in line with our gradual learning rules-- You encounter difficulties or low efficiency, and then solve this obstacle or improve efficiency. In fact, the most important thing is to look for opportunities to introduce various functions, exercise skills, and maintain good habits.
The time relationship has not been carefully considered and verified, and relevant materials have been consulted. If you have any errors, please correct them. If you are interested, you can discuss them with me.
Thank you.