C Language Test: I want to be the 0x10 basic problem that embedded programmers should know.

xiaoxiao2021-03-06  40

C language testing is a method necessary and effective in the process of recruiting embedded system programmers. These years, I also participated in many of this test. In this process I realized that these tests can provide many useful information for the interviewer and the interviewer. In addition, the pressure of the interview does not talk, this test is also Quite interesting.

From the perspective of the interviewer, you can learn more about the topic or invigilator. This test is just the topic for displaying the knowledge of the ANSI standard details rather than technical skills? Is this stupid question? If you want to answer a ASCII value of a character. Do you focus on your system calls and memory allocation strategies? This marks that the topic may spend time on the microcomputer without being on the embedded system. If the answer to any of the above questions is "Yes", then I know that I have to consider whether I should do this job.

From the perspective of the interviewer, a test may reveal the quality of the respondent from many aspects: the most basic, you can understand the level of C. Anyway, look at how this person answers the problem he will not be full. Is the candidate to make a wise choice with a good intuition, or is it just a shame? When the candidate is caught in a question, it is to find an excuse, or show the real curiosity of the problem, and see this as a chance to learn? I found this information as useful as their test score.

With these ideas, I decided some questions that truly target embedded systems, I hope that these headaches can help people who are looking for work. These issues are actually encountered in these years. Some of these questions are difficult, but they should give you a little enlightenment.

This test suitable for different levels, most primary levels of candidates are very poor, and experienced programmers should have good results. In order for you to decide some of the preferences, each problem does not assign a score. If you choose these exam questions, please share the score according to your meaning.

Preprocessor

1. Declare a constant with pre-processing instruction #define, to indicate how many seconds in 1 year (ignore leap year issues)

#define seconds_per_year (60 * 60 * 24 * 365) UL

I want to see a few things here:

• The basic knowledge of #define syntax (for example: cannot end with a semicolon, brackets, etc.)

• Know that the preprocessor will calculate the value of the constant expression, so it is clearer without calculating the actual value for a few seconds instead of calculating the actual value.

• Aware that this expression will overflow a 16-bit machine's integer overflow - therefore use long integer symbols L, telling the compiler that this constant is long.

• If you use UL in your expression, you have a good starting point. Remember, the first impression is very important.

2. Write a "standard" macro min, this macro inputs two parameters and returns a smaller one.

#define min (a, b) ((a) <= (b)? (a): (b))

This test is designed for the following purposes:

• Identify the basic knowledge of #define in the macro. This is very important because until the embedding operation is part of the standard C, the macro is convenient to generate a unique way to embedded code. For embedded systems, in order to achieve the performance, embedded code is often necessary. Methods.

• Difficulties with triple condition operators. This operator has a C language because it makes the compiler produces a code that is more optimized than if-dam, it is important to understand this usage.

• I know how to put parameters in the middle of the macro.

• I also use this question to discuss the side effects of macros, for example: What happens when you write the following code? LeaSt = min (* p , b);

3. What is the purpose of the pre-processor logo #error?

If you don't know the answer, please see the reference 1. This issue is useful for distinguishing a normal buddy and a nerd. Only nerd will read the appendix of the C language textbook to find the answer to this problem. Of course, if you are not looking for a nerd, then the respondent is best to want to know the answer.

INFINITE LOOPS

4. Embedded systems often use an infinite loop, how do you write a dead loop with C?

This problem uses several solutions. My preferred program is:

While (1)

{

?

Some programmers prefer the following scenario:

For (;;)

{

?

This implementation makes me difficult, because this syntax does not have exact expressions. If a candidate gives this as a program, I will use this as a chance to explore the basic principles they do. If their basic answer is: "I have been teaching this, but I have never thought about why." This will leave me a bad impression.

The third solution is to use GOTO

LOOP:

...

Goto loop;

If the subject gives the above scheme, this explanation or he is a compilation language programmer (this may be a good thing) or he is a Basic / Fortran programmer who wants to enter the new field.

Data declarations (Data Declarations)

5. Use the variable A to give the following definition

a) an integer (an integer)

b) a pointer to the integer (a Pointer to an INTEGER)

c) a pointer to the pointer, which pointing to the pointer to a constant number (a Pointer to a Pointer to an inTege)

d) A number of arrays with 10 integers (AN Array of 10 Integers)

e) A array of 10 pointers that point to a integer. (AN Array of 10 Pointers to Integers)

