1.2 C vs C++, Streams, Operators & Reference Variables
C vs C++ — Comparison
C++ is often called "C with classes" — but it's much more. The full comparison:
| Aspect | C | C++ |
|---|---|---|
| Paradigm | Procedural | Multi-paradigm (procedural, OOP, generic, functional) |
| Approach | Top-down | Bottom-up |
| OOP support | No | Yes (classes, inheritance, polymorphism) |
| Encapsulation | Via structs (no access control) | public/private/protected |
| I/O | printf/scanf (functions) | cin/cout (objects of stream classes) |
| Memory | malloc/free | new/delete (also malloc/free) |
| Function overloading | Not allowed | Allowed |
| Operator overloading | Not allowed | Allowed |
| Reference variables | Not available | Available (&) |
| Default arguments | Not allowed | Allowed |
| Templates / Generics | Not available | Available |
| Exception handling | Setjmp / longjmp | try / catch |
| Inheritance | Not available | Single + multiple |
| Polymorphism | Function pointers (manual) | Virtual functions (built-in) |
| Inline functions | Macros only | inline keyword |
| Strict typing | Loose | Stricter |
| Standard library | Smaller (stdio, stdlib) | Large (STL — vectors, maps, algorithms) |
bool type | Not built-in (until C99) | Built-in |
new keyword | No | Yes |
| Header files | .h | .h (C-style) or no extension (C++ standard like <iostream>) |
Exam tip: "Differentiate C and C++" needs at least 10 differences for full marks. Use this table.
Code comparison
C:
#include <stdio.h>
int main() {
int n;
printf("Enter a number: ");
scanf("%d", &n);
printf("You entered: %d\n", n);
return 0;
}
C++:
#include <iostream>
using namespace std;
int main() {
int n;
cout << "Enter a number: ";
cin >> n;
cout << "You entered: " << n << endl;
return 0;
}
---
C++ Stream-Based I/O
C++ replaces C's printf / scanf with stream objects:
| Stream | Direction | Bound To |
|---|---|---|
cin | Input | Standard input (keyboard) |
cout | Output | Standard output (screen) |
cerr | Output (unbuffered errors) | Standard error |
clog | Output (buffered logging) | Standard error |
They are objects of classes defined in <iostream>. The >> operator is the extraction (input) operator and << is the insertion (output) operator.
Basic I/O
#include <iostream>
using namespace std;
int main() {
int age;
string name;
cout << "Enter your name and age: ";
cin >> name >> age;
cout << "Hello " << name << ", you are " << age << " years old." << endl;
return 0;
}
Manipulators
#include <iostream>
#include <iomanip> // for setw, setprecision
using namespace std;
int main() {
double pi = 3.141592653589;
cout << setprecision(4) << pi << endl; // 3.142
cout << setw(10) << "Hello" << endl; // right-aligned in 10 columns
cout << fixed << setprecision(2) << pi; // 3.14
return 0;
}
Common manipulators: endl, setw, setfill, setprecision, fixed, hex, oct, dec, boolalpha.
---
Literals and Constant Qualifiers
Literals
42 // integer literal
3.14 // double literal
3.14f // float literal
'A' // char literal
"hello" // string literal
true // bool literal
0x1F // hex (= 31)
0b1010 // binary (C++14+) (= 10)
const qualifier
const int MAX = 100; // value cannot change
int x = 10;
const int* p = &x; // pointer to const int — *p cannot change
int* const q = &x; // const pointer — q cannot change
const int* const r = &x; // both const
constexpr (C++11+)
constexpr int SIZE = 100; // computed at compile time
---
Operators in C++
C++ inherits all C operators and adds new ones:
| Category | Operators | ||
|---|---|---|---|
| Arithmetic | + - * / % | ||
| Relational | == != < > <= >= | ||
| Logical | `&& | !` | |
| Bitwise | `& | ^ ~ << >>` | |
| Assignment | `= += -= *= /= %= &= | = ^= <<= >>=` | |
| Increment / Decrement | ++ -- | ||
| Conditional | ? : (ternary) | ||
| Comma | , | ||
| Sizeof | sizeof | ||
| Pointer / Reference | * & -> | ||
| Member access | . -> :: | ||
| Memory | new new[] delete delete[] | ||
| Stream | << >> (also bitwise — context disambiguates) | ||
| Scope | :: | ||
| typeid | RTTI | ||
| Cast | static_cast dynamic_cast const_cast reinterpret_cast |
Scope-resolution operator ::
int x = 10; // global
int main() {
int x = 20; // local
cout << x; // 20 (local)
cout << ::x; // 10 (global, via ::)
return 0;
}
Also used for class members:
class Math {
public:
static int square(int x) { return x * x; }
};
Math::square(5); // 25
---
Reference Variables — a C++ exclusive
A reference is an alias for an existing variable. Once initialised, it cannot be reseated. Declared with &.
int x = 10;
int& ref = x; // ref is now an alias for x
ref = 20; // changes x to 20
cout << x; // 20
int& ref2; // ERROR — must be initialised at declaration
Reference vs Pointer — exam classic
| Aspect | Pointer | Reference |
|---|---|---|
| Stores | Address | Alias |
| Syntax | int p = &x; then p = 20; | int& r = x; then r = 20; |
| Null | Can be nullptr | Must always refer to something |
| Reseating | Can point to different variables | Once bound, cannot change |
| Arithmetic | Pointer arithmetic allowed | None |
| Memory | Has its own memory (4/8 bytes) | Often optimised away — no own memory |
| Indirection | Explicit (*p) | Implicit |
| Address of | &p is address of pointer | &r is address of original |
| Use case | Dynamic allocation, polymorphism via base pointer, optional null | Function parameters, return-by-reference, range-based for |
Common reference uses
1. Pass-by-reference to a function:
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
int x = 5, y = 10;
swap(x, y); // x = 10, y = 5
2. Return-by-reference:
int& getElement(int arr[], int i) {
return arr[i];
}
int a[5] = {1, 2, 3, 4, 5};
getElement(a, 2) = 99; // arr[2] now = 99
3. Range-based for (C++11):
vector<int> nums = {1, 2, 3};
for (int& n : nums) n *= 2; // doubles each element in place
---
Const References
A const reference is a reference that cannot modify the referent. Useful for passing large objects without copying:
void print(const string& s) { // s cannot be modified, but no copy made
cout << s << endl;
}
Compared to:
- Pass-by-value:
void print(string s)— copies the string (expensive) - Pass-by-reference (non-const):
void print(string& s)— caller's string can be modified - Pass-by-const-reference:
void print(const string& s)— efficient AND safe
This is the most common idiom for parameters in modern C++.
---
Comments and Namespaces
Comments
// Single-line comment
/* Multi-line
comment */
Namespaces
namespace MyApp {
int counter = 0;
void increment() { counter++; }
}
MyApp::counter = 5; // explicit qualification
MyApp::increment();
using namespace MyApp; // bring all into scope
counter = 5; // now unqualified
The C++ standard library lives in namespace std. Either prefix everything (std::cout) or write using namespace std;.
---
Type Conversion in C++
Implicit (automatic)
int i = 5;
double d = i; // int → double (widening — safe)
float f = 3.14;
int x = f; // double → int (narrowing — may lose data)
Explicit / C-style cast
double d = 3.14;
int i = (int) d; // C-style
C++ casts (preferred)
double d = 3.14;
int i = static_cast<int>(d); // typical type conversion
const int x = 10;
int* p = const_cast<int*>(&x); // removes const-ness
Base* b = new Derived();
Derived* dp = dynamic_cast<Derived*>(b); // safe down-cast (RTTI)
int* p2 = reinterpret_cast<int*>(somePointer); // raw reinterpretation (unsafe)
Why prefer C++ casts? They are searchable, intent-revealing, and the compiler enforces safety (static_cast won't compile for unrelated types).
---
Key Terms — Lesson 1.2
The terms below cover the C-to-C++ vocabulary, the stream-based I/O system, operators, and reference variables — every Unit-I PYQ on C++ basics expects them.
Header File — A file (.h or no extension for standard C++ headers like <iostream>) that declares functions, classes, and constants intended to be shared across multiple source files. In C++, standard library headers have no .h extension (<vector>, <string>); C-compatibility headers add a c prefix (<cstdio>, <cstdlib>).
<iostream> Header — The C++ standard header that declares the stream objects (cin, cout, cerr, clog) and the stream insertion/extraction operators. Required for any program that does console I/O the C++ way.
Stream — An abstraction representing a sequential flow of bytes to or from a source/destination — keyboard, screen, file, network socket, in-memory buffer. C++ streams are objects of classes derived from ios_base; the operators << and >> are overloaded for them.
cin — The standard input stream object (instance of istream) bound to the keyboard / stdin. Used with the extraction operator >>. cin >> n; reads a value into n, skipping leading whitespace.
cout — The standard output stream object (instance of ostream) bound to the console / stdout. Used with the insertion operator <<. cout << "Hello"; writes a string to standard output.
cerr vs clog — Two error-output streams. cerr is unbuffered — output appears immediately, used for urgent error messages. clog is buffered — output is held until the buffer flushes, used for logging.
Insertion Operator << — In stream context, the operator that writes the right operand to the left stream. cout << x; inserts x into cout. << is also the bitwise left-shift operator; context disambiguates.
Extraction Operator >> — In stream context, the operator that reads from the left stream into the right variable. cin >> x; extracts a value from cin into x. Skips leading whitespace by default; stops at the first whitespace.
Manipulator — A function (or function-like object) applied to a stream to modify its behaviour — endl (insert newline + flush), setw(n) (set field width), setprecision(n) (decimal places), fixed (fixed-point notation), hex / oct / dec (number base), boolalpha (print bools as true/false). Most live in <iomanip>.
Literal — A fixed value written directly in source code — 42 (int), 3.14 (double), 'A' (char), "hello" (string), true (bool), 0x1F (hex int), 0b1010 (binary int, C++14+). Suffixes choose the type: 3.14f is float, 100L is long, 100U is unsigned.
const Qualifier — A type qualifier that prohibits modification of the qualified variable. const int MAX = 100; cannot be reassigned. const on a pointer (const int p) means the pointee cannot change; int const p means the pointer cannot change.
constexpr (C++11) — A stronger form of const that requires the value to be computable at compile time. constexpr int SIZE = 100; can be used in places where the compiler needs a known constant (array sizes, template parameters).
Reference Variable — A C++ feature: an alias for an existing variable. Declared with &: int& ref = x;. Once initialised, a reference cannot be reseated (made to refer to a different variable) and cannot be null. References are the safer, simpler counterpart to pointers.
Reference vs Pointer — Two ways to refer indirectly to another variable. Pointer stores an address, can be null, can be reseated, supports pointer arithmetic, requires explicit dereferencing (*p). Reference is an alias, cannot be null, cannot be reseated, has no arithmetic, used implicitly. References are preferred in modern C++ for function parameters and return values.
Pass-by-Value — A function-call style where the argument value is copied into the function's parameter. The function operates on the copy; the original is unaffected. Safe but expensive for large objects.
Pass-by-Reference — A function-call style where the parameter is a reference to the argument. The function operates on the original. Efficient (no copy) and allows the function to modify the caller's variable. Declared with &: void swap(int& a, int& b);.
Pass-by-Const-Reference — A function-call style combining pass-by-reference's efficiency with safety. The parameter is a const reference: void print(const string& s);. No copy is made, but the function cannot modify the caller's variable. The most common idiom for function parameters in modern C++.
Return-by-Reference — A function-return style where the function returns a reference to an existing object, not a copy. Lets the caller modify the returned object directly: arr.at(2) = 99;. Caller must ensure the referenced object outlives the reference.
Namespace — A C++ feature that groups related names into a named scope, preventing name collisions across libraries. The C++ standard library is in namespace std. Access namespace members with the scope operator (std::cout) or import them with using namespace std;.
Scope Resolution Operator (::) — The operator that specifies which scope a name belongs to. Used for namespace members (std::cout), class members (Math::square()), and accessing global scope (::x when a local x shadows the global).
Type Conversion / Type Casting — Converting a value from one type to another. Implicit conversion happens automatically for compatible types (int → double); explicit conversion requires a cast. C-style cast: (int) d. C++ casts (preferred): static_cast<int>(d).
static_cast — The standard C++ cast for well-defined type conversions — int to double, base pointer to derived pointer when you know it's safe, enum to int. Checked at compile time; rejects unrelated types.
dynamic_cast — A C++ cast for safely down-casting in a polymorphic hierarchy. Base b = ...; Derived d = dynamic_cast<Derived*>(b); returns the derived pointer if b actually points to a Derived, or nullptr if not. Uses RTTI (Run-Time Type Information); requires at least one virtual function in the base.
const_cast — A C++ cast that adds or removes const-ness. Use sparingly — usually a signal that the design has a const-correctness problem.
reinterpret_cast — A C++ cast that performs a raw bit-pattern reinterpretation — pointer-to-int, pointer-to-different-pointer-type. The most unsafe cast; only justified in low-level code (serialisation, hardware interfaces).
Function Overloading — A C++ feature: multiple functions can share the same name as long as their parameter lists differ. The compiler picks the right overload based on the call's argument types. Resolves at compile time — a form of compile-time polymorphism.
Operator Overloading — A C++ feature: operators (+, -, <<, etc.) can be given custom meanings for user-defined types. This is how cout << myObject works — the << operator is overloaded for the user's type. Covered in detail in Unit III.
inline Function — A function annotated with the inline keyword as a hint to the compiler to substitute the function body at the call site instead of generating a call. Avoids function-call overhead for small frequently-used functions. The compiler may ignore the hint.
endl vs "\n" — Both insert a newline. endl also flushes the output buffer, which is slower but ensures the output is visible immediately (important for interactive programs and debugging). "\n" just writes the newline character.
RAII (Resource Acquisition Is Initialisation) — A C++ idiom (Bjarne Stroustrup) where a resource is tied to an object's lifetime — the constructor acquires the resource (file handle, memory, lock), the destructor releases it. RAII is what makes C++ resource management safe without garbage collection. The conceptual backbone of smart pointers (std::unique_ptr, std::shared_ptr).
---
Study deep
- The cleanest mental model: C++ = "C + Classes + Templates + RAII". Strip away just the OOP additions and you have C; strip away templates and you have early C++; add RAII (resource cleanup tied to object lifetime) and you have modern C++.
- References are cheaper than pointers — sometimes. Modern compilers often implement references as pointers internally — but the language guarantees they can never be null, never be reseated, and always reflect the original. This safety is the value, not the implementation.
cin/coutare slower thanscanf/printf. For competitive programming,std::ios_base::sync_with_stdio(false)makes them comparable. For most apps, the difference is irrelevant.
- Modern alternatives.
std::format(C++20) is the modern formatting facility — likeprintfbut type-safe. Many codebases still usecoutfor simplicity.
- Avoid C-style casts in new code. They silently allow unsafe conversions. The four named casts give you exactly the conversion you intend, and nothing more.
PYQ pattern (very common): "Differentiate C and C++." — Tabulate 10+ differences (paradigm, I/O, encapsulation, overloading, references, templates, exception handling). Close with code comparison (printf vs cout).
PYQ pattern: "What is a reference variable? Differentiate references and pointers." — Define as alias; show declaration; table 7-8 differences (null, reseating, arithmetic, memory, syntax, use); give swap-function example.