In this post, we explore a range of C interview questions that interviewers might ask. This is the first in a series of posts focusing on C interview questions.
If you’re searching for C interview questions or tricky questions in C, you’re in the right spot. I’ve put together a collection of insightful C interview questions after dedicating many hours to their creation. I hope you find these challenging questions both enjoyable and educational. Best of luck with your C interview!
C interview Questions – Set 1
1) What is the difference between declaration and definition of a variable?
Ans:
Declaration of a variable in C
In C language, a variable declaration is used to provide the compiler with assurance at compile time that a variable with a specific type and name exists. This allows the compiler to proceed with further compilation without requiring complete details of the variable. When a variable is declared in C, information is given to the compiler, but no memory is reserved for it. Instead, the declaration serves as a reference that informs the compiler that the variable may be defined within the function or externally.
Note: We can declare a variable multiple times but defined only once.
Example:
extern int data;
extern int foo(int, int);
int fun(int, char); // extern can be omitted for function declarations
Definition of a variable in C
The definition of a variable involves the allocation of storage for it. In other words, a variable definition instructs the compiler where and how much storage should be created for the variable. Generally, definition and declaration occur at the same time, but this is not always the case.
Example:
int data;
int foo(int, int) { }
Note: When a variable is defined, there is no need to declare it, but the reverse is not true.
2) What is the difference between global and static global variables?
Ans:
In C programming, the terms “global variable” and “static global variable” both refer to variables that are declared outside of all functions (typically at the top of the source file). However, they differ in terms of visibility and linkage, which influences how they are accessed within a program and across multiple files. Here’s a detailed comparison:
Global Variables
- Definition: A global variable is declared outside of any function and can be accessed from any function within the same file or other files that include a declaration for it.
- Scope: The scope of a global variable is the entire program. All functions across different files can access the global variable if it is declared properly (for instance, using an
extern
keyword in other files). - Lifetime: Global variables are initialized when the program starts and are destroyed when the program ends.
- Visibility: Global variables have external linkage, meaning they can be accessed from any other file in the project, provided there is an external declaration (using
extern
). - Example:
int globalVar = 10; // Global variable declared at the top of a file
void function() {
printf("%d\n", globalVar); // Access global variable
}
Static Global Variables
- Definition: A static global variable is also declared outside of any function but includes the
static
keyword, modifying its linkage. - Scope: While the scope remains the entire program in terms of lifetime, its accessibility is restricted to the file in which it is declared.
- Lifetime: Like global variables, static global variables are initialized at the start of the program and exist until the program terminates.
- Visibility: Static global variables have internal linkage. This means they are only visible to functions within the same source file and cannot be accessed directly from other files.
- Example:
static int staticGlobalVar = 20; // Static global variable
void function() {
printf("%d\n", staticGlobalVar); // Access static global variable
}
Summary
- Global vs. Static Global Variables:
- Global variables are accessible from any file within a project, making them useful for sharing data between different parts of a program.
- Static global variables are only accessible within the file they are declared in, effectively making them private to that file. This helps in preventing namespace pollution and inadvertent access or modification from other parts of the program.
Both types of variables are useful in different programming scenarios. Choosing between a global and a static global variable depends on the desired scope and the need to restrict access to the variable from other parts of the program.
3) What are storage classes in C language?
Ans:
The extent (lifetime) and scope (visibility) of a variable or function within a program are determined by storage classes. A specific location in memory, where the variable’s value is stored in the form of bits, is allocated to each variable. The decision of where these variable values are stored, such as in a CPU register, stack memory, BSS, or DS, is made by the storage classes.
There are four storage classes available in C
- auto
- static
- extern
- register
i. auto
- Keyword:
auto
- Scope: Local to the block in which the variable is defined.
- Lifetime: The variable is automatically allocated when the block is entered and deallocated when the block is exited.
- Storage Location: Typically on the stack.
- Usage: It is the default storage class for local variables.
ii. static
- Keyword:
static
- Scope: If used with global variables, the scope remains limited to the file in which it is declared. For local variables, the scope remains within the block, but the variable persists for the life of the program.
- Lifetime: The variable is initialized only once and exists till the termination of the program.
- Storage Location: Typically in the data segment, not on the stack.
- Usage: Useful for maintaining state between function calls without making the variable global.
iii. extern
- Keyword:
extern
- Scope: Global. Used to access variables defined in another file or earlier in the same file.
- Lifetime: The lifetime is the same as that of the variable being accessed.
- Storage Location: Depends on where the variable is defined initially.
- Usage: Used to declare a global variable or a function that is implemented in another file.
iv. register
- Keyword:
register
- Scope: Local to the block in which the variable is defined.
- Lifetime: Same as
auto
; exists only within the block in which it is declared. - Storage Location: The compiler may store it in a register instead of RAM for faster access, though this is merely a request to the compiler, not a guarantee.
- Usage: Suggests to the compiler that the variable will be heavily used and that it should attempt to optimize its storage for speed.
For more details, you can see below-mentioned articles,
- Storage classes in C.
- Memory Layout of C program.
4) Differentiate between an internal static and external static variable?
Ans:
In C programming, the static
keyword can be used in two contexts that affect the visibility and linkage of variables: internal static variables and external static variables. Here’s how they differ:
Internal Static Variables
- Definition: An internal static variable is declared within a function or a block with the
static
keyword. - Scope: The scope of the variable is limited to the block or function in which it is declared. It is not accessible outside of this block or function.
- Lifetime: The lifetime of an internal static variable extends across the entire runtime of the program. It is initialized only once and retains its value between function calls.
- Visibility: Internal static variables are not visible outside of their function or block, effectively making them private to that block.
- Example:
void function() {
static int count = 0; // count retains its value between calls
count++;
printf("%d\n", count);
}
Each time function()
is called, count
retains its last value and is incremented.
External Static Variables
- Definition: An external static variable is declared outside of all functions, typically at the top of a file.
- Scope: The scope of the variable is limited to the file in which it is declared due to its static nature.
- Lifetime: Like internal static variables, external static variables also exist for the duration of the program’s execution and are initialized only once.
- Visibility: Even though declared outside any function, external static variables are not accessible from other files. This limits their visibility to the file in which they are declared, unlike regular global variables that are accessible from other files.
- Example:
static int fileLevelVariable = 0; // Only accessible within this file
void increment() {
fileLevelVariable++;
}
void print() {
printf("%d\n", fileLevelVariable);
}
fileLevelVariable
can be accessed and modified by any function within the same file but not beyond that.
Summary
- Internal vs. External:
- Internal static variables are confined to the function or block where they are declared. They help maintain state within that context across multiple invocations of the function or block.
- External static variables are limited to the file where they are declared, providing a private, file-level scope. They are useful for maintaining state across different functions within the same file without exposing the variable to other files, unlike global variables.
Both types of static variables share the characteristic of preserving their value throughout the life of the program and being initialized only once, but their scope and visibility differ significantly.
5) What is the difference between typedef & Macros?
Ans:
In C programming, both typedef
and macros (#define
) are used to create aliases or shorthand notations, but they serve different purposes and operate in distinct ways. Understanding the difference between them is crucial for effective and appropriate use in your code.
Typedef
- Purpose:
typedef
is used to create new data type names or aliases for existing data types. This is particularly useful with user-defined data types like structures, unions, or enums to simplify complex declarations and improve code readability and portability. - Syntax:
typedef existing_type new_type_name;
Example:
typedef unsigned int UnsignedInt;
UnsignedInt Mydata; // Mydata is an unsigned int variable
- Operation:
typedef
is handled by the compiler and respects scope rules and C’s type system. It is part of C’s type safety mechanism. - Scope: The scope of a
typedef
is limited to the block in which it is defined. If defined outside any block, it has global scope. - Note: A
typedef
creates synonyms or new names for existing types; it does not create new types.
Macros
- Purpose: Macros are defined using the
#define
directive and serve as preprocessor replacements. They can define constants, function-like expressions, and code snippets that are replaced by the preprocessor before compilation. - Syntax:
#define MACRO_NAME MACRO_VALUE
- Example:
#define VALUE 10
int number = VALUE; // number is assigned the value 10
- Operation: Macros are handled by the preprocessor, not the compiler. They perform textual substitution and do not understand C syntax or semantics, which can lead to unintended consequences if not used carefully (e.g., operator precedence issues).
- Scope: Macros do not have scope. Once defined, they are replaced wherever they appear in the code that follows the definition, unless they are undefined (
#undef
). - Example Usage:
#define SQUARE(x) ((x) * (x))
int num = 5;
int result = SQUARE(num); // Preprocessor replaces this with ((5) * (5))
This macro for SQUARE(x)
computes the square of x
, but due to its nature, it can lead to errors if used with expressions where the order of operations isn’t considered.
Key Differences
- Type Safety:
typedef
respects C’s type system and allows for compile-time type checking. Macros do not provide type safety and can lead to subtle bugs due to incorrect expansions or precedence issues. - Scope and Lifetime:
typedef
has scope control (local or global), whereas macros are replaced by the preprocessor wherever they appear after their definition. - Usage Context:
typedef
is used for creating aliases for data types, improving code readability and maintainability. Macros are versatile and can be used for conditional compilation, defining constants, and simplifying repetitive code, but they require careful handling to avoid errors.
In summary, while both typedef
and macros can be used to simplify and manage C code more effectively, they serve different purposes and have distinct implications on code safety and maintainability. Use typedef
for type-related definitions and macros for textual substitutions and conditionally compiling code.