C Programming Interview Questions for Freshers (2026) — with Answers

Updated August 2026

C is the subject where an interviewer can tell in two questions whether you learned syntax or understood memory, and that is precisely why it is still asked. Almost every C question is a memory question wearing different clothes: what a pointer holds, where a variable lives, what survives a function returning, what happens when you free something twice. Candidates who see that pattern find the subject small. Candidates who memorise definitions find it endless.

It also matters more for some students than the placement chatter suggests. C is the first language in most Indian engineering curricula, so it is fair game in any fresher interview; but for embedded, VLSI, firmware and core electronics roles — including the Hyderabad semiconductor design centres — it is not a warm-up subject, it is the main one. If you are an ECE or EEE student targeting those roles rather than following your batch into services IT, this page matters more to you than the Java or Python sets do.

The highest-return preparation here is being able to draw memory. A simple picture — stack on one side, heap on the other, a pointer as a box holding an address — answers the majority of what gets asked, and drawing it on the rough sheet while you speak is what separates a candidate who understands from one who recites. Answer each question below in 30–60 seconds and finish with why the behaviour exists.

Frequently asked questions

What is a pointer, and what does it actually contain?

A pointer is a variable whose value is a memory address. It is not the data — it holds where the data lives, which is why it has its own size regardless of what it points to, and why dereferencing with * is a separate operation from reading the pointer itself. Its declared type matters for two reasons: it tells the compiler how many bytes to read when you dereference, and it sets the step size for pointer arithmetic, so adding one to an int pointer moves it by the size of an int rather than by one byte. Draw it as a box holding an arrow — that picture answers most of the follow-ups.

Explain stack versus heap memory.

The stack holds function calls and their local variables. It is allocated and freed automatically as functions enter and return, it is fast, and it is limited in size — deep or infinite recursion exhausts it, which is a stack overflow. The heap is memory you request explicitly with malloc or calloc, it persists until you free it, it is much larger, and it is entirely your responsibility. The consequence that gets asked most: a local array declared inside a function lives on the stack and is gone when the function returns, so returning its address gives a pointer to memory that is no longer valid, while heap memory survives the return and must be freed by someone.

malloc vs calloc vs realloc, and what does free actually do?

malloc takes one size argument and returns a block of uninitialised memory, so it contains garbage. calloc takes a count and an element size, and zero-initialises the block. realloc resizes an existing block, possibly moving it and returning a new address, which is why you must use its return value rather than assuming the old pointer is still valid. free returns the block to the allocator — it does not change your pointer, which still holds the old address and is now dangling, so setting it to NULL after freeing is the standard habit. Always check the return of malloc against NULL, because allocation can fail.

What is the difference between an array and a pointer?

They are not the same thing, though they behave similarly in expressions. An array is a block of contiguous memory, and its name decays to a pointer to its first element in most contexts — which is why passing an array to a function actually passes a pointer, and why the function cannot know its length. A pointer is a separate variable holding an address, and it can be reassigned; an array name cannot. The distinction shows up concretely with sizeof: applied to an array in its own scope it gives the total bytes, but inside a function that received it, sizeof gives the size of a pointer, because that is all the function has.

Is C pass by value or pass by reference?

C is always pass by value — there is no pass by reference in the language. What creates the confusion is that you can pass the value of a pointer, and the function can then modify what that address points to. So a function receiving an int cannot change the caller's variable, while a function receiving an int* can change the pointed-to value but still cannot change which address the caller's pointer holds — unless you pass a pointer to the pointer. Saying "C passes everything by value, including pointers" is the answer that demonstrates you understand it.

What is a dangling pointer, and how does it differ from a wild or NULL pointer?

A dangling pointer holds an address that was valid but is not any more — after the memory was freed, or after the function whose local variable it pointed to returned. A wild pointer is an uninitialised pointer holding whatever garbage was in that memory. A NULL pointer explicitly points to nothing and is safe to test against. The first two are dangerous precisely because using them may appear to work: the memory often still holds the old data, so the bug surfaces later and somewhere else. Initialise pointers, and set them to NULL after freeing.

What is a memory leak, and why does it matter if the program exits anyway?

A leak is heap memory that is allocated and never freed while the pointer to it is lost, so it cannot be released. For a short program it may not matter visibly, since the operating system reclaims everything at exit — which is why students underrate it. It matters in exactly the software C is used for: long-running processes, servers, embedded systems and firmware that run for weeks or years, where a small leak in a repeated code path grows until the system fails. Mentioning that distinction is what turns a textbook answer into a credible one.

What causes a segmentation fault?

Accessing memory you are not allowed to access. The usual causes: dereferencing a NULL or uninitialised pointer, using a dangling pointer after free, running past the end of an array, writing to a string literal, or overflowing the stack through runaway recursion. The useful framing for an interview is that a segfault is the operating system catching you — the more dangerous version of the same mistake is the one that does not crash, silently corrupting memory that is used later, which is why bounds and initialisation discipline matters rather than relying on crashes to find bugs.

strlen vs sizeof for a string — why do they differ?

sizeof is a compile-time operator giving the number of bytes of the type or array, and it includes the terminating null character in a character array. strlen is a runtime function that counts characters until it reaches the null terminator, so it excludes it. For char s[] = "hello", sizeof is 6 and strlen is 5. And if you pass that array into a function, sizeof there gives the size of a pointer, because the array decayed. This one question tests arrays-versus-pointers, the null terminator and compile-time-versus-runtime at once, which is why it is asked so often.

Why do C strings need a null terminator?

