From deep C (and C + +) by Olve Maudal and Jon Jagger, itself half bucket of water, if any netizen found fault, message points out:
Programming is difficult, and it is especially difficult to correctly use C + + programming. Indeed, it is difficult to see the code that is well defined and written in both C and C + +. Why does a professional programmer write such a code. Because most programmers don't have a deep understanding of the language they are using. They have a grasp of language, and sometimes they know that something is undefined or unspecified, but often do not know why. This slide, we'll look at a few small C + + code snippets, and we'll talk about the basic principles, limitations, and design philosophies of these great and dangerous languages.
Suppose you are going to recruit a C program for your company, your company is embedded development, so you have to interview some candidates. As part of the interview, you want to know whether the candidate has a deep enough knowledge of the C language, so you can start your conversation by interviewing:
int main ()
{
int a=;
printf ("%d\n", a);
}
What happens when you try to compile a link to run this code.
A candidate might answer this:
You must include the header file through the #include<stdio.h>, and return 0 at the back of the program; Then compile the link, and the run will print 42 on the screen.
Yes, the answer is very correct.
But another candidate may take the opportunity to show that he has a deeper understanding of C, and he will answer:
You may need to #include<stdio.h> This header file shows the function printf (), which runs through a compiled link, and outputs 42 on standard output, followed by a new line.
He then further explained:
The C + + compiler will reject this code because the C + + requirement must display all the functions defined. However, there are some special C compilers that create an implicit definition for the printf () function to compile the file into the destination file. When you link to the standard library, it looks for the definition of the printf () function to match the implicit definition.
Therefore, the above code will also compile, link and then run, of course, you may get some warning information.
The candidate is on the run and may also say, if it is C99, the return value is defined to indicate whether the running environment is successful, as c++98. But for older versions of C, such as ANSI C and K&r C, the return value in the program would be some undefined garbage value. But the return value is usually passed by a register, and if I return a value of 3, I'm not surprised because the printf () function returns a value of 3, which is the number of characters that output to the standard output.
When it comes to the C standard, if you want to show that you care about C, you should use Intmain (void) as your program entry, because that's what the standard says.
c, use void to indicate that no parameters are required in a function declaration. If this declares the function int f (), that means that the F () function can have any number of arguments, although you may intend to state that the function does not require arguments, but this is not what you intended. If you mean that a function does not require arguments, explicit use of void has no harm.
int main (void)
{
inta = n;
printf ("%d\n", a);
}
Then, a little ostentatious, the candidate went on to say:
If you allow me to be a bit pedantic, then this program is not fully compliant with the C standard, because the C standard indicates that the source code must end with a new line. Like this:
int main ()
{
inta = n;
printf ("%d\n", a);
}
Also, don't forget to explicitly declare the function printf ():
#include <stdio.h>
int main (void)
{
inta = n;
printf ("%d\n", a);
}
Now it looks a bit like a C program, right.
Then, compile, link, and run this program on my machine:
$ cc–std=c89–c foo.c
$ ccfoo.o $/a.out $
echo $?
3
$ cc–std=c99–c foo.c
$ ccfoo.o $
/a.out $
echo $?
0
What's the difference between those two candidates? Yes, there's no big difference, but you're obviously more satisfied with the answer to the second candidate.
Maybe this is not really a candidate, perhaps is your staff, hehe.
Giving your employees an in-depth understanding of the language they are using will be of great help to your company.
Let's take a look at how deep they are to C + + understanding ...
#include <stdio.h>
void foo (void)
{
int a = 3;
++a;
printf ("%d\n", a);
}
int main (void)
{
foo ();
Foo ();
Foo ();
}
All two candidates will be, output three 4. Then look at this program:
#include <stdio.h>
void foo (void)
{
static int a = 3;
++a;
printf ("%d\n", a);
}
int main (void)
{
foo ();
Foo ();
Foo ();
}
They will say, output 4,5,6. And then look:
#include <stdio.h>
void foo (void)
{
static int A;
++a;
printf ("%d\n", a);
}
int main (void)
{
foo ();
Foo ();
Foo ();
}
The first candidate questions that a is undefined and you get some junk value.
You say: No, it will output 1,2,3.
Candidate: why.
You: Because static variables are initialized to 0.
The second candidate would answer:
The C standard notes that static variables are initialized to 0, so output 1,2,3.
Then look at the following code fragment:
#include <stdio.h>
void foo (void)
{
int A;
++a;
printf ("%d\n", a);
}
int main (void)
{
foo ();
Foo ();
Foo ();
}
First candidate: You'll get 1,1,1.
You: Why do you think so?
Candidate: Because you said he would initialize to 0.
You: But this is not a static variable.
Candidate: Oh, then you'll get the junk value.
The second candidate comes in and he answers:
The value of a is not defined and you will theoretically get three garbage values. But in practice, because automatic variables are generally allocated in the run stack, three times when the Foo function is called, A is likely to have the same memory space, so you will get three consecutive values if you do not compile any optimizations.
You: On my machine, I did get 1,2,3.
Candidate: That's not surprising. If you run in debug mode, the runtime mechanism will initialize your stack space to 0.
The next question is why the static variable is initialized to 0, and the automatic variable is not initialized.
The first candidate apparently did not consider the issue.
The second candidate responded by:
The cost of initializing the automatic variable to 0 will increase the cost of the function call. C language is very focused on the speed of operation.
However, the global variable area is initialized to 0 and costs are generated only when the program starts. This may be the main reason for this problem.
More precisely, C + + does not initialize static variables to 0, they have their own default values, which means 0 for native types (native types).
Let's look at a piece of code:
#include <stdio.h>
static int A;
void foo (void)
{
++a;
printf ("%d\n", a);
}
int main (void)
{
foo ();
Foo ();
Foo ();
}
First candidate: Output 1,2,3.
You: Well, why.
Candidate: Because A is a static variable, it is initialized to 0.
You: I agree with ...
Candidate: Cool ...
What about this piece of code:
#include <stdio.h>
int A;
void foo (void)
{
++a;
printf ("%d\n", a);
}
int main (void)
{
foo ();
Foo ();
Foo ();
}
First candidate: Rubbish, rubbish, rubbish.
You: Why do you think so?
Candidate: Is it going to be initialized to 0.
You: Yes.
Candidate: Then he may output 1,2,3.
You: Yes. Do you know the difference between this piece of code and the previous one? There is the static section.
Candidate: not quite sure. And so on, the difference between them is the private variables and the public variables.
You: Well, almost.
Second candidate: it will print 1,2,3. Variable or statically allocated, and initialized to 0. And the front difference: um. This is related to the linker (linker). The variables here can be accessed by other compile units, that is, the linker can let other target files access the variable. But if the static is added, then the variable becomes a local variable of the compilation unit, and other compilation units cannot access the variable through the linker.
You: Yes. Next, we'll show you some pretty good stuff. Wait:)