f) a pointer to having 10 integer numbers (a Pointer to an Array of 10 Integers)

g) a pointer to a function, which has a integer parameter and returns a integer (a pointer to a function what takes an integer as an argument and returns an integer)

h) A array with 10 pointers, which points to a function, which has a integer parameter and returns an integer (An Array Of Ten Pointers to Functions Take An Integer Argument and Return An Integer)

the answer is:

a) int a; // an integer

b) Int * a; // a Pointer to an integer

c) int ** a; // a Pointer to a Pointer to an inTeger

d) int A [10]; // AN Array of 10 Integers

e) int * a [10]; // an array of 10 Pointers to Integers

f) int (* a) [10]; // a Pointer to an Array of 10 Integers

g) int (* a) (int); // a Pointer to a function a Takes an integer argument and returns an intergerh) INT (* a [10]) (int); // an array of 10 Pointers to functions That take an integer argument and return an integer

People often claim that there are several problems here that I have to turn back the book to answer questions, I agree with this statement. When I wrote this article, in order to determine the correctness of the grammar, I really checked a book. But when I was interviewed, I expected to be asked (or a similar problem). Because in this time of the interview, I am sure I know the answer to this question. If you don't know all the answers (or at least most of the answers), then you have not prepared for this interview. If the interviewer is not prepared for this interview, then he can prepare?

Static

6. What is the role of keyword static?

This simple problem is very fewer people answering complete. In C language, there are three obvious roles in keyword static:

• In the function body, a variable that is declared is static in this function to maintain its value unchanged during the call.

• In the module (but outside the function), a variable that is declared as static can be accessed by the function used in the module, but cannot be accessed by the module other functions. It is a local global variable.

• In the module, a function that is declared static can only be called by other functions within this module. That is, this function is restricted to declare the local range of its module.

Most candidents can answer the first part correctly, and some can answer the second part correctly, and they can understand the third part. This is a serious disadvantage of a candidate because he obviously does not know the benefits and importance of localized data and code range.

Const

7. What is the meaning of keyword const?

