C++ Programming: Streams, Functions, and Memory
In C++, Input/Output (I/O) operations are managed through a hierarchy of classes collectively known as streams. A stream is an abstraction that represents a flow of data between a source (like a keyboard) and a destination (like a screen).
Here is a comprehensive breakdown of how C++ handles both unformatted and formatted I/O operations, along with the core stream mechanisms.
Streams, Insertion, and Extraction
At the heart of C++ I/O are the standard stream objects:
- cin: Standard input stream (usually the keyboard), an instance of
istream. - cout: Standard output stream (usually the screen), an instance of
ostream.
The Insertion Operator (<<)
Used with cout to output data. It "inserts" data into the output stream.
cout << "Hello, World!";The Extraction Operator (>>)
Used with cin to input data. It "extracts" data from the input stream. By default, it skips whitespace (spaces, tabs, newlines).
int age;
cin >> age;Unformatted I/O Operations
Unformatted I/O functions read or write data in its raw, binary format without any special formatting or styling. They process data character-by-character or as a block of bytes, making them highly efficient.
Unformatted Input Functions
- get(): Reads a single character, including whitespace.
- getline(): Reads a whole line of text (until it hits a newline character
\n). - read(): Reads a specific number of blocks or bytes into a buffer.
Unformatted Output Functions
- put(): Writes a single character to the screen.
- write(): Writes a specific number of blocks or bytes from a buffer to the screen.
#include <iostream>
using namespace std;
int main() {
char ch;
char str[100];
// Using get() and put()
cout << "Enter a single character: ";
cin.get(ch);
cout << "You entered: ";
cout.put(ch) << "\n";
cin.ignore(); // Clear the newline character left in the buffer
// Using getline() and write()
cout << "Enter a full line of text: ";
cin.getline(str, 100);
cout << "Your string via write(): ";
cout.write(str, 10); // Writes only the first 10 characters
return 0;
}Formatted I/O Operations
Formatted I/O allows you to control exactly how the data looks when it is displayed or read. This includes setting the width of fields, alignment, filling blank spaces, and formatting floating-point numbers.
C++ provides two main ways to format your I/O: ios member functions and manipulators.
Formatting Using ios Member Functions
The stream classes have built-in member functions to adjust state flags.
| Function | Description | Example |
|---|---|---|
| width(n) | Sets the field width for the next output to n characters. | cout.width(10); |
| fill(ch) | Fills the unused spaces in the field with character ch. | cout.fill('*'); |
| precision(n) | Sets the number of digits to display for floating-point numbers. | cout.precision(4); |
| setf() | Sets specific format flags (e.g., left/right alignment, hex/octal). | cout.setf(ios::left); |
| unsetf() | Clears specific format flags. | cout.unsetf(ios::scientific); |
Formatting Using Manipulators
Manipulators are special functions that can be directly chained inside the << or >> operators. To use most of them, you need to #include <iomanip>.
| Manipulator | Equivalent Member Function | Description |
|---|---|---|
| setw(n) | width(n) | Sets the field width to n. |
| setfill(ch) | fill(ch) | Fills empty spaces with ch. |
| setprecision(n) | precision(n) | Sets floating-point precision. |
| hex / dec / oct | setf(ios::hex), etc. | Changes the base of the number. |
| left / right | setf(ios::left), etc. | Adjusts the alignment. |
| fixed / scientific | setf(ios::fixed), etc. | Forces decimal or scientific notation. |
#include <iostream>
#include <iomanip> // Required for parameterized manipulators
using namespace std;
int main() {
double pi = 3.1415926534;
int num = 42;
// Formatting output using manipulators
cout << "Default Pi: " << pi << endl;
cout << "Pi with precision 3: " << setprecision(3) << pi << endl;
cout << "Pi in fixed format: " << fixed << setprecision(2) << pi << endl;
cout << "\n--- Creating a Table Structure ---" << endl;
cout << setw(10) << "Product" << setw(10) << "Price" << endl;
cout << setfill('-') << setw(20) << "" << endl; // Prints a divider line
cout << setfill(' ') << left << setw(10) << "Apples" << right << setw(10) << 1.50 << endl;
cout << left << setw(10) << "Bananas" << right << setw(10) << 0.75 << endl;
cout << "\n--- Base Conversions ---" << endl;
cout << "Decimal: " << dec << num << endl;
cout << "Hexadecimal: " << hex << num << endl;
cout << "Octal: " << oct << num << endl;
return 0;
}Functions in C++
A function is a block of code that performs a specific task. They make the code reusable, organized, and easier to maintain.
Declaration and Definition
- Function Declaration (Prototype): Tells the compiler about the function's name, return type, and parameters before it is used. It acts like a placeholder.
- Function Definition: Contains the actual body of code that executes when the function is called.
#include <iostream>
using namespace std;
// 1. Function Declaration
int add(int a, int b);
int main() {
// Function Call
int sum = add(5, 3);
cout << "Sum: " << sum;
return 0;
}
// 2. Function Definition
int add(int a, int b) {
return a + b; // Return value
}Arguments and Return Values
- Arguments (Parameters): Values passed into a function during a call. In
add(5, 3), 5 and 3 are the arguments. - Return Value: The result sent back by the function to the caller. If a function doesn't return anything, its return type is marked as
void.
Parameter Passing Mechanisms
How arguments are sent to functions significantly impacts performance and data safety.
Pass by Value
A copy of the actual argument is passed into the function. Modifying the parameter inside the function does not affect the original variable.
void modifyValue(int x) {
x = 100; // Only changes the copy
}Call by Reference (&)
An alias (reference) of the actual argument is passed. Modifying the parameter directly changes the original variable. It is efficient because it avoids copying data.
void modifyRef(int &x) {
x = 100; // Changes the original variable
}Call by Pointer (*)
The address of the variable is passed to the function. Inside the function, you must dereference the pointer to change the original value.
void modifyPtr(int *ptr) {
*ptr = 100; // Changes the original variable at that address
}
// Called using: modifyPtr(&myVar);Advanced Function Concepts
Recursion
A process where a function calls itself to solve a smaller subset of the same problem. Every recursive function must have a base case to prevent infinite loops.
int factorial(int n) {
if (n <= 1) return 1; // Base case
return n * factorial(n - 1); // Recursive call
}Inline Functions
When you prefix a function with the inline keyword, the compiler tries to replace the function call with the actual function code. This eliminates the overhead of a function call, making it ideal for small, frequently called functions.
inline int square(int x) { return x * x; }
Function Overloading
A feature that allows multiple functions to have the same name but different parameters (different type, number, or order of arguments).
void printData(int i) { cout << "Integer: " << i << endl; }
void printData(double f) { cout << "Float: " << f << endl; }
void printData(string s) { cout << "String: " << s << endl; }Pointers in C++
A pointer is a variable that stores the memory address of another variable.
- & (Address-of operator): Gets the memory address.
- * (Dereference operator): Accesses the value stored at the address.
int var = 20;
int *ptr = &var; // ptr stores the address of var
cout << "Address of var: " << ptr << endl;
cout << "Value of var via pointer: " << *ptr << endl; // Prints 20Structures (struct)
A structure is a user-defined data type that allows you to group variables of different data types under a single name.
- Members of a structure are accessed using the dot (
.) operator. - If using a pointer to a structure, members are accessed using the arrow (
->) operator.
#include <iostream>
using namespace std;
struct Student {
string name;
int rollNumber;
float gpa;
};
int main() {
Student s1 = {"Alice", 101, 3.9};
// Accessing via dot operator
cout << s1.name << " has a GPA of " << s1.gpa << endl;
// Accessing via pointer
Student *ptr = &s1;
cout << "Roll Number: " << ptr->rollNumber << endl;
return 0;
}Unions in C++
Like structures, a union is a user-defined data type that groups different variables. However, unions share the same memory location for all their members.
⚠️ Key Rule: A union can only hold a value for one member at a time. Its total size is equal to the size of its largest member.
English with a size of 11.17 KB