String vs Cstring in C++
String vs Cstring in C++
In C++, `string` and `cstring` (C-style strings) serve different purposes and have distinct characteristics.
Example:
cpp
#include <iostream>
#include <string>
int main() {
std::string s = "Hello, World!";
std::cout << s.length() << std::endl; // Prints: 13
std::cout << s.substr(0, 5) << std::endl; // Prints: Hello
return 0;
}
Example:
cpp
#include <iostream>
#include <cstring>
int main() {
char str[] = "Hello, World!";
std::cout << strlen(str) << std::endl; // Prints: 13
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 1/42
Key Differences
Performance Overhead due to dynamic allocation Faster in some cases (direct memory access)
Use `std::string` in modern C++ code for safety, ease of use, and flexibility.
Use C-style strings (`cstring`) when working with legacy C code, low-level system
programming, or performance-critical applications.
cpp
std::string s = "Hello";
const char* cstr = s.c_str(); // Use c_str()
cpp
Would you like a deeper dive into performance or best practices for specific use cases? 🚀
char [] vs char *
In C++, `char[]` (character array) and `char*` (character pointer) are both used to handle character
sequences (C-style strings), but they have significant differences in memory management, mutability,
and behavior.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 2/42
Example:
cpp
#include <iostream>
int main() {
str1[0] = 'M'; // ✅
char str1[] = "Hello"; // Allocates 6 bytes: {'H', 'e', 'l', 'l', 'o', '\0'}
Allowed
std::cout << str1 << std::endl; // Prints: Mello
return 0;
}
✅ Mutable: You can modify since it's stored as an array in stack memory.
`str1`
cpp
#include <iostream>
int main() {
// str2[0] = 'M'; ❌
char* str2 = "Hello"; // Stores "Hello" in read-only memory (UB if modified)
Undefined Behavior!
std::cout << str2 << std::endl;
return 0;
}
❌ String literals are immutable: Modifying `"Hello"` causes undefined behavior because it's stored
in read-only memory.
cpp
#include <iostream>
#include <cstring>
int main() {
char* str3 = new char[6]; // Allocates memory on the heap
str3[0] = 'M'; // ✅
strcpy(str3, "Hello"); // Copies string into allocated memory
Allowed
std::cout << str3 << std::endl; // Prints: Mello
delete[] str3; // Free memory to prevent leaks
return 0;
}
cpp
It should be:
cpp
In C++, `new` and `malloc()` are both used for dynamic memory allocation, but they have significant
differences in terms of initialization, type safety, and usage.
cpp
#include <iostream>
class MyClass {
public:
MyClass() { std::cout << "Constructor called\n"; }
};
int main() {
delete obj; //
return 0;
✅
MyClass* obj = new MyClass(); // Allocates memory and calls constructor
Free memory
cpp
delete[] arr; // ✅
int* arr = new int[5]; // Allocates an array of 5 integers
Must use delete[]
🔹 2. `malloc()` (C Style)
Comes from C (`#include <cstdlib>`).
Allocates raw memory on the heap without calling a constructor.
Returns a `void*` that must be explicitly cast to the correct type.
Memory is not initialized (contains garbage values).
Must be freed using `free()`.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 5/42
Example: Allocating Memory for an Integer
cpp
#include <iostream>
#include <cstdlib> // Required for malloc()
int main() {
*num = 42; //
free(num); //
✅
int* num = (int*) malloc(sizeof(int)); // Must cast manually
✅
Needs manual initialization
Free memory
return 0;
}
cpp
free(arr); // ✅
int* arr = (int*) malloc(5 * sizeof(int)); // Allocates memory for 5 integers
Must use free()
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 6/42
🔹 Common Pitfalls
❌ Mixing with `free()` or `malloc()` with `delete`
🚫 Wrong:
`new`
cpp
delete p; // ❌
int* p = (int*) malloc(sizeof(int));
Undefined Behavior
🚫 Wrong:
cpp
Would you like a performance comparison or best practices for memory management? 🚀
delete vs free
Both `delete` and `free()` are used for deallocating dynamically allocated memory, but they have
significant differences in object management, destructor calls, and usage.
cpp
#include <iostream>
class MyClass {
public:
MyClass() { std::cout << "Constructor called\n"; }
~MyClass() { std::cout << "Destructor called\n"; }
};
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 7/42
int main() {
delete obj; //
return 0;
✅
MyClass* obj = new MyClass(); // Allocates memory and calls constructor
Calls destructor and deallocates memory
cpp
delete[] arr; // ✅
int* arr = new int[5]; // Allocates an array
Must use delete[] for arrays
🔹 2. `free()` (C Style)
Used to deallocate memory allocated using `malloc()`, `calloc()`, or `realloc()`.
Does not call destructors for objects.
Requires a manual pointer cast when working with complex types.
Does not differentiate between single objects and arrays.
cpp
#include <iostream>
#include <cstdlib>
int main() {
free(num); //
return 0;
✅
int* num = (int*) malloc(sizeof(int)); // Allocates memory
Deallocates memory (no destructor call)
Destructor
Call?
✅ Yes ❌ No
Type Safety? ✅ No need for casting ❌ Requires explicit casting for objects
For Arrays? ✅ `delete[]` needed 🚫 No separate function (same `free()` call)
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 8/42
Feature `delete` (C++) `free()` (C)
Memory
Heap Heap
Source
🔹 Common Pitfalls
❌ Mixing with `malloc()` or `free()` with `new`
🚫 Wrong:
`delete`
cpp
delete p; // ❌
int* p = (int*) malloc(sizeof(int));
Undefined behavior!
🚫 Wrong:
cpp
✅ Correct Pairing:
`new` → `delete`
`new[]` → `delete[]`
`malloc()/calloc()/realloc()` → `free()`
Would you like a deeper dive into memory leaks or performance optimization? 🚀
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 9/42
These three functions are used for dynamic memory allocation in C (and C++ when using C-style
memory management). They differ in initialization, usage, and performance.
Syntax
Example
cpp
#include <iostream>
#include <cstdlib> // Required for malloc()
int main() {
int* arr = (int*) malloc(5 * sizeof(int)); // Allocates memory for 5 integers
if (!arr) { // Check if allocation was successful
std::cerr << "Memory allocation failed!\n";
return 1;
}
🚨 Warning: Since `malloc()` does not initialize memory, the array will contain garbage values.
Syntax
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 10/42
Example
cpp
#include <iostream>
#include <cstdlib>
int main() {
int* arr = (int*) calloc(5, sizeof(int)); // Allocates memory for 5 integers
if (!arr) {
std::cerr << "Memory allocation failed!\n";
return 1;
}
🔹 3. `realloc()` (Reallocation)
Resizes previously allocated memory (`malloc()` or `calloc()`).
If the new size is larger, it may move to a new memory location.
If the new size is smaller, extra memory may be released.
Syntax
cpp
#include <iostream>
#include <cstdlib>
int main() {
int* arr = (int*) malloc(5 * sizeof(int)); // Allocates 5 integers
if (!arr) return 1;
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 11/42
🚨 Warning: Newly allocated memory (if extended) may contain garbage values.
🔹 Key Differences
Feature `malloc()` `calloc()` `realloc()`
Allocates a single
Usage Allocates multiple blocks Resizes allocated memory
block
Initialization
❌ No (garbage ✅ Yes (zeroed memory) ❌ No (new memory is
values) uninitialized)
Faster (no Slower (zero-initialization Depends (can involve copying
Performance
initialization) overhead) memory)
You need fast memory allocation and can manually initialize values later.
Working with raw memory (e.g., file buffers, network data).
🔹 Common Pitfalls
❌ Not Checking for `NULL` (Memory Allocation Failure)
cpp
cpp
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 12/42
Would you like to see a performance comparison or a real-world use case? 🚀
void *
A `void*` (void pointer) is a generic pointer that can hold the address of any data type. It is primarily
used for generic programming, dynamic memory allocation, and function parameters where the
data type is unknown or variable.
1. Generic: Can store addresses of any data type (`int`, `char`, `struct`, etc.).
2. No Dereferencing Without Casting: Since `void*` does not have a specific type, it must be cast
before dereferencing.
3. Used in Memory Functions: `malloc()`, `calloc()`, and `realloc()` return `void*`, which allows
them to allocate memory for any type.
4. Compatible With Any Pointer: A `void*` can be assigned any pointer type without explicit
casting in C, but C++ requires an explicit cast when assigning `void*` to other pointer types.
cpp
#include <iostream>
#include <cstdlib>
int main() {
void* ptr = malloc(sizeof(int)); // Allocates memory for an integer
*intPtr = 42; // ✅
int* intPtr = (int*) ptr;
Now it's safe to use
std::cout << *intPtr << std::endl; // Prints: 42
free(ptr); //
return 0;
✅ Free memory
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 13/42
Example: A Generic Swap Function
cpp
#include <iostream>
#include <cstring> // For memcpy()
int main() {
int x = 10, y = 20;
swap(&x, &y, sizeof(int)); // Swap integers
std::cout << x << " " << y << std::endl; // Prints: 20 10
return 0;
}
cpp
#include <iostream>
struct Node {
void* data; // Can store any data type
Node* next;
};
int main() {
int value = 42;
Node node;
node.data = &value; // Store an int in a void*
node.next = nullptr;
printIntNode(&node); // Prints: 42
return 0;
}
cpp
#include <iostream>
#include <cstdlib>
int main() {
int arr[] = {5, 3, 8, 2, 1};
size_t size = sizeof(arr) / sizeof(arr[0]);
return 0;
}
✅ `qsort()` allows sorting of any data type because it uses `void*` for generic comparisons.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 15/42
Templates (for type-safe generic programming).
`std::any` (for holding any type without type casting).
`std::variant` (for defining a set of allowed types).
struct in c vs c++
`struct` in C vs C++
In both C and C++, `struct` (short for structure) is used to define user-defined data types that group
multiple variables together. However, there are significant differences between how `struct` works in C
and C++.
🔹 1. `struct` in C
Only contains data members (cannot have member functions).
Cannot have constructors or destructors.
Cannot have access specifiers (`private`, `public`, `protected`).
Uses `struct` keyword to declare variables.
Does not support inheritance.
#include <stdio.h>
#include <string.h>
struct Student {
char name[50];
int age;
float gpa;
};
int main() {
struct Student s1; //
strcpy(s1.name, "Alice");
✅Requires `struct` keyword
s1.age = 20;
s1.gpa = 3.8;
🔹 2. `struct` in C++
Supports member functions (methods).
Can have constructors and destructors.
Supports access specifiers (`private`, `public`, `protected`).
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 16/42
Does not require `struct` keyword when declaring variables.
Supports inheritance, similar to `class`.
cpp
#include <iostream>
#include <cstring>
struct Student {
char name[50];
int age;
float gpa;
int main() {
Student s1; // ✅No `struct` keyword needed
s1.setData("Alice", 20, 3.8);
s1.display();
return 0;
}
cpp
#include <iostream>
#include <cstring>
struct Student {
char name[50];
int age;
float gpa;
// ✅ Constructor
Student(const char* n, int a, float g) {
strcpy(name, n);
age = a;
gpa = g;
}
void display() {
std::cout << "Name: " << name << ", Age: " << age << ", GPA: " << gpa << std::endl;
}
};
int main() {
Student s1("Bob", 22, 3.5); // ✅ Calls constructor
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 17/42
s1.display();
return 0;
}
cpp
struct A {
int x; // public by default
};
class B {
int x; // private by default
};
✅ Use `struct` for simple data structures and `class` for complex objects.
cpp
#include <iostream>
struct Animal {
void makeSound() {
std::cout << "Animal sound" << std::endl;
}
};
int main() {
✅ ✅
Dog myDog;
myDog.makeSound(); // Inherited method
myDog.bark(); // Own method
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 18/42
✅ Inheritance works in `struct`, just like `class`!
typedef struct {
int x;
} MyStruct;
cpp
struct MyStruct {
int x;
};
You need a simple data structure (like `Point`, `Vector`, `RGB` color).
You want default public access.
You are working with plain-old data (POD) types.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 19/42
You need encapsulation (data hiding).
You need complex behavior (multiple methods, inheritance).
You prefer default private access.
Final Thoughts
In C, `struct` is only for grouping data.
In C++, `struct` is nearly identical to `class` except for default access.
C++ allows methods, constructors, destructors, and inheritance in `struct`.
In C and C++, function pointers, callbacks, `std::function`, and lambdas are different ways of
implementing higher-order functions, where functions can be passed as parameters.
cpp
#include <iostream>
int main() {
void (*funcPtr)() = sayHello; // Assign function pointer
funcPtr(); // Calls sayHello()
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 20/42
cpp
#include <iostream>
// Callback function
void printData(int value) {
std::cout << "Processed Data: " << value << std::endl;
}
int main() {
processData(printData); // Pass function as argument
return 0;
}
cpp
#include <iostream>
#include <functional> // Required for std::function
int main() {
processData(printData); // Pass function
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 21/42
cpp
#include <iostream>
#include <functional>
int main() {
processData([](int value) { // Inline lambda function
std::cout << "Lambda Processed Data: " << value << std::endl;
});
return 0;
}
cpp
#include <iostream>
#include <functional>
int main() {
int multiplier = 10;
return 0;
}
cpp
#include <iostream>
#include <functional>
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 22/42
int main() {
int counter = 0;
increment(); // Counter: 1
increment(); // Counter: 2
return 0;
}
cpp
#include <iostream>
#include <functional>
class MyClass {
public:
void printMessage(int value) {
std::cout << "Message: " << value << std::endl;
}
};
int main() {
MyClass obj;
processData(std::bind(&MyClass::printMessage, &obj, std::placeholders::_1));
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 23/42
✅ Binds a class member function to be used as a callback.
✅ allows passing
`std::bind` pointer and placeholders (
`this` `_1`, `_2`, etc.).
🔹 Conclusion
Feature Function Pointer `std::function` Lambda
Regular Function Support ✅ Yes ✅ Yes ✅ Yes
Member Function Support ❌ No ✅ Yes (`std::bind`) ✅ Yes (capture `this`)
Lambda Support ❌ No ✅ Yes ✅ Yes
Captures Variables ❌ No ✅ Yes ✅ Yes
Type Safety ❌ No ✅ Yes ✅ Yes
Performance ✅ Fast ❌ Slight overhead ✅ Fast
🚀 When to Use What?
✅ Use function pointers when:
Working in C-style programming.
Performance is critical and no capturing is needed.
memset
The `memset()` function is used to set a block of memory to a specific value. It is a low-level memory
manipulation function available in C and C++ through `<cstring>` or `<string.h>`.
🔹 1. Syntax
c
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 24/42
Parameters
Returns
#include <iostream>
#include <cstring> // Required for memset()
int main() {
char buffer[10];
return 0;
}
cpp
#include <iostream>
#include <cstring>
int main() {
char arr[5];
return 0;
}
#include <iostream>
#include <cstring>
int main() {
int arr[5];
return 0;
}
#include <iostream>
#include <algorithm> // For std::fill
int main() {
int arr[5];
return 0;
}
#include <iostream>
#include <cstring>
struct Student {
char name[20];
int age;
float gpa;
};
int main() {
Student s;
memset(&s, 0, sizeof(s)); // ✅ Safe for zeroing memory
std::cout << "Age: " << s.age << ", GPA: " << s.gpa << std::endl; // Prints: 0 0
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 26/42
✅ Good for clearing structures before use.
❌ Do not use if structure has non-POD types (e.g., `std::string`).
🔹 6. `memset()` Performance
`memset()`is highly optimized and implemented at the assembly level, making it much faster than
manual loops.
cpp
#include <iostream>
#include <cstring>
#include <chrono>
int main() {
char arr1[SIZE], arr2[SIZE];
return 0;
}
🔹 7. `memset()` vs Alternatives
Sets Memory Byte-by- Supports Non-Byte
Function Use Case
Byte? Values?
`memset()`
Initialize bytes, clear
memory
✅ Yes ❌ No
`std::fill()` Initialize integer arrays ❌ No ✅ Yes
`std::vector::assign()` Initialize a vector ❌ No ✅ Yes
🔹 8. When to Use `memset()`?
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 27/42
❌ Avoid `memset()` when:
🚀 Final Thoughts
`memset()` is fast and efficient for byte-wise initialization.
Use it carefully for structs but not for integer arrays.
Prefer `std::fill()` for C++ objects.
Would you like a deeper dive into performance analysis or assembly-level optimizations? 🚀
memmove
The `memmove()` function is used to copy a block of memory from one location to another, even if the
source and destination memory areas overlap. Unlike `memcpy()`, it handles overlapping memory
regions safely.
🔹 1. Syntax
c
Parameters
Returns
🔹 2. `memmove()` vs `memcpy()`
Feature `memcpy()` `memmove()`
Overlapping Memory ❌ Unsafe (Undefined Behavior) ✅ Safe (Handles Overlapping Regions)
Performance ✅ Faster (Optimized for speed) ❌ Slightly slower (Extra checks for overlap)
Usage Copying non-overlapping memory Copying potentially overlapping memory
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 28/42
🔹 3. Example: Using `memmove()` Safely
cpp
#include <iostream>
#include <cstring> // Required for memmove()
int main() {
char str[] = "Hello, World!";
return 0;
}
cpp
#include <iostream>
#include <cstring>
int main() {
char str[] = "Hello, World!";
🚨 Issue: `memcpy()` copies left to right, causing incorrect results when regions overlap.
cpp
#include <iostream>
#include <cstring>
int main() {
char buffer[] = "123456789";
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 29/42
return 0;
}
cpp
#include <iostream>
#include <cstring>
#include <chrono>
int main() {
char src[SIZE], dest[SIZE];
return 0;
}
🚀 Final Thoughts
`memmove()` is slower than `memcpy()` but safer for overlapping memory.
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 30/42
If you're not sure whether memory overlaps, use `memmove()`.
If memory definitely does not overlap, use `memcpy()` for better performance.
Would you like a deeper dive into assembly-level implementation or a real-world use case? 🚀
memcopy
The `memcpy()` function is used to copy a block of memory from one location to another. It is a low-
level memory function, optimized for speed but does not handle overlapping memory regions
safely.
🔹 1. Syntax
c
Parameters
Returns
#include <iostream>
#include <cstring> // Required for memcpy()
int main() {
char source[] = "Hello, World!";
char destination[20];
std::cout << "Destination: " << destination << std::endl; // Output: "Hello, World!"
return 0;
}
cpp
#include <iostream>
#include <cstring>
int main() {
char str[] = "123456789";
🚨 Issue: `memcpy()` copies left to right, causing incorrect results when regions overlap.
✅ Fix: Use `memmove()` for overlapping memory.
cpp
cpp
#include <iostream>
#include <cstring>
struct Student {
char name[20];
int age;
float gpa;
};
int main() {
Student s1 = {"Alice", 20, 3.8};
Student s2;
std::cout << "Copied Student: " << s2.name << ", " << s2.age << ", " << s2.gpa << std::endl;
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 32/42
✅ Works well for Plain Old Data (POD) types.
❌ Avoid for non-POD types (e.g., ).
`std::string`
Performance Comparison
cpp
#include <iostream>
#include <cstring>
#include <chrono>
int main() {
char src[SIZE], dest1[SIZE], dest2[SIZE];
return 0;
}
🔹 6. `memcpy()` vs Alternatives
Function Use Case Handles Overlap? Optimized for Speed?
`memcpy()` Copy non-overlapping memory ❌ No ✅ Yes
`memmove()` Copy overlapping memory ✅ Yes ❌ Slightly slower
`std::copy()` Copy elements in C++ containers ✅ Yes ✅ Yes (for iterators)
🔹 7. When to Use `memcpy()`?
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 33/42
Copying C++ objects with constructors/destructors → Use `std::copy()`.
🚀 Final Thoughts
`memcpy()` is fast and efficient but unsafe for overlapping memory.
Use `memmove()` if memory regions may overlap.
Prefer `std::copy()` in modern C++ for type safety.
Would you like a deeper dive into assembly-level optimizations or real-world use cases? 🚀
macros
Macros are preprocessor directives that perform text substitution before compilation. They are
defined using the `#define` directive and are useful for defining constants, inline functions,
conditional compilation, and debugging.
#include <stdio.h>
#define PI 3.14159
int main() {
printf("PI = %f\n", PI); // Output: PI = 3.14159
return 0;
}
#include <stdio.h>
int main() {
printf("%d\n", SQUARE(5)); // Output: 25
printf("%d\n", SQUARE(4 + 1)); //
return 0;
🚨
Incorrect: Expands to (4 + 1 * 4 + 1) = 6
🔹 3. Multi-Line Macros
Use `do { ... } while(0)` to ensure safe expansion in conditionals.
#include <stdio.h>
#define DEBUG_PRINT(msg) do { \
printf("Debug: %s\n", msg); \
} while(0)
int main() {
DEBUG_PRINT("Hello, World!");
return 0;
}
#include <stdio.h>
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 35/42
int main() {
int value = 10;
PRINT_VAR(value); // Output: value = 10
return 0;
}
#include <stdio.h>
int main() {
CREATE_VAR(value, 1) = 10; // Expands to `int value1 = 10;`
printf("%d\n", value1); // Output: 10
return 0;
}
#include <stdio.h>
int main() {
#ifdef DEBUG
printf("Debug Mode Enabled\n");
#else
printf("Release Mode\n");
#endif
return 0;
}
#ifndef MY_HEADER_H
#define MY_HEADER_H
void myFunction();
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 36/42
#endif // MY_HEADER_H
#pragma once
void myFunction();
cpp
#include <iostream>
int main() {
std::cout << square(5) << std::endl; // Output: 25
return 0;
}
#include <stdio.h>
#define LOG_ERROR(msg) printf("Error: %s (File: %s, Line: %d, Function: %s)\n", msg, __FILE__, __LIN
void testFunction() {
LOG_ERROR("Something went wrong");
}
int main() {
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 37/42
testFunction();
return 0;
}
✅ Displays the exact file, line, and function where an error occurs!
🔹 9. Common Macro Pitfalls
❌ Using Macros for Constants Instead of `const`
#define PI 3.14159 // ❌ ✅
No type safety
const double pi = 3.14159; // Type safe in C++
#define MULTIPLY(a, b) a * b
int result = MULTIPLY(2 + 3, 4); // ❌ ✅
Expands to `2 + 3 * 4` = 14 instead of 20
#define FIXED_MULTIPLY(a, b) ((a) * (b)) // Use parentheses!
🚀 Final Thoughts
Macros are powerful but should be used carefully.
Prefer `const`, `inline`, and `constexpr` in C++.
Use `#pragma once` over traditional include guards.
Debugging macros (`__FILE__`, `__LINE__`) are great for logging!
casting
cpp
#include <iostream>
int main() {
int a = 10;
double b = a; // ✅ Implicit conversion (int → double)
std::cout << b << std::endl; // Output: 10.0000
return 0;
}
cpp
#include <iostream>
int main() {
double pi = 3.14159;
int int_pi = (int) pi; // ✅ Explicit cast (C-style)
std::cout << int_pi << std::endl; // Output: 3
return 0;
}
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 39/42
🚨 Data Loss: `3.14159` → `3`
Example: `static_cast<>`
cpp
#include <iostream>
int main() {
double pi = 3.14159;
int int_pi = static_cast<int>(pi); // ✅ Safer explicit cast
std::cout << int_pi << std::endl; // Output: 3
return 0;
}
cpp
#include <iostream>
int main() {
int num = 65;
char* ptr = reinterpret_cast<char*>(&num); // ⚠️Converts int* → char*
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 40/42
cpp
#include <iostream>
int main() {
const char* msg = "hello";
modifyString(const_cast<char*>(msg)); // ✅ Remove `const`
return 0;
}
cpp
#include <iostream>
class Base {
public:
virtual void show() {} // Polymorphic base class
};
int main() {
Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
derivedPtr->sayHello(); //
} else {
✅ Safe: Prints "Hello from Derived!"
delete basePtr;
return 0;
}
🔹 8. Casting Pointers
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 41/42
Cast Type Use Case Safe?
`static_cast<>` Convert between related types (e.g., `int` → `double`) ✅ Yes
`reinterpret_cast<>` Convert pointer types (e.g., `int*` → `char*`) ❌ No
`const_cast<>` Add or remove `const` ⚠️ Caution
`dynamic_cast<>` Downcasting in inheritance (with virtual functions) ✅ Yes
🔹 9. When to Use Which Cast?
✅ Use `static_cast<>` when:
Removing `const` to pass data to functions that don’t accept `const` parameters.
❌ Avoid C-style casts ( `(type)`) in C++ as they are unsafe and error-prone.
🚀 Final Thoughts
Use `static_cast<>` for safe conversions.
Avoid `reinterpret_cast<>` unless absolutely necessary.
Use `dynamic_cast<>` for safe downcasting in inheritance.
Prefer C++ casts (`static_cast`, `reinterpret_cast`, etc.) over C-style casts.
Would you like more real-world examples or a deep dive into performance considerations? 🚀
Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 42/42