Embedded C-Pen questions

Source: Internet
Author: User

Preprocessor (preprocessor)
1. Declare a constant with pre-processing directive # # to indicate how many seconds are in 1 years (ignoring leap year issues

#define SECONDS_PER_YEAR (* * 365) UL

I want to see a few things here:
1). #defineBasic knowledge of grammar (for example: cannot end with semicolons, use of parentheses, etc.)
2).Knowing that the preprocessor will calculate the value of a constant expression for you, write out how you calculate the number of seconds in a year instead of calculating
The actual value is clearer and has no cost.
3).Realizing that this expression will make a -The integer number overflow of the bit machine-So we're going to use a long integer symbol.L,Tell the compiler that this constant is long,
The integer number.
4).If you're using it in your expression,UL(for unsigned long integers), then you have a good starting point. Remember, first impressions are heavy.

To.

2. write a "standard" macro min, this macro enters two parameters and returns the smaller one. #define MIN (A) (A) <= (B)? (A): (B) This test is for the purposes set out below: 1). Identifies the basic knowledge that a # define is applied in a macro. This is important because, until the embedding (inline) operator becomes part of standard C, macros are the only way to generate embedded code, and embedding code is often a necessary method for embedded systems to achieve the required performance. 2). Knowledge of the triple condition operator. The reason that this operator exists in the C language is that it allows the compiler to produce code that is more optimized than if-then-else, and it is important to understand this usage. 3). Learn to carefully enclose the parameters in parentheses in a macro 4). I also use this issue to start discussing the side effects of macros, such as: What happens when you write the following code? least = MIN (*p++, b); 3. What is the purpose of the preprocessor identity #error?

#error预处理指令的作用是, when the program is compiled, a compile error message is generated and the compilation is stopped whenever a #error is encountered. Directives are used to report compile-time error messages, and if there is an error in preprocessing, the text after the #error instruction is printed. The syntax format is: #error error-message Note that the macro string error-message not surrounded by double quotes. When the #error instruction is encountered, the error message is displayed, and other content that is predefined by the compiler author may also be displayed. Error-message supported by the system please find the relevant information to get!

dead Loop (Infinite loops)

4. Infinite loops are often used in embedded systems, How do you write a dead loop in C?? This problem is solved with several solutions. My first choice.

The scenario is: while (1) {} Some programmers prefer the following scenario: for (;;) {} This implementation is difficult for me, because the syntax does not exactly express what is going on. If a candidate gives this as a plan, I'll use this as an opportunity to explore the fundamentals of what they do. If their basic answer is: "I was taught to do this, but never thought of why." "It will leave a bad impression on me. The third option is to use Gotoloop:...goto Loop; If the candidate gives the above scenario, it means that either he is an assembly language programmer (which may be a good thing) or he is a Basic/fortran programmer who wants to enter a new field.

Data Statement (declarations)

5. Use variable A to give the following definition

A) An integer number (an integer) b) A pointer to the integer number (a pointer to an integer) c) A pointer to the pointer that points to the number of integers (a pointer to a pointer to an intege R) d) an array with 10 integers (an array of ten integers) e) An array of 10 pointers that point to a number of integers (an array of ten pointers to integers) f) A pointer to 10 array of integers Pointer (a pointer to an array of integers) g) A pointer to a function that has an integer parameter and returns an integer number (a pointer to a function that takes an intege R as an argument and returns an integer) h) A 10-pointer array that points to a function that has an integer parameter and returns an integer number (an array of ten pointers to Func tions that take an integer argument and return an integer) The answer is: a) int A; an integerb) int *a; A Pointer to an INTEGERC) int **a; A pointer to a pointer to an integerd) int a[10]; An array of ten integerse) int *a[10]; An array of ten pointers to INTEGERSF) int (*a) [10]; A pointer to an array of ten INTEGERSG) int (*a) (int); A pointer to a function A, takes an integer argument and returns an integerh) int (*a[10]) (int); An array of ten pointers to functions this take an integer argumEnt and return an integer it is often claimed that there are a few questions here that are to be answered by flipping the book, and I agree with that statement. When I wrote this article, I did check the book in order to determine the correctness of the grammar. But when I was interviewed, I expected to be asked the question (or similar question). Because during the interview, I was sure I knew the answer to the question. If the candidate does not know all the answers (or at least most of them), then he is not prepared for the interview, and if the interviewer does not prepare for the interview, then why should he be prepared?

