C++ is a structured and object-oriented language used in systems programming, game development, competitive coding.
1. How does C++ enable both high-level and low-level programming, and what features make it suitable for systems-level development?
C++ is called a middle-level language because it combines the features of both high-level and low-level programming.
- High-level features: It supports abstraction, object-oriented programming, templates, and the standard library, which make writing complex applications easier and closer to human thinking.
- Low-level features: It allows direct memory management using pointers, inline assembly, and hardware-level manipulation, which makes it suitable for systems programming like operating systems, compilers, and device drivers.
Reasons why C++ is suitable for systems-level development:
- Direct Memory Access: Through pointers and pointer arithmetic.
- Manual Resource Management: Developers can control memory allocation/deallocation using new and delete.
- Performance: Minimal runtime overhead compared to other higher-level languages.
- Object-Oriented Design: Helps in organizing large system codebases (e.g., OS kernels, databases).
C++
#include <iostream>
using namespace std;
int main() {
int x = 10; // high-level: simple variable
int* p = &x; // low-level: direct memory access with pointer
*p = 20; // modifying value through pointer
cout << "x = " << x << endl;
return 0;
}
- High-level: int x = 10; shows simple variable handling.
- Low-level: int* p = &x; and *p = 20; show direct memory manipulation.
- It clearly demonstrates how C++ can act at both levels in just a few lines.
2. Whats is 'namespace std'?
'std' stands for Standard. It is a namespace in C++. Namespace is a feature that provides a way to group related identifiers such as variables, functions, and classes under a single name. The line "using namespace std" informs the compiler to add everything under the std namespace and inculcate them in the global namespace. This all inculcation of global namespace benefits us to use "cout" and "cin" without using "std::_operator_".
C++
#include <iostream>
using namespace std;
int main() {
cout << "Hello using std namespace!" << endl;
return 0;
}
3. What are references in C++?
In C++, references is a way to create an alias for another variable.
- A reference acts as a synonym for a variable, allowing you to access the variable directly without any additional syntax.
- They must be initialized when created and cannot be changed to refer to another variable afterward.
- This feature makes it easier to manipulate variables in functions while avoiding the overhead of copying large objects. A reference variable is preceded with a '&' symbol.
Syntax:
int GFG = 10;
// reference variable
int& ref = GFG;
C++
#include <iostream>
using namespace std;
int main() {
int a = 10;
int &ref = a;
ref = 20;
cout << "a = " << a << ", ref = " << ref << endl;
return 0;
}
4. Define the Block scope variable.
A block scope variable is also known as a local scope variable. A variable that is defined inside a function (like main) or inside a block (anything enclosed with curly braces like loops and if else) is a local variable. A block-scoped variable will not be available outside the block even if the block is inside a function.
C++
#include <iostream>
using namespace std;
int main() {
int a = 10; // local to main
if (a > 5) {
int b = 20; // block scope inside if-block
cout << "Inside if-block: a = " << a << ", b = " << b << endl;
}
for (int i = 0; i < 3; i++) {
int temp = i * 10; // block scope inside for-loop
cout << "temp = " << temp << endl;
}
return 0;
}
5. What does the "auto" keyword do?
The auto keyword is a type inference specifier introduced in C++11, which tells the compiler to automatically deduce the type of a variable from its initializer expression.
Primary Function of auto:
- Simplifies declarations (especially for iterators, lambdas, template types).
- Enhances code readability and maintainability.
- Reduces redundancy and typing errors.
- Promotes use of generic programming.
Use Case: With Iterators use this
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4};
for (auto it = v.begin(); it != v.end(); ++it)
cout << *it << " ";
return 0;
}
Instead of this:
std::vector<int>::iterator it = v.begin();
6. What do you mean by Pass by Value and Pass by Reference?
In this programming language to call a function we have 2 methods: Pass by Value and Pass by Reference
Pass by Value | Pass by Reference |
|---|
| A copy of a variable is passed. | Either the address of variable or reference to the variable is passed. |
| The changes made in the function are never reflected outside the function on the variable. In short, the original value is never altered in Call by Value. | The changes made in the functions can be seen outside the function on the passed function. In short, the original value is altered in Call by reference. |
| Passed actual and formal parameters are stored in different memory locations. Therefore, making Call by Value a little memory inefficient. | Passed actual and formal parameters are stored in the same memory location. Therefore, making Call by Reference a little more memory efficient. |
Pass by Value:
C++
#include <iostream>
using namespace std;
void modify(int x) {
x = x + 10;
}
int main() {
int a = 5;
modify(a);
cout << "Value after call by value: " << a << endl;
return 0;
}
Pass by Reference:
C++
#include <iostream>
using namespace std;
void modify(int &x) {
x = x + 10;
}
int main() {
int a = 5;
modify(a);
cout << "Value after call by reference: " << a << endl;
return 0;
}
7. Define token in C++
A token is the smallest individual element of a program that is understood by a compiler. A token comprises the following:
- Keywords: That contain a special meaning to the compiler
- Identifiers: That hold a unique value/identity
- Constants: That never change their value throughout the program
- Strings: That contains the homogenous sequence of data
- Special Symbols: They have some special meaning and cannot be used for another purpose; eg: [] () {}, ; * = #
- Operators: Who perform operations on the operand
C++
#include <iostream>
using namespace std; // Keyword
int main() {
int age = 25; // int (keyword), age (identifier), 25 (constant)
cout << "Age: " << age << endl; // "Age:" (string), << (operator)
return 0; // return (keyword), 0 (constant)
}
8. What is the difference between C and C++?
The following table lists the major differences between C and C++:
C | C++ |
|---|
C language came before C++ and has subset of features provided by C++ | C++ can be seen as a superset of C. Almost everything written in C compiles in C++ as well except few exceptions. |
| It is a procedural programming language. In simple words, it does not support classes and objects | It supports both procedural and object-oriented programming languages. |
| It does not support any OOP concepts like polymorphism, data abstraction, encapsulation, classes, and objects. | It supports all OOP concepts like classes, objects, inheritance, polymorphism, etc |
| It does not support Exception Handling and Generics | Supports Exception Handling and Generics through templates |
| It is a function-driven language | It is an object-driven language |
C Code (No OOP):
C
#include <stdio.h>
void greet() {
printf("Hello from C-style function!\n");
}
int main() {
greet();
return 0;
}
C++ Code with OOP:
C++
#include <iostream>
using namespace std;
class Greet {
public:
void sayHello() {
cout << "Hello from C++ class!" << endl;
}
};
int main() {
Greet g;
g.sayHello();
return 0;
}
9. What happens if you use cout without using namespace std or std::cout? Why is namespace resolution important in large C++ projects?
In C++, cout belongs to the std namespace. If you forget to use using namespace std; or std::cout, you'll get a compiler error. In large projects, polluting the global namespace can lead to naming collisions
C++
#include <iostream>
// using namespace std; // not used intentionally
int main() {
std::cout << "Using std::cout directly avoids namespace pollution\n";
return 0;
}
10. What is the difference between const and #define?
- const: A typed constant with scope rules, checked by the compiler.
- #define: A preprocessor macro replaced before compilation, no type checking.
- const int x = 10; // Type safe
- #define y 10 // No type checking
11. What are default arguments?
Default arguments are values that are used when a function is called without some parameters.
C++
#include <iostream>
using namespace std;
void greet(string name = "Guest") {
cout << "Hello " << name;
}
int main() {
greet();
return 0;
}
12. What are type modifiers in C++?
Modifiers like signed, unsigned, long, short change the size or sign of basic data types.
Example:
unsigned int a = 5;
long double b = 5.66;
C++
#include <iostream>
using namespace std;
int main() {
unsigned int u = 10;
signed int s = -20;
short sh = 30000;
long lg = 100000L;
long long ll = 9223372036854775807LL;
cout << "unsigned int: " << u << endl;
cout << "signed int: " << s << endl;
cout << "short: " << sh << endl;
cout << "long: " << lg << endl;
cout << "long long: " << ll << endl;
return 0;
}
13. How does type deduction using auto and decltype in C++ enhance type safety and flexibility? Show how these modern features relate to built-in and user-defined data types.
Explanation: Instead of manually specifying data types, C++ allows the compiler to deduce the type using:
- auto: Deduces the type from initializer.
- decltype: Infers type from an expression.
These features:
- Reduce boilerplate.
- Improve maintainability.
- Prevent type mismatches.
Code Example:
C++
#include <iostream>
using namespace std;
int getNumber() { return 42; }
int main() {
auto x = 10.5; // deduced as double
decltype(getNumber()) y = 5; // deduced as int (from return type)
cout << "x: " << x << ", y: " << y << endl;
return 0;
}
14. What is a reference in C++ and how is it different from a pointer?
- A reference is an alias for another variable. Once initialized, it always refers to the same variable.
- A pointer stores the address of a variable and can be changed to point somewhere else.
- References do not need dereferencing (*) to access the value; they behave just like the original variable.
C++
#include <iostream>
using namespace std;
int main() {
int a = 10;
int& ref = a; // reference to a
int* ptr = &a; // pointer to a
ref = 20; // changes a
*ptr = 30; // also changes a
cout << a; // prints 30
}
15. Can a reference be reseated to another variable after initialization? What happens if you try to return a reference to a local variable?
- References cannot be reseated.
- Returning a reference to a local variable causes undefined behavior — you're returning a variable that no longer exists after function ends.
Code:
C++
#include <iostream>
using namespace std;
int& getLocal() {
int a = 10;
return a; // Returning reference to a local variable (UB)
}
int main() {
int &ref = getLocal();
cout << "Undefined behavior: " << ref << endl;
return 0;
}
16. Discuss the difference between prefix and postfix?
Following are the major difference between prefix and postfix:
prefix | postfix |
|---|
| It simply means putting the operator before the operand | It simply means putting the operator after the operand |
| The variable is incremented/decremented first, and then the updated value is used in the expression. | The current value of the variable is used in the expression first, and then the increment/decrement happens afterward. |
| Associativity of prefix ++ is right to left | Associativity of postfix ++ is left to right |
17. Define namespace in C++.
Namespaces enable us to organize named items that would otherwise have global scope into smaller scopes, allowing us to give them namespace scope. This permits program parts to be organized into distinct logical scopes with names. The namespace provides a place to define or declare identifiers such as variables, methods, and classes.
Or we could say that A namespace is a declarative zone that gives the identifiers (names of types, functions, variables, and so on) within it a scope. Namespaces are used to arrange code into logical categories and to avoid name clashes, which might happen when you have many libraries in your code base.
C++
#include <iostream>
using namespace std;
// Define a namespace called "MathOps"
namespace MathOps {
int add(int a, int b) {
return a + b;
}
int multiply(int a, int b) {
return a * b;
}
}
int main() {
int x = 5, y = 3;
// Access functions using namespace scope resolution
cout << "Addition: " << MathOps::add(x, y) << endl;
cout << "Multiplication: " << MathOps::multiply(x, y) << endl;
return 0;
}
18. When is void() return type used?
The void keyword, when used as a function return type, indicates that the function does not return a value. You can use return; in such functions, but you cannot return an actual value. When used as a parameter list (e.g., void f(void) in C-style), it means the function takes no parameters.
C++
#include <iostream>
using namespace std;
void greet() {
cout << "Hello from a void function!\n";
return; // valid, though it returns nothing
}
int main() {
greet();
return 0;
}
19. What is the difference between a reference and a pointer?
- Reference is an alias for a variable. It cannot be NULL and must be initialized.
- Pointer is a variable storing address. It can be reassigned and can be NULL.
C++
#include <iostream>
using namespace std;
int main() {
int a = 10;
int& ref = a; // reference
int* ptr = &a; // pointer
cout << "ref: " << ref << endl;
cout << "ptr: " << *ptr << endl;
*ptr = 20;
cout << "After changing via pointer, a = " << a << endl;
ref = 30;
cout << "After changing via reference, a = " << a << endl;
return 0;
}
20. In the line "int* a, b;", how many pointers are declared?
Many assume both a and b are pointers, but only a is a pointer — b is just an int.
Code Example:
C++
#include <iostream>
using namespace std;
int main() {
int* a, b; // a is a pointer, b is just an int
int x = 5;
a = &x;
cout << "Pointer a: " << *a << ", Integer b: " << b << endl;
return 0;
}
21. Define storage class in C++ and name some
Storage class is used to defines the scope (visibility), lifetime, and linkage of variables or functions. These features usually help in tracing the existence of a variable during the runtime of a program.
Syntax:
storage_class var_data_type var_name;
Some types of storage classes:
Examples of storage class22. What is a mutable storage class specifier? How can they be used?
The mutable keyword is a storage class specifier used only with non-static data members of a class. It allows a member of a const object to be modified. Normally, if an object is declared const, you cannot modify any of its members, but mutable makes an exception.
Key Points:
- Used only with non-static, non-const, and non-reference data members.
- Allows modification even inside: A const object & A const member function
- Useful in caching, lazy evaluation, logging, etc., where some internal state can change without affecting observable behavior.
Why is mutable Needed: When a member function is marked as const like this
void show() const;
It cannot modify any data members of the object, because this becomes a const pointer (i.e., const ClassName* this). But sometimes, you want to modify an internal variable (e.g., access counter, log flag) that is not part of the logical state of the object. That’s where mutable helps.
Example:
C++
#include <iostream>
using namespace std;
class Logger {
private:
mutable int accessCount; // can change even in const functions
string data;
public:
Logger(string d) : data(d), accessCount(0) {}
void showData() const {
accessCount++; // allowed because accessCount is mutable
cout << "Data: " << data << ", Accessed: " << accessCount << " times\n";
}
};
int main() {
const Logger log("Secret Info");
log.showData(); // Allowed even though log is const
log.showData(); // Internal counter keeps updating
}
Even though log is declared as const, accessCount is being updated, because it is declared mutable.