Because a C string is just a character array with no stored length, so the only way any function can know where it ends is a sentinel value — the \0 byte. Every standard string function relies on it. This is the source of a whole family of bugs: forgetting to allocate the extra byte for it, overwriting it, or reading a character buffer that was never terminated, all of which cause functions to run past the end of your data. It is also why C string handling is a classic source of buffer overflows and why languages designed later store the length explicitly.

strcpy vs strncpy — which should you use?

strcpy copies until the null terminator with no idea how large the destination is, so if the source is longer than the destination it writes past the end — a buffer overflow, and historically one of the most exploited bug classes in software. strncpy takes a maximum length, which bounds the write, but it has its own trap: if the source is at least as long as the limit, it does not null-terminate the destination, leaving you with a string that has no end. The honest answer is that you use a bounded copy and terminate explicitly, and that knowing strncpy is not automatically safe is the part interviewers are checking.

What are the uses of the static keyword?

Three distinct ones, and being asked to name all three is common. A static local variable keeps its value between calls to the function and is initialised once, because it lives in static storage rather than on the stack. A static global variable or function has internal linkage, meaning it is visible only within its own translation unit — the standard way to keep something private to one file. And in C, unlike C++, that is the full set. The unifying idea worth stating: static is about lifetime and visibility, not about the value.

Explain the storage classes in C.

auto is the default for local variables and is essentially never written out. register was a hint to keep a variable in a CPU register and is effectively obsolete, since compilers optimise better than the hint does — but you cannot take the address of one. static gives a variable a lifetime spanning the whole program and, at file scope, restricts visibility to that file. extern declares that a variable or function is defined in another translation unit, which is how you share a global across files. The two that actually matter in interviews and in real code are static and extern.

Structure vs union — what is the difference?

A structure allocates space for all its members, so its size is at least the sum of the members plus padding, and every member can hold a value at the same time. A union allocates only enough space for its largest member, and all members share that same memory, so writing one overwrites the others and only the most recently written member is meaningful. Unions exist for memory efficiency and for interpreting the same bytes in different ways — which is why they appear constantly in embedded code and in protocol parsing, the context where an interviewer is most likely to follow up.

What is structure padding, and why does it exist?

The compiler inserts unused bytes between members so each one begins at an address suitable for its type, because processors read aligned memory more efficiently and some architectures fault on unaligned access. The consequence students find surprising is that the size of a structure is often larger than the sum of its members, and that reordering members from largest to smallest can shrink it. This is a favourite question for embedded and systems roles specifically, where memory is constrained and structures map onto hardware or wire formats.

#define vs const — which is better?

#define is handled by the preprocessor, which performs textual substitution before compilation, so it has no type, no scope and is invisible to the debugger — and unparenthesised macro arguments cause classic bugs when the expression is substituted into a larger one. A const variable is a real typed variable the compiler knows about, respects scope, and can be checked. Prefer const for constants and reserve macros for conditional compilation and include guards. Being able to explain why a macro like #define SQ(x) x*x breaks for SQ(a+b) is the follow-up worth having ready.

What is the difference between const char* and char* const?

Read the declaration from the variable name outwards. const char *p is a pointer to a constant character: you cannot modify what it points to, but you can point it somewhere else. char * const p is a constant pointer to a character: you can modify the character, but the pointer itself cannot be reassigned. And const char * const p fixes both. This tests whether you can parse declarations rather than recall a fact, which is why it appears in interviews for systems-facing roles.

What is a void pointer, and what can you do with it?

A void pointer is a generic pointer that can hold the address of any type, which is how functions like malloc return memory without knowing what it will hold, and how qsort works with any array. The trade-off is that it carries no type information, so you cannot dereference it or do pointer arithmetic on it until you cast it to a concrete type — and the compiler cannot check that your cast is correct, which makes it a place where mistakes go unnoticed. It is C's mechanism for generic code, purchased with the loss of type safety.

What are the stages of compilation in C?

Four. The preprocessor handles #include, #define and conditional compilation, producing expanded source. The compiler turns that into assembly. The assembler turns assembly into an object file of machine code. The linker combines object files and libraries, resolving references between them, into an executable. Knowing this makes a whole class of errors readable rather than mysterious: an undefined-reference error is the linker failing to find a definition, which is a different problem from a compiler syntax error, and that distinction is often the actual point of the question.

What is a function pointer, and when would you use one?

A pointer that holds the address of a function, letting you store, pass and call functions dynamically. The syntax is the intimidating part — return type, then the pointer name in parentheses, then the parameter list — but the concept is simple. The uses worth naming are callbacks, where you pass behaviour into a function such as the comparison given to qsort, and dispatch tables that map a value to a handler, which is how state machines and command handlers are commonly written in embedded C. Naming a real use is what makes this answer land.

Is C still worth preparing for 2027-batch placements?

It depends on what you are targeting, and the honest answer splits. For mainstream services IT roles, C is where most Indian curricula begin, so basics can be asked, but your coding rounds and technical interviews will mostly run on Java or Python — prepare C well enough to answer confidently, not exhaustively. For embedded, firmware, VLSI, automotive and core electronics roles, including the semiconductor design centres in Hyderabad and Bengaluru, C is the primary language and the depth expected is real: pointers, memory layout, structure padding, volatile and bit manipulation. ECE and EEE students choosing between the crowded software queue and their branch advantage should weight this accordingly.

Don't just read C programming questions — get asked them

Phiny's AI interviews you on exactly these topics, follows up on weak answers, and tells you what a stronger answer looks like. Text interviews are free and unlimited.

Start a free AI mock interview

How to prepare

Where these questions get asked