C++ Programming: Streams, Functions, and Memory

Posted by Anonymous and classified in Computers

Written on in English with a size of 11.17 KB

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.

FunctionDescriptionExample
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>.

ManipulatorEquivalent Member FunctionDescription
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 / octsetf(ios::hex), etc.Changes the base of the number.
left / rightsetf(ios::left), etc.Adjusts the alignment.
fixed / scientificsetf(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 20

Structures (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.

Related entries: