Essential C Interview Questions for Embedded Systems: Preprocessor, Macros, and More
This article compiles a comprehensive set of embedded‑C interview questions covering preprocessors, macros, infinite loops, data declarations, static, const, volatile, bit manipulation, fixed‑address memory access, interrupts, code snippets, dynamic allocation, typedefs and obscure syntax, each with detailed explanations and example code.
Preprocessor
Define a constant for the number of seconds in a year using #define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL. The discussion highlights basic #define syntax, the benefit of letting the preprocessor compute constant expressions, the need for unsigned long suffix to avoid overflow on 16‑bit targets, and the use of UL as a good practice.
It also asks for a standard MIN macro that returns the smaller of two arguments, emphasizing the importance of parenthesising parameters: #define MIN(A,B) ((A) <= (B) ? (A) : (B)). The purpose is to test knowledge of macro side‑effects and proper argument handling.
Infinite Loops
Common ways to write an infinite loop in embedded C are shown: while(1) { }, for(;;) { }, and a goto Loop; label. The article notes how each style reveals the candidate’s understanding of low‑level control flow.
Data Declarations
Eight declaration tasks are presented, from a simple integer to pointers to functions. The correct answers are:
int a; int *a; int **a; int a[10]; int *a[10]; int (*a)[10]; int (*a)(int); int (*a[10])(int);static Keyword
Three effects of static in C are explained: (1) a function‑local static variable retains its value between calls, (2) a file‑scope static variable is visible only within that translation unit, and (3) a static function is limited to the defining file.
const Keyword
The article stresses that const means “read‑only” and is more than just a constant. It examines several declarations such as const int a;, int const a;, const int *a;, int * const a;, and const int * const a;, explaining which parts are immutable. Benefits of const include clearer intent, possible optimizer improvements, and reduced bugs.
volatile Keyword
volatiletells the compiler that a variable may change unexpectedly, preventing certain optimizations. Typical examples are hardware registers, variables accessed in an ISR, and shared variables in multithreaded code. The article also answers questions about combining const and volatile, volatile pointers, and why a function like int square(volatile int *ptr) must avoid using the volatile value twice in an expression.
Bit Manipulation
To set and clear bit 3 of an integer a while preserving other bits, the recommended portable solution uses masks:
#define BIT3 (0x1 << 3)
static int a;
void set_bit3(void) { a |= BIT3; }
void clear_bit3(void) { a &= ~BIT3; }Accessing Fixed Memory Locations
For an absolute address 0x67A9, the straightforward ANSI‑C method is:
int *ptr = (int *)0x67A9;
*ptr = 0xAA55;An alternative, more obscure form is *(int * const)(0x67A9) = 0xAA55;, but the first version is recommended in interviews.
Interrupts
The article critiques a sample ISR declared as __interrupt double compute_area(double radius), pointing out four major errors: an ISR cannot return a value, cannot take parameters, floating‑point operations are often non‑reentrant, and using printf inside an ISR is unsafe.
Code Examples
A snippet illustrating integer promotion rules:
void foo(void) {
unsigned int a = 6;
int b = -20;
(a + b > 6) ? puts("> 6") : puts("<= 6");
}The expression evaluates to “> 6” because b is converted to an unsigned value, yielding a large positive number.
Dynamic Memory Allocation
When malloc(0) is called, the implementation may return a non‑NULL pointer; the article shows a test that prints “Got a valid pointer”. It also discusses typical concerns in embedded systems such as fragmentation and lifetime of allocated blocks.
typedef vs. #define
Using typedef to create an alias for a pointer type is safer than a macro because the macro can lead to unintended declarations (e.g., struct s *p1, p2; makes p2 a struct, not a pointer). The typedef version correctly defines both p3 and p4 as pointers.
Obscure Syntax
The expression c = a+++b; is legal and parsed as c = a++ + b;, resulting in a becoming 6, b staying 7, and c being 12 after execution.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
ITPUB
Official ITPUB account sharing technical insights, community news, and exciting events.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
