int a = 5; float b = 2.
5; float result = a + b;
Answer: The result is 7.5. Explanation: When an int and a float are used in an arithmetic operation, the int is implicitly
converted to a float before the operation is performed. So, a becomes 5.0, and the addition 5.0 + 2.5 yields 7.5.
int x = 10; float result = (float)x / 3;
Answer: The value is 3.333333. Explanation: The expression (float)x explicitly casts the integer x to a float, resulting in
10.0. The division 10.0 / 3 is then a floating-point division, which produces 3.333333.
int a = 7;
int b = 2;
float c = (float)a / b;
Answer: The value is 3.5. Explanation: The explicit cast (float)a converts a to a floating-point number. The division 7.0 /
2 is then a floating-point division, which results in 3.5. Without the cast, the division would be integer division, yielding 3.
float myFloat = 3.75f;
int myInt = (int)myFloat; // myInt will be 3
float negativeFloat = -3.75f;
int negativeInt = (int)negativeFloat; // negativeInt will be -3
Round, floor, ceil function can be used from math.h
char a = 'C';
int b = 5;
int sum = a + b;
Answer: The value is 74. Explanation: In C, a char is treated as a small integer. The ASCII value of the character 'C' is
69. The expression a + b is therefore 69 + 5, which equals 74.
char ch = 97;
printf("%c", ch);
Answer: The output is 'a'. Explanation: When an integer is assigned to a char, the character corresponding to that
ASCII value is stored. The ASCII value of 97 is the lowercase letter 'a'.
double d = 100.75;
int i = (int)d;
char c = (char)i;
int result = c;
Answer: The value is 100. Explanation: The double d is explicitly cast to an int i, which truncates the value to 100.
The int i is then cast to a char c. The ASCII value 100 corresponds to the character 'd'. Finally, c is assigned to an
int result, which stores the ASCII value of 'd', which is 100.
int x = 257;
char c = x;
printf("%d", c);
Answer: The output is 1. Explanation: A char is typically an 8-bit signed integer and can store values from -128 to
127. When the integer 257 is assigned to an 8-bit char, it undergoes a modulo 256 operation. The value 257 is
equivalent to 1 in an 8-bit system (257 % 256 = 1). This is a case of data loss due to overflow. When int x = 384; it
will print -128.
Question: What is the difference between an interpreter and a compiler? Answer: A compiler translates the entire
program into machine code before execution, while an interpreter translates and executes code line by line.
Question: What does the -o flag in gcc stand for? Answer: It stands for "output file".
Question: What command would you use to compile mycode.c and name the executable myprogram? Answer: gcc
mycode.c -o myprogram
Question: What is an object file? Answer: An intermediate file containing machine code from a single source file, but
not yet linked with libraries or other object files.
Question: A C program with a main.c file and a utils.c file needs to be compiled. What command sequence would
you use to produce object files first, and then link them to create an executable?
gcc -c main.c, gcc -c utils.c, gcc main.o utils.o -o my_program
Question: Why might a compilation fail at the linking stage? Provide two common reasons. Answer: 1. Missing
Library: A function used in the code (e.g., sin() from <math.h>) is not linked with the appropriate library (e.g., -lm).
2. Undefined Reference: The program calls a function that is declared but not defined anywhere in the source code or
linked libraries.
Question: What is the difference between a static library and a dynamic (shared) library? Answer: A static library is
directly embedded into the executable during linking, making the executable larger but self-contained. A dynamic
library is loaded at runtime, making the executable smaller but dependent on the library being present on the system.
The linker does not embed the entire library code into the executable. Instead, it includes references or
"stubs" that indicate where the required functions will be found in the dynamic library at runtime typically
handled by a dynamic linker/loader in the operating system.
Question: Consider a program with a function my_function() that calls printf(). Explain the difference
in how my_function()'s machine code is linked versus printf()'s machine code, assuming printf() is
from a shared library. Answer: my_function()'s code is directly compiled and linked into the executable. A
call to printf() from my_function() is a dynamic link. The compiler creates a "stub" in the executable's
text segment. At runtime, the dynamic linker will use this stub to find and call the actual printf() function in
the shared C library.
Question: A program has two source files, main.c and helper.c. How do you compile them into a single
executable named app? Answer: gcc main.c helper.c -o app. Each .c source file is compiled into
a separate object file (e.g., main.o and helper.o). This step converts the C code into machine-independent
bytecode or assembly code. The linker combines these object files and any necessary libraries into a single
executable file. During linking, the linker resolves references between different object files, such as function
calls from main.c to functions defined in helper.c.
Question: What is a header file's role in the compilation process? Answer: Header files (.h) contain function
prototypes, data type definitions, and macro definitions. They are not compiled directly but are included by
the preprocessor into the .c file, allowing the compiler to verify function calls and variable declarations.
Declarations, Not Definitions: Header files typically contain declarations (like function prototypes or class
signatures) and definitions of macros and data types, but not the actual executable code (definitions) for
functions. They serve as an interface, specifying "what" components are available and "how" to use them, but
not "how" they are implemented.
Questions: What kind of error is segmentation fault. Answer: Runtime error.
Question: Explain the -E flag in gcc. What is the output and what is its purpose? Answer: The -E flag stops
the compilation process after the preprocessing stage. The output is a C source file with all preprocessor
directives (like #include and #define) expanded. This is useful for debugging to see the code as the
compiler sees it.
Question: What command would you use to generate only the object file for a C source file named file.c
without performing the linking step? Answer: gcc -c file.c
Question: Why might a program compile successfully but crash during execution? Answer: The compiler
can only detect syntax errors. Runtime errors, such as a segmentation fault (accessing invalid memory), an
infinite loop, or division by zero, are logical errors that occur only when the program is running.
Question: What happens if you compile a program with a function prototype in a header file but never define
the function in any .c file? Answer: The compilation will succeed at the assembly stage, but it will fail at the
linking stage with an "undefined reference" error because the linker cannot find the actual code for the
function to include in the executable.
Question: Explain the difference between a variable's declaration and its definition in C. Answer: A
variable declaration informs the compiler about the variable's name and type, but does not allocate memory
for it (e.g., extern int my_variable;). A variable definition reserves a memory location for the variable
and makes it accessible for use (e.g., int my_variable=0;).
Question: Why can a const variable not be modified after initialization, and where is it typically stored in
memory? Answer: A const variable is a read-only variable. The compiler enforces this at compile time, and
it may be stored in a special, read-only section of memory to prevent accidental modification at runtime.
Question: What is the size (in bytes) of an int variable on most modern 64-bit systems, and what is a
common reason for this to vary? Answer: The size is typically 4 bytes on a 64-bit system. The size can vary
depending on the specific compiler, operating system, and hardware architecture being used.
Question: Explain what a "stack overflow" is in the context of C programming. Answer: A stack overflow
occurs when a program attempts to use more stack memory than is allocated to it. This can happen with deep
or infinite recursion, or when declaring very large local variables (e.g., a large array).
Question: In what memory segment are global and static variables stored, and how does this differ from
local variables? Answer: Global and static variables are stored in the data segment of memory, while local
variables are stored on the stack. This means global and static variables persist for the entire duration of the
program, unlike local variables which are deallocated when their function returns.
Question: What does the sizeof operator do? Answer: The sizeof operator returns the size, in bytes, of
a variable or data type at compile time.
Question: Why do we need object files in a multi-file project? Answer: Object files allow for incremental
compilation. If you only change one source file, you only need to recompile that single file into a new object
file and then relink all the existing object files. This is much faster than recompiling every source file from
scratch.
Question: What happens if a function is declared in a header file but never defined in a source file, and what
error will you likely get? Answer: The program will compile the source file successfully because the compiler
only sees the declaration. However, the linking stage will fail with an "undefined reference" error, because
the linker cannot find the function's actual machine code.
Question: What is a "symbol" in the context of linking, and what kind of information does a symbol table
store? Answer: A symbol is a name for a function or global variable. The symbol table within an object file
lists these symbols and their memory addresses. The linker uses this table to match function calls in one
object file to their definitions in another.
Question: What command can you use to inspect the symbol table of a compiled object file? Answer: The
nm command is used to list symbols from object files. For example: nm my_object_file.o
Question: Explain the difference between relocatable object files and executable object files. Why is a
linker necessary to transform the former into the latter? Answer: Relocatable object files contain relative
memory addresses. The linker's job is to resolve these relative addresses and assign absolute, final memory
addresses to them, creating an executable object file that can be loaded into memory and run directly.
Question: Describe the concept of relocation in the context of linking. Provide a simple example of why it's
needed. Answer: Relocation is the process of adjusting memory addresses in an object file so they point to
the correct final addresses in the executable. It's needed because the compiler doesn't know where code from
different object files and libraries will be placed. For example, a function call to utils_function() in
main.o initially points to a relative address. The linker finds utils_function()'s absolute address in
utils.o and "relocates" the call in main.o to that final address.
Question: Why does changing a variable's name in a header file sometimes lead to a linking error, even if
the source file is not recompiled? Answer: A variable's name is a symbol. If you change its name in the
header file, other source files that include the header and use that variable will now be looking for a different
symbol name. If you only recompile those other source files, their object files will now contain references to a
non-existent symbol. When you try to link these object files with the original, un-recompiled source file, the
linker will be unable to match the new symbol name to the old one.
Question: Explain the preprocessor's role in error detection. Can it catch syntax errors? Answer: The
preprocessor performs text-based substitutions and manipulations (like handling #include and #define). It
cannot catch syntax errors in the C language itself. It can, however, generate a compile-time error if a
preprocessor directive is malformed (e.g., a missing macro argument).
Question: What is a compiler warning, and why is it important to address them even if the program
compiles? Answer: A compiler warning is a message from the compiler indicating a potential problem or a
questionable coding practice that is not a strict violation of syntax but could lead to a logical error or
unintended behavior. It's important to address them because they often point to subtle logical flaws,
uninitialized variables, or potential data type conversion issues that can lead to bugs.