Static

6. What is the role of the keyword static? Few people can answer this simple question completely.

In the C language, the keyword Static has three distinct effects.: 1). In the function body, a variable declared as static maintains its value in the process of the function being called. 2). Within the module (but outside the function body), a variable declared as static can be accessed by the function used within the module, but not by other functions outside the module. It is a local global variable. 3). Within the module, a function declared as static can only be called by other functions within this module. That is, this function is restricted to the local scope of the module that declares it. Most candidates are able to answer the first part correctly, and part of them can answer the second part correctly, with very few people able to understand the third part. This is a serious drawback for a candidate because he clearly does not understand the benefits and importance of localizing data and code scope.

Const

7. What is the meaning of the keyword const?

As soon as I heard the interviewee say "Const means constant", I knew I was dealing with an amateur. Last year Dan Saks has completely summed up all the usages of const in his article, so ESP (translator: Embedded Systems programming) Every reader should be very familiar with what const can and cannot do. If you've never read that article, you can just say that const means "read-only". Although this answer is not a complete answer, I accept it as a correct answer. (If you want to know more about the answer, read Saks's article carefully.) If the candidate is able to answer the 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 functions are the same, a is a constant integer number. The third means that a is a pointer to a constant integer number (that is, the integer number is not modifiable, but the pointer can). The fourth meaning a is a constant pointer to an integer number (that is, the integer number pointed to by the pointer can be modified, but the pointer is non-modifiable). The last one means that a is a constant pointer to a constant number (that is, the integer number pointed to by the pointer is not modifiable and the pointer is not modifiable). If the candidate can answer these questions correctly, then he leaves a good impression on me. Incidentally, perhaps you may ask, even without the keyword const, it is easy to write the function of the correct program, then why do I value the keyword const? I also have the following several reasons: 1). The function of the keyword const is to convey very useful information to the person who is reading your code, and in fact, declaring a parameter as a constant is to tell the user the purpose of the parameter's application. If you have spent a lot of time cleaning up the rubbish left by others, you will soon learn to thank for the extra information. (Of course, it's very rare for a const programmer to leave rubbish for others to clean up.) ) 2). By giving some additional information to the optimizer, using the keyword const may produce more compact code. 3). The use of the keyword const can make it natural for the compiler to protect those parameters that you do not want to change, and to prevent them from being unintentionally modified by the code. In short, this can reduce the occurrence of bugs.

Volatile

8. What is the meaning of the keyword volatile and gives three different examples. A variable that is defined as volatile is that the variable may be

Unexpectedly, so that the compiler will not assume the value of the variable. Precisely, the optimizer must carefully re-read the value of the variable each time it uses the variable, rather than using the backup stored in the register. Here are a few examples of volatile variables: 1). Hardware registers for parallel devices (e.g., status registers) 2). A non-automatic variable (non-automatic variables) 3) that is accessed in an interrupt service subroutine. A variable that is shared by several tasks in multi-threaded applications The person who cannot answer the question will not be hired. I think this is the most basic problem of distinguishing between C programmers and embedded system programmers. Embedded system programmers often deal with hardware, interrupts, RTOs, and so on, which require volatile variables. Not knowing volatile content will bring disaster. Assuming that the interviewee answered the question correctly (well, wondering if this would be the case), I'll look at it a little bit and see if this guy knows exactly the importance of volatile. 1). Can a parameter be either const or volatile? explain why. 2). Can a pointer be volatile? explain why. 3). What is wrong with the following function: int square (volatile int *ptr) {         return *ptr * *PTR;   Here's the answer: 1). Yes. An example is a read-only status register. It is volatile because it can be changed unexpectedly. It is const because the program should not attempt to modify it. 2). Yes. Although this is not very common. An example is when a service subroutine fixes a pointer that points to a buffer. 3). There's a prank on this piece of code. The purpose of this code is to return the pointer *ptr to the square of the value, but since *ptr points to a volatile parameter, the compiler will produce code similar to the following: int square (volatile int *ptr) {     int a,b;    A = *ptr;    B = *ptr;    return a * b;}   Because the value of *ptr can be unexpectedly changed, A and B may be different. As a result, this code may return to the square value you expect! The correct code is as follows: Long square (volatile int *ptr) {     int a;   A = *ptr;    return a * A;}

bit operation (bit manipulation)

9. The embedded system always wants the user to perform bit operation on the variable or register. Given an integer variable A, write a two-segment code, and the first one sets a

Bit 3, the second clears the bit 3 of a. In the above two operations, keep the other bits intact. There are three basic reactions to this problem 1). Don't know how to do it. The quilt cover has never done any embedded system work. 2). Use bit fields. Bit fields are something that is thrown into the C-language corner, which guarantees that your code is not portable between different compilers, and that your code is not reusable. I recently unfortunately saw Infineon write a driver for its more complex communication chip, which used bit fields so it was totally useless to me because my compiler implemented bit fields in other ways. From the moral: never let a non-embedded guy stick to the edge of the actual hardware. 3). Operate with #defines and bit masks. This is a highly portable approach that should be used. The optimal 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 for setting and clearing values and defining some description constants, which is acceptable. I want to see a few points: Description constants, |=, and &=~ operations. 10. Embedded systems often have features that require programmers to access a particular memory location. In a project, it is required to set an absolute address of

The value of the integer variable of 0x67a9 is 0xaa66. The compiler is a purely ANSI compiler. Write the code to complete the task. This question tests whether you know that in order to access an absolute address it is legal to cast an integral number (typecast) as a pointer. The way this problem is implemented varies with individual style. A typical similar code is as follows: int *ptr;ptr = (int *) 0x67a9;*ptr = 0xaa55; a more obscure method is: * (int * const) (0X67A9) = 0xaa55; Even if your tastes are closer to the second option, I suggest you use the first option in your interview.

Interrupt (interrupts)

11. Interrupts are an important part of the embedded system, which has led to a number of compiler developers providing an extension-allowing standard C to support interrupts. With

Represents the fact that a new keyword __interrupt has been produced. 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 ("area =%f", area); return area;} There are so many mistakes in this function that you don't know where to start: 1. The ISR cannot return a value. If you do not understand this, then you will not be employed. 2). The ISR cannot pass parameters. If you do not see this, your chances of being employed are equal to the first item. 3). In many processors/compilers, floating-point is generally non-reentrant. Some processors/compilers require the register to be placed in the stack, and some processors/compilers do not allow floating-point operations in the ISR. In addition, the ISR should be short and efficient, and it is unwise to do floating-point operations in the ISR. 4). With the 3rd same strain, printf () often has re-entry and performance problems. If you lose the third and 4th, I will not be too difficult for you. Needless to say, if you can get the post two o'clock, then your employment prospects are getting brighter.

Re-entry can generally be understood as A function is called multiple times at the same time, such as the operating system during the process of scheduling, or MCU, processor, and so on when the phenomenon of re-entry occurs.

General floating-point arithmetic is done by specialized hardware, for example, suppose there is a hardware register named float, the intermediate operation used to calculate and store the floating-point number is assumed to have such a function void fun () {//... This function operates on the float register} if it is executed for the first time, a float register is temporarily present for the result of a floating-point operation. be interrupted, and the interrupt function or another process calls the fun function, and the second call of the fun function will be executed in the process destroys the results from the first float register, so when you return to the first fun function, the result is not correct. The fun function can be understood as the printf () function.

Example codeexamples

12. What is the output of the following code and why?

void foo (void) {     unsigned int a = 6;    int b = -20;    (a+b > 6) puts ("> 6") : Puts ("<= 6");}   This question to test whether you understand the principle of automatic conversion of integers in C, I find that some developers know very little about these things. However, the answer to this unsigned integer question is that the output is ">6". The reason is that when there are signed and unsigned types in an expression, all operands are automatically converted to unsigned types. So 20 becomes a very large positive integer, so the expression evaluates to more than 6. This is important for embedded systems that should be used frequently for unsigned data types. If you answer the wrong question, you will not get to the edge of the job. 13. Evaluate the following code snippet:  unsigned int zero = 0;unsigned int compzero = 0xffff;/*1 ' s complement of Zero */  for an int type not 16-bit processing The above code is incorrect, says the device. Should be written as follows: unsigned int compzero = ~0; This problem really reveals whether the test taker understands the importance of processor word length. In my experience, a good embedded programmer is very precise about the details of the hardware and its limitations, but the PC program often takes the hardware as an unavoidable annoyance. At this stage, candidates are either completely depressed or confident. If obviously the candidate is not very good, then the test is over here. But if the candidate does a good job, then I throw out the following additional questions, which are difficult, and I think only very good candidates can do well. To raise these questions, I would like to see more of the candidates coping with the problem rather than the answer. No matter what, you should be the entertainment bar ...

Dynamic Memory allocation (allocation)

PTR = (char *) malloc (0)

Char *ptr;if ((ptr = (char *) malloc (0)) = = NULL) puts ("Got a NULL pointer"); Else puts ("Got a valid pointer"); The above program output under VC6.0 is: Got A valid pointer where the pointer is null, where the allocated space is 0 o'clock and point to where when malloc is used, NULL is returned only if there is not enough memory, or an exception report occurs. malloc (0), the system has helped you prepare the use start address in the heap (not null). However, you cannot write to the address (not disallowed), and if you write, the call to free (PTR) generates an exception report (address corruption). NULL is generally predefined as (void *) 0, which points to 0 addresses. malloc is allocating space on the program stack and will not be 0 address malloc (0) means allocating memory size to zero NULL is not pointing to any entity malloc (0) is also a presence not NULL Typedef
The Typedef is frequently used in the C language to declare a synonym for an existing data type. You can also use a preprocessor to do something similar.

For example, consider the following example: #define DPS struct S *typedef struct S * tPS; The intent of both of these cases is to define DPS and TPS as a pointer to the struct S. Which method is better? (if any) why? This is a very delicate question, and anyone who answers the question correctly (for the right reason) should be congratulated. The answer is: TypeDef is better. Consider the following example: DPS P1,p2;tps p3,p4; The first extension is a struct S * p1, p2; The code above defines P1 as a pointer to a struct, p2 as an actual structure, which may not be what you want. The second example correctly defines the P3 and P4 two pointers.

the Obscure grammar

The C language agrees with some shocking structures, is the following structure legal, and if so what does it do?

int a = 5, B = 7, c;c = A+++b; This question will be done as a happy ending to this quiz. Whether you believe it or not, the above example is entirely grammatical. The question is how does the compiler handle it? A low-level compilation author actually argues that the compiler should be able to handle as many legitimate usages as possible, according to the most processing principle. Therefore, the above code is processed as: c = a++ + B; Therefore, this code is held after a = 6, B = 7, c = 12. If you know the answer, or guess the right answer, do it well. If you don't know the answer, I don't think of it as a problem. I found the biggest benefit of this problem: this is a good topic about code writing style, code readability, code modification

Embedded C-Pen questions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.