As long as I hear the interviewer: "Const means constant", I know that I am in harmony with a happening. Last year, Dan Saks has fully summarized all the use of Const in his article, so each reader of ESP (Translator: Embedded Systems Programming) should be very familiar with what CONST can do and can not do. If you have never read That article, just say that constings mean that "only reading" is ok. Although this answer is not a complete answer, I accept it as a correct answer. (If you want to know more detailed answers, read the Saks' article.)

If the candier can answer this question correctly, I will ask him an additional question:

What does the following statement mean?

Const Int A;

Int const a;

Const Int * a;

INT * Const A;

Int const * a const;

/ ****** /

The first two effects are the same, A is a constant number. The third means that A is a pointer to the constant number (that is, the integer is unmodified, but the pointer can be). The fourth meaning A is a normally pointer to integer (that is, the integer of pointer points to modify, but the pointer is unmodified). The last one means A is a normally pointer to the constant number (that is, the integer of the pointer is not modified, while the pointer is not modified). If the candidate can answer these questions correctly, he will leave me a good impression. In the way, maybe you may ask, even if you don't need the keyword const, it is easy to write the correct program, then why should I value the keyword const? I also have the following reason: •; Keyword const is to convey very useful information for people who read your code, in fact, declare a parameter is to tell the user's application purposes. If you spend a lot of time to clean up the garbage left by other people, you will soon learn this extra information. (Of course, I know that the garbage that will be leaving with Const will make others cleaned up.)

• By adding some additional information to the optimizer, using the keyword const may produce a more compact code.

• Reasonably uses the keyword const to make the compiler naturally protect those parameters that do not want to be changed to prevent their unintentional code modifications. In short, this can reduce the emergence of bugs.

Volatile

8. What is the meaning of keyword volatile? And give three different examples.

A variable defined as Volatile is that this variable may be unveasuating, so that the compiler will not assume that this variable is worth the value. Precisely said that the optimizer must reread the value of this variable every time when used this variable, rather than using the backup stored in the register. Below is a few examples of the volatile variable:

•; hardware registers of parallel equipment (such as status register)

• Non-Automatic Variables in an interrupt service subroutine (non-automatic variables)

• Targes shared by several tasks in multi-threaded applications

People who can't answer this question will not be hired. I think this is the most basic problem that distinguishes C programmers and embedded system programmers. Engaging embedded guys often deal with hardware, interrupts, RTOS, etc., all of which require Volatile variables. I don't know how to volatile will bring disasters.

Suppose is the problem that the interviewer has answered this is a problem (um, if you will be like this), I will have a little more, look at this guy, I know the full importance of Volatile.

• Is a parameter can be both CONST or Volatile? Explain why.

• Can a pointer be Volatile? Explain why.

• What is wrong with the following functions:

INT Square (Volatile Int * PTR)

{

Return * ptr * * PTR;

}

Here is the answer:

•; Yes it is. An example is a read-only status register. It is volatile because it may be unable to change. It is const because the program should not try to modify it.

•; Yes it is. Although this is not very common. An example is when a serving subroutine is robotic to a pointer to a buffer.

• This code is a bit a bit state. The purpose of this code is to return the square of the pointer * PTR point to the value of the value, but because * Ptr point to a Volatile type parameter, the compiler will produce the following code:

INT Square (Volatile Int * PTR)

{

INT A, B;

a = * PTR;

B = * PTR;

Return a * b;}

Since the value of * PTR may become unexpected, A and B may be different. As a result, this code may return the square value you expect! The correct code is as follows:

Long Square (Volatile INT * PTR)

{

Int a;

a = * PTR;

Return A * a;

}

Bit manipulation

9. The embedded system always wants to operate the variable or register. A integer variable A is given, write two of the code, the first setting A Bit 3, the second clear A Bit 3. In the above two operations, keep other bits unchanged.

Three basic reactions to this issue

• I don't know how to start. The subject has never done any embedded system.

Use Bit Fields. Bit Fields is throwing things to C language dead angles, which guarantees that your code is unmiglable between different compilers, and it is also guaranteed that your code is unused. I have recently unfortunately seen the driver written by Infineon for its more complex communication chip, which uses Bit Fields so it is completely useless, because my compiler uses other ways to implement Bit Fields. From moral speaking: Never let a non-embedded guy stick the actual hardware.

• Download with #defines and bit masks. This is a method with extremely high portability and should be used. The best solution is as follows:

#define bit3 (0x1 << 3)

Static Int A;

Void set_bit3 (void) {

a | = bit3;

}

Void clear_bit3 (void) {

A & = ~ bit3;

}

Some people like to define a mask simultaneously for setting and clear values, which is also acceptable. I hope to see a few points: indicating constants, | = and & = ~ operations.

Access fixed memory location (Accessing Fixed Memory Locations)

10. Embedded systems often have the characteristics of requesting programmers to access a particular memory location. In a project, the value of an integer variable having an absolute address is 0x67A9 is required to be 0xAA66. The compiler is a pure ANSI compiler. Write code to complete this task.

This issue tested whether you know that a constant number of forced conversion is a pointer to a pointer in order to access an absolute address. The implementation of this problem is different from the personal style. A typical similar code is as follows:

INT * PTR;

PTR = (int *) 0x67a9;

* PTR = 0xAA55;

A more obscure approach is:

A more embarrassing method is:

* (int * const) (0x67a9) = 0xAA55;

Even if your taste is closer to the second solution, I suggest you use the first solution during the interview.

Interrupted (Interrupts)

11. Interrupt is an important part of the embedded system, which has led many compilers to provide an extension - allowing standard C to support interrupts. The real thing is that a new keyword __interrupt is generated. The following code uses the __interrupt keyword to define an interrupt service subroutine (ISR), please comment on this code.

__interrupt Double Compute_Area (Double Radius)

{

Double Area = Pi * Radius * Radius;

Printf ("/ Narea =% f", Area;

Return Area;

}

This function has too much mistake, so that people don't know why:

• The ISR cannot return a value. If you don't understand this, then you will not be hired. •; ISR cannot pass parameters. If you don't see this, you are hired and equivalent to the first item.

• In many processors / compilers, floating points are generally unreportable. Some processors / compilers need the amount of registers in the stack, some processor / compilers are not allowed to do floating point operations in ISR. In addition, the ISR should be short and efficient, which is unwise to do floating point operations in ISR.

• The third point of the pulse is associated with PRINTF () often has a problem of re-entry and performance. If you lose your third and fourth points, I will not be too hard to be. Needless to say, if you can get two points, then your employment prospect is getting better and bright.

*****

Code Examples

12. What is the output output below, why?

Void foo (void)

{

Unsigned int a = 6;

INT b = -20;

(A B> 6)? PUTS ("> 6"): PUTS ("<= 6");

}

This problem tests if you know how to automatically transform in C language, I found some developers to understand these things. Anyway, the answer to this unsigned integer problem is "> 6". The reason is that all operands are automatically converted to non-symbol type when there is a symbol type and unsigned type. Therefore, -20 becomes a very large positive integer, so the result is greater than 6. This is usually important for embedded systems that should be frequently used in unsigned data types. If you answer this question, you will not get the edge of this job.

13. Evaluate the following code snippet:

Unsigned int zero = 0;

Unsigned int compzero = 0xfff;

/ * 1'S Complement of Zero * /

For a processor that is not 16-bit, the above code is incorrect. Should be written as follows:

Unsigned int compzero = ~ 0;

This problem really exposes whether the candidate knows how to process the leader. In my experience, a good embedded programmer understands the details of the hardware and its limitations, but the PC machine often uses hardware as an unavoidable trouble.

At this stage, the respondent or completely dreamed or is full of confidence. If it is obvious that the test is not very good, then this test is over here. But if it is clear that the respondents are doing well, then I will throw the following additional problems, these problems are more difficult, I want to be very excellent at the advice. I would like to see how the respondents cope with the problem, not the answer. Anyway, you will be this entertainment ...

Dynamic Memory Allocation

14. Although unlike non-embedded computers, embedded systems still have the process of dynamically allocating memory from the heap (HEAP). Then, in the embedded system, what is the problem that the dynamically allocated memory may happen?

Here, I expect that the candidate can mention the problem of memory fragmentation, debris collection, and the time of the variable. This topic has been widely discussed extensively in the ESP magazine (mainly P.J. Plauger, his explanation far exceeds any explanation I can mention here), all of you look back, look at these magazines! Let the respondents enter a false safe feeling, I took this small program:

What is the output of the code snippet below, why?

Char * PTR;

IF ((ptr = (char *) malloc (0)) == NULL)

Else

PUTS ("Got A Null Pointer";

PUTS ("Got a Valid Pointer");

This is an interesting question. Recently, a colleague in my colleague was introduced to the function Malloc, and I thought of this problem after I got a legal pointer. This is the code above, the output of this code is "Got a Valid Pointer". I use this to start discussing such a problem to see if the interviewer thinks that the library routine is correct. Getting the right answer is important, but the method of solving the problem and the basic principles you make decisions are more important.

Typedef

:

15 Typedef is frequently used in C language to declare a synonym of an existing data type. You can also do a similar thing with a preprocessor. For example, think about the following example:

#define DPS Struct S *

Typedef struct s * tps;

The intent of the above two cases is to define DPS and TPS as a pointing structure S pointer. Which method is better? (If any, why?

This is a very subtle problem, anyone answers to this issue (just reason) should be congratulated. The answer is: Typedef is better. Think about the example below:

DPS P1, P2;

TPS P3, P4;

The first extension is

Struct S * P1, P2;

.

The above code definition P1 is a pointing structure, P2 is an actual structure, which may not be what you want. The second example correctly defines two pointers of P3 and P4.

涩 涩 语

16. C language agrees some shocking structure, the following structure is legal, if it is what it do?

INT A = 5, B = 7, C;

C = a b;

This issue will be a pleasant end of this test. No matter what you don't believe, the above example is completely syntax. The problem is how the compiler handles it? The compiling author of the level will actually argue this issue. According to the most processed principles, the compiler should be able to handle all legal uses as possible. Therefore, the above code is processed:

C = a b;

Therefore, this code is taken behind a = 6, b = 7, c = 12.

If you know the answer, or guess the correct answer, do well. If you don't know the answer, I don't take this as a problem. I found that this problem is that this is a good topic about code writing style, code readability, code modality.

Ok, guys, you have already finished all tests. This is my C language test, I finished writing it with a happy mood, I hope you have finished reading the same mood. If you think this is a good test, then try to use your job in the process of finding your work. God knows maybe for a year or two, I don't do now, and I need to find one.

Nigel Jones is a consultant, now live in Maryland, when he is not underwater, you can find him in multiple range embedded projects. He is very happy to receive the reader's letter, his Email address is: najones@compuserve.com.

References

•; Jones, Nigel, "In Praise of The #Error Directive," Embedded Systems Programming, September 1999, P. 114.

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

New Post(0)