C Variables & Data Types - Tricky MCQ
Tricky Questions on Variables, Data Types & Keywords
What is the size of 'void' data type in C?
The 'void' type is an incomplete type that cannot be completed. In C, sizeof(void) is invalid and results in a compilation error. However, GCC allows it as an extension and returns 1. The void type can only be used in specific contexts: function return types, function parameters (void), and pointers to void (void*).
What is the difference between "auto" and "register" storage classes?
'auto' is the default storage class for local variables (stored in stack memory). 'register' is a hint to the compiler to store the variable in CPU registers for faster access, but it's only a request - the compiler may ignore it. You cannot take the address of a register variable (& operator). In modern compilers with optimization, 'register' is often ignored as compilers are better at register allocation.
What is the output: printf("%d", sizeof(3.14));
In C, floating-point constants like 3.14 are of type double by default, not float. To make it a float, you need to append 'f' or 'F' (3.14f). Similarly, 3.14L would be long double. So sizeof(3.14) returns the size of double (typically 8 bytes on most systems).
Which of these is NOT a valid variable name in C?
All of these are keywords in C and cannot be used as variable names. 'int' and 'register' are keywords in all C versions. '_Bool' was introduced as a keyword in C99. Keywords are reserved words that have special meaning to the compiler and cannot be used as identifiers.
What is the range of 'char' data type in C?
This is a tricky one! The C standard says plain 'char' can be either signed or unsigned, depending on the implementation (compiler and platform). Most compilers treat char as signed by default, but ARM compilers often treat it as unsigned. To guarantee signedness, use 'signed char' or 'unsigned char' explicitly.
What is "variable shadowing" in C?
Variable shadowing occurs when a variable declared in an inner scope (like inside a function or block) has the same name as a variable in an outer scope (like a global variable or function parameter). The inner variable "shadows" or hides the outer variable, making it inaccessible within that scope.
What is the difference between "const" and "#define" for constants?
const creates typed constants that occupy memory (like variables), have scope, and provide type safety. #define creates text substitutions (macros) that don't use memory, have no type checking, and are replaced by the preprocessor before compilation. const is generally preferred in modern C for type safety and debugging.
What is the value of: sizeof('A' + 1);
In C, character constants like 'A' are of type int. When you add 1 to it, the result is still an int. More importantly, C has integer promotion: in expressions, char and short are promoted to int before operations. So sizeof('A' + 1) returns sizeof(int), typically 4 bytes.
Which keyword makes a variable retain its value between function calls?
The static keyword, when applied to a local variable inside a function, gives it static storage duration. This means the variable persists between function calls and retains its value. It's initialized only once (to 0 if no explicit initializer) and exists for the lifetime of the program.
What is the output: int a = 5, b = 2; float c = a / b; printf("%f", c);
In C, when both operands of division are integers, integer division occurs (truncates toward zero). So 5/2 = 2 (not 2.5). This integer result (2) is then converted to float (2.0) when assigned to c. To get float division, make at least one operand float: float c = (float)a / b; or float c = a / 2.0;
What does the "restrict" keyword do in C (C99)?
The restrict keyword (C99) is a type qualifier for pointers. It tells the compiler that for the lifetime of the pointer, only that pointer (or directly derived from it) will access the pointed-to object (no aliasing). This allows more aggressive optimizations. Violating this promise leads to undefined behavior.
What is "type punning" in C and is it safe?
Type punning is accessing the same memory location as different types (e.g., accessing an int as float). This violates C's strict aliasing rule which says you can only access an object through its own type, a compatible type, or a character type. Violating this leads to undefined behavior. The safe way is using memcpy() or unions (in C99).
What is the "volatile" qualifier used for?
volatile tells the compiler that a variable's value may change at any time without any action being taken by the code. This prevents optimization (like caching in register). Used for: 1) Memory-mapped hardware registers, 2) Variables shared between main code and interrupt service routines, 3) Variables shared between threads (though not sufficient for thread safety - needs atomic operations or mutexes), 4) Variables accessed in signal handlers.
What is the difference between "signed" and "unsigned" integer overflow?
In C, signed integer overflow is undefined behavior - anything can happen (crash, wrong results, etc.). Unsigned integer overflow (or more precisely, "wrap-around") is well-defined: it wraps modulo 2^n (where n is number of bits). This is a critical difference for security and optimization.
What is "flexible array member" in C (C99)?
A flexible array member (C99) is an array without a specified size as the last member of a struct. It allows allocating memory for the struct plus additional array elements dynamically. This replaces the old "struct hack" (array of size 1). The struct must have at least one other member before the flexible array.