Show description
C/C++ Fundamentals Reference
C/C++ Fundamentals Reference
C/C++ Fundamentals Reference
Table of Contents
Data Types
Memory Organization
Basic Data Handling
Byte Addressable Memory
C-Style Strings
String Handling Operations
Common Patterns & Best Practices
Data Types
Fundamental Data Types
Type
Size (bytes)
Range
Description
char
1
-128 to 127 or 0 to 255
Single character or small integer
unsigned char
1
0 to 255
Unsigned character
short (short int)
2
-32,768 to 32,767
Short integer
unsigned short
2
0 to 65,535
Unsigned short integer
int
4
-2,147,483,648 to 2,147,483,647
Standard integer
unsigned int
4
0 to 4,294,967,295
Unsigned integer
long
8
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Long integer
unsigned long
8
0 to 18,446,744,073,709,551,615
Unsigned long integer
float
4
±3.4E±38 (7 digits precision)
Single precision floating point
double
8
±1.7E±308 (15 digits precision)
Double precision floating point
long double
16
Extended precision
Extended precision floating point
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main() {
printf("char: %zu bytes, range: %d to %d\n", sizeof(char), CHAR_MIN, CHAR_MAX);
printf("int: %zu bytes, range: %d to %d\n", sizeof(int), INT_MIN, INT_MAX);
printf("long: %zu bytes, range: %ld to %ld\n", sizeof(long), LONG_MIN, LONG_MAX);
printf("float: %zu bytes, range: %E to %E\n", sizeof(float), FLT_MIN, FLT_MAX);
printf("double: %zu bytes, range: %E to %E\n", sizeof(double), DBL_MIN, DBL_MAX);
return 0;
}
Derived Data Types
arrays - Collection of elements of same type
pointers - Variables that store memory addresses
structures - Custom data types with multiple members
unions - Data types where members share same memory
enumerations - Named integer constants
functions - Code blocks that perform specific tasks
Memory Organization
Memory Layout
┌─────────────────┐ ← High Address
│ Stack │
│ (grows down) │
├─────────────────┤
│ │
│ Free Space │
│ │
├─────────────────┤
│ Heap │
│ (grows up) │
├─────────────────┤
│ BSS Segment │
│ (uninitialized)│
├─────────────────┤
│ Data Segment │
│ (initialized) │
├─────────────────┤
│ Text Segment │
│ (cod…
C/C++ Fundamentals Reference
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>C/C++ Fundamentals Reference</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
background-color: #0d1117;
color: #f0f6fc;
line-height: 1.6;
font-size: 14px;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
h1 {
color: #7dd3fc;
text-align: center;
margin-bottom: 30px;
font-size: 2.5em;
border-bottom: 3px solid #22c55e;
padding-bottom: 10px;
}
h2 {
color: #22c55e;
margin: 30px 0 15px 0;
font-size: 1.8em;
border-left: 4px solid #22c55e;
padding-left: 15px;
}
h3 {
color: #4ade80;
margin: 20px 0 10px 0;
font-size: 1.3em;
}
.section {
background-color: #161b22;
border: 1px solid #30363d;
border-radius: 8px;
padding: 20px;
margin-bottom: 25px;
}
.code {
background-color: #0d1117;
border: 1px solid #4ade80;
border-radius: 6px;
padding: 15px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
margin: 10px 0;
overflow-x: auto;
}
.inline-code {
background-color: #262c36;
color: #4ade80;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}
table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
background-color: #0d1117;
}
th, td {
border: 1px solid #4ade80;
padding: 10px;
text-align: left;
}
th {
background-color: #22c55e;
color: #0d1117;
font-weight: bold;
}
tr:nth-child(even) {
background-color: #161b22;
}
.warning {
background-color: #2d1b1e;
border: 1px solid #ef4444;
border-radius: 6px;
padding: 15px;
margin: 15px 0;
}
.tip {
background-color: #1e2d1b;
border: 1px solid #22c55e;
border-radius: 6px;
padding: 15px;
margin: 15px 0;
}
.memory-diagram {
font-family: monospace;
background-color: #0d1117;
border: 2px solid #4ade80;
padding: 15px;
margin: 15px 0;
text-align: center;
}
ul, ol {
margin: 10px 0 10px 30px;
}
li {
margin: 5px 0;
}
.toc {
background-color: #161b22;
border: 1px solid #4ade80;
border-radius: 8px;
padding: 20px;
margin-bottom: 30px;
}
.toc a {
color: #4ade80;
text-decoration: none;
}
.toc a:hover {
color: #7dd3fc;
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>C/C++ Fundamentals Reference</h1>
<div class="toc">
<h2>Table of Contents</h2>
<ol>
<li><a href="#data-types">Data Types</a></li>
<li><a href="#memory-organization">Memory Organization</a></li>
<li><a href="#basic-data-handling">Basic Data Handling</a></li>
<li><a href="#byte-addressing">Byte Addressable Memory</a></li>
<li><a href="#c-strings">C-Style Strings</a></li>
<li><a href="#string-handling">String Handling Operations</a></li>
<li><a href="#common-patterns">Common Patterns & Best Practices</a></li>
</ol>
</div>
<div class="section" id="data-types">
<h2>Data Types</h2>
<h3>Fundamental Data Types</h3>
<table>
<tr>
<th>Type</th>
<th>Size (bytes)</th>
<th>Range</th>
<th>Description</th>
</tr>
<tr>
<td>char</td>
<td>1</td>
<td>-128 to 127 or 0 to 255</td>
<td>Single character or small integer</td>
</tr>
<tr>
<td>unsigned char</td>
<td>1</td>
<td>0 to 255</td>
<td>Unsigned character</td>
</tr>
<tr>
<td>short (short int)</td>
<td>2</td>
<td>-32,768 to 32,767</td>
<td>Short integer</td>
</tr>
<tr>
<td>unsigned short</td>
<td>2</td>
<td>0 to 65,535</td>
<td>Unsigned short integer</td>
</tr>
<tr>
<td>int</td>
<td>4</td>
<td>-2,147,483,648 to 2,147,483,647</td>
<td>Standard integer</td>
</tr>
<tr>
<td>unsigned int</td>
<td>4</td>
<td>0 to 4,294,967,295</td>
<td>Unsigned integer</td>
</tr>
<tr>
<td>long</td>
<td>8</td>
<td>-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807</td>
<td>Long integer</td>
</tr>
<tr>
<td>unsigned long</td>
<td>8</td>
<td>0 to 18,446,744,073,709,551,615</td>
<td>Unsigned long integer</td>
</tr>
<tr>
<td>float</td>
<td>4</td>
<td>±3.4E±38 (7 digits precision)</td>
<td>Single precision floating point</td>
</tr>
<tr>
<td>double</td>
<td>8</td>
<td>±1.7E±308 (15 digits precision)</td>
<td>Double precision floating point</td>
</tr>
<tr>
<td>long double</td>
<td>16</td>
<td>Extended precision</td>
<td>Extended precision floating point</td>
</tr>
</table>
<div class="code">
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main() {
printf("char: %zu bytes, range: %d to %d\n", sizeof(char), CHAR_MIN, CHAR_MAX);
printf("int: %zu bytes, range: %d to %d\n", sizeof(int), INT_MIN, INT_MAX);
printf("long: %zu bytes, range: %ld to %ld\n", sizeof(long), LONG_MIN, LONG_MAX);
printf("float: %zu bytes, range: %E to %E\n", sizeof(float), FLT_MIN, FLT_MAX);
printf("double: %zu bytes, range: %E to %E\n", sizeof(double), DBL_MIN, DBL_MAX);
return 0;
}
</div>
<h3>Derived Data Types</h3>
<ul>
<li><span class="inline-code">arrays</span> - Collection of elements of same type</li>
<li><span class="inline-code">pointers</span> - Variables that store memory addresses</li>
<li><span class="inline-code">structures</span> - Custom data types with multiple members</li>
<li><span class="inline-code">unions</span> - Data types where members share same memory</li>
<li><span class="inline-code">enumerations</span> - Named integer constants</li>
<li><span class="inline-code">functions</span> - Code blocks that perform specific tasks</li>
</ul>
</div>
<div class="section" id="memory-organization">
<h2>Memory Organization</h2>
<h3>Memory Layout</h3>
<div class="memory-diagram">
<div>┌─────────────────┐ ← High Address</div>
<div>│ Stack │</div>
<div>│ (grows down) │</div>
<div>├─────────────────┤</div>
<div>│ │</div>
<div>│ Free Space │</div>
<div>│ │</div>
<div>├─────────────────┤</div>
<div>│ Heap │</div>
<div>│ (grows up) │</div>
<div>├─────────────────┤</div>
<div>│ BSS Segment │</div>
<div>│ (uninitialized)│</div>
<div>├─────────────────┤</div>
<div>│ Data Segment │</div>
<div>│ (initialized) │</div>
<div>├─────────────────┤</div>
<div>│ Text Segment │</div>
<div>│ (code) │ ← Low Address</div>
<div>└─────────────────┘</div>
</div>
<h3>Memory Segments</h3>
<ul>
<li><strong>Text Segment:</strong> Contains executable code (read-only)</li>
<li><strong>Data Segment:</strong> Initialized global and static variables</li>
<li><strong>BSS Segment:</strong> Uninitialized global and static variables</li>
<li><strong>Heap:</strong> Dynamic memory allocation (malloc, new)</li>
<li><strong>Stack:</strong> Local variables, function parameters, return addresses</li>
</ul>
<div class="code">
#include <stdio.h>
#include <stdlib.h>
int global_var = 100; // Data segment
int uninitialized_var; // BSS segment
int main() {
int local_var = 50; // Stack
int *heap_var = malloc(sizeof(int)); // Heap
*heap_var = 75;
printf("Global var address: %p\n", &global_var);
printf("Local var address: %p\n", &local_var);
printf("Heap var address: %p\n", heap_var);
free(heap_var);
return 0;
}
</div>
</div>
<div class="section" id="basic-data-handling">
<h2>Basic Data Handling</h2>
<h3>Variables and Constants</h3>
<div class="code">
// Variable declarations and initialization
int x = 10; // Initialize at declaration
int y; // Declare, initialize later
y = 20;
const int MAX_SIZE = 100; // Constant (cannot be changed)
#define PI 3.14159 // Preprocessor constant
// Type qualifiers
volatile int sensor_data; // Value may change unexpectedly
register int counter; // Suggest storing in CPU register
static int file_scope; // Internal linkage
extern int global_from_other_file; // External linkage
</div>
<h3>Arrays</h3>
<div class="code">
// Array declaration and initialization
int numbers[5]; // Uninitialized array
int values[5] = {1, 2, 3, 4, 5}; // Initialized array
int partial[5] = {1, 2}; // Partially initialized (rest are 0)
int auto_size[] = {1, 2, 3}; // Size determined by initializer
// Multidimensional arrays
int matrix[3][4]; // 3x4 matrix
int cube[2][3][4] = { // 3D array with initialization
{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}},
{{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}}
};
// Array access
for (int i = 0; i < 5; i++) {
numbers[i] = i * 10;
}
</div>
<h3>Pointers</h3>
<div class="code">
// Pointer declaration and usage
int value = 42;
int *ptr = &value; // Pointer to int, initialized with address of value
int **double_ptr = &ptr; // Pointer to pointer
printf("Value: %d\n", value); // 42
printf("Address of value: %p\n", &value);
printf("Pointer value: %p\n", ptr);
printf("Value through pointer: %d\n", *ptr); // Dereferencing
// Pointer arithmetic
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr; // Points to first element
printf("First element: %d\n", *p); // 10
printf("Second element: %d\n", *(p+1)); // 20
printf("Third element: %d\n", p[2]); // 30 (equivalent to *(p+2))
// Moving through array
for (int i = 0; i < 5; i++) {
printf("Element %d: %d at address %p\n", i, *p, p);
p++;
}
</div>
<div class="tip">
<strong>Tip:</strong> Array names are essentially constant pointers to the first element. <span class="inline-code">arr</span> and <span class="inline-code">&arr[0]</span> are equivalent.
</div>
</div>
<div class="section" id="byte-addressing">
<h2>Byte Addressable Memory</h2>
<h3>Understanding Memory Addresses</h3>
<p>In C/C++, memory is byte-addressable, meaning each byte has a unique address. Understanding this is crucial for pointer arithmetic and memory manipulation.</p>
<div class="code">
#include <stdio.h>
int main() {
char c = 'A';
short s = 1000;
int i = 50000;
double d = 3.14159;
printf("char 'A' at address %p, size: %zu bytes\n", &c, sizeof(c));
printf("short 1000 at address %p, size: %zu bytes\n", &s, sizeof(s));
printf("int 50000 at address %p, size: %zu bytes\n", &i, sizeof(i));
printf("double 3.14159 at address %p, size: %zu bytes\n", &d, sizeof(d));
// Examining memory byte by byte
unsigned char *byte_ptr = (unsigned char*)&i;
printf("Integer %d stored as bytes: ", i);
for (size_t j = 0; j < sizeof(i); j++) {
printf("0x%02X ", byte_ptr[j]);
}
printf("\n");
return 0;
}
</div>
<h3>Memory Layout Example</h3>
<div class="memory-diagram">
<div>Array: int arr[4] = {0x12345678, 0x9ABCDEF0, 0x11111111, 0x22222222}</div>
<br>
<div>Address │ Byte 0 │ Byte 1 │ Byte 2 │ Byte 3 │ Value</div>
<div>─────────┼────────┼────────┼────────┼────────┼──────────</div>
<div>0x1000 │ 78 │ 56 │ 34 │ 12 │ arr[0]</div>
<div>0x1004 │ F0 │ DE │ BC │ 9A │ arr[1]</div>
<div>0x1008 │ 11 │ 11 │ 11 │ 11 │ arr[2]</div>
<div>0x100C │ 22 │ 22 │ 22 │ 22 │ arr[3]</div>
</div>
<div class="warning">
<strong>Important:</strong> The byte order shown above assumes little-endian architecture (least significant byte first). On big-endian systems, the byte order would be reversed.
</div>
<h3>Pointer Arithmetic and Byte Addressing</h3>
<div class="code">
#include <stdio.h>
int main() {
int arr[4] = {0x12345678, 0x9ABCDEF0, 0x11111111, 0x22222222};
printf("Array addresses and values:\n");
for (int i = 0; i < 4; i++) {
printf("arr[%d] = 0x%08X at address %p\n", i, arr[i], &arr[i]);
}
// Pointer arithmetic - moves by sizeof(type) bytes
int *ptr = arr;
printf("\nPointer arithmetic:\n");
printf("ptr points to %p, value: 0x%08X\n", ptr, *ptr);
ptr++; // Moves by sizeof(int) = 4 bytes
printf("ptr++ points to %p, value: 0x%08X\n", ptr, *ptr);
// Byte-level access
unsigned char *byte_ptr = (unsigned char*)arr;
printf("\nByte-level access of first integer:\n");
for (int i = 0; i < 4; i++) {
printf("Byte %d: 0x%02X at address %p\n", i, byte_ptr[i], &byte_ptr[i]);
}
return 0;
}
</div>
</div>
<div class="section" id="c-strings">
<h2>C-Style Strings</h2>
<h3>String Representation</h3>
<p>C-style strings are arrays of characters terminated by a null character ('\0' or ASCII 0).</p>
<div class="code">
#include <stdio.h>
#include <string.h>
int main() {
// Different ways to declare and initialize strings
char str1[] = "Hello"; // Size automatically calculated (6 bytes)
char str2[10] = "World"; // Fixed size array, partially filled
char str3[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // Character array
char *str4 = "Constant string"; // Pointer to string literal
printf("String lengths:\n");
printf("str1: \"%s\" length: %zu, array size: %zu\n", str1, strlen(str1), sizeof(str1));
printf("str2: \"%s\" length: %zu, array size: %zu\n", str2, strlen(str2), sizeof(str2));
printf("str3: \"%s\" length: %zu, array size: %zu\n", str3, strlen(str3), sizeof(str3));
printf("str4: \"%s\" length: %zu\n", str4, strlen(str4));
// Examining string memory layout
printf("\nMemory layout of str1 (\"%s\"):\n", str1);
for (size_t i = 0; i < sizeof(str1); i++) {
if (str1[i] == '\0') {
printf("Index %zu: '\\0' (null terminator)\n", i);
} else {
printf("Index %zu: '%c'\n", i, str1[i]);
}
}
return 0;
}
</div>
<h3>String Memory Layout</h3>
<div class="memory-diagram">
<div>char str[] = "Hello";</div>
<br>
<div>Index │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │</div>
<div>──────┼───┼───┼───┼───┼───┼───┤</div>
<div>Char │ H │ e │ l │ l │ o │\0 │</div>
<div>ASCII │72 │101│108│108│111│ 0 │</div>
</div>
<div class="warning">
<strong>Warning:</strong> String literals are stored in read-only memory. Attempting to modify them through a pointer results in undefined behavior.
</div>
</div>
<div class="section" id="string-handling">
<h2>String Handling Operations</h2>
<h3>Standard String Functions</h3>
<div class="code">
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char source[] = "Hello World";
char destination[50];
char buffer[100];
// String copying
strcpy(destination, source);
printf("strcpy result: %s\n", destination);
// Safe string copying (with size limit)
strncpy(buffer, source, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0'; // Ensure null termination
printf("strncpy result: %s\n", buffer);
// String concatenation
strcat(destination, " from C");
printf("strcat result: %s\n", destination);
// Safe string concatenation
strncat(buffer, " - safe version", sizeof(buffer) - strlen(buffer) - 1);
printf("strncat result: %s\n", buffer);
// String comparison
int cmp = strcmp("Apple", "Banana");
printf("strcmp(\"Apple\", \"Banana\"): %d\n", cmp); // Negative
cmp = strcmp("Hello", "Hello");
printf("strcmp(\"Hello\", \"Hello\"): %d\n", cmp); // Zero
// String searching
char *found = strchr(source, 'W');
if (found) {
printf("Found 'W' at position: %ld\n", found - source);
}
found = strstr(source, "World");
if (found) {
printf("Found \"World\" at position: %ld\n", found - source);
}
return 0;
}
</div>
<h3>Manual String Operations</h3>
<div class="code">
// Custom string length function
size_t my_strlen(const char *str) {
size_t length = 0;
while (str[length] != '\0') {
length++;
}
return length;
}
// Custom string copy function
char *my_strcpy(char *dest, const char *src) {
char *original_dest = dest;
while (*src != '\0') {
*dest = *src;
dest++;
src++;
}
*dest = '\0'; // Add null terminator
return original_dest;
}
// Custom string comparison function
int my_strcmp(const char *str1, const char *str2) {
while (*str1 && (*str1 == *str2)) {
str1++;
str2++;
}
return *(unsigned char*)str1 - *(unsigned char*)str2;
}
// Reverse a string in-place
void reverse_string(char *str) {
if (!str) return;
size_t len = strlen(str);
for (size_t i = 0; i < len / 2; i++) {
char temp = str[i];
str[i] = str[len - 1 - i];
str[len - 1 - i] = temp;
}
}
</div>
<h3>Dynamic String Handling</h3>
<div class="code">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Dynamic string creation
char *create_string(const char *source) {
if (!source) return NULL;
size_t len = strlen(source);
char *new_str = malloc(len + 1); // +1 for null terminator
if (!new_str) return NULL; // Check for allocation failure
strcpy(new_str, source);
return new_str;
}
// String concatenation with dynamic allocation
char *concat_strings(const char *str1, const char *str2) {
if (!str1 || !str2) return NULL;
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
char *result = malloc(len1 + len2 + 1);
if (!result) return NULL;
strcpy(result, str1);
strcat(result, str2);
return result;
}
int main() {
char *dynamic_str = create_string("Hello");
printf("Dynamic string: %s\n", dynamic_str);
char *combined = concat_strings(dynamic_str, " World!");
printf("Combined string: %s\n", combined);
// Always free dynamically allocated memory
free(dynamic_str);
free(combined);
return 0;
}
</div>
<div class="tip">
<strong>Memory Management:</strong> Always pair <span class="inline-code">malloc()</span> with <span class="inline-code">free()</span>, and set pointers to NULL after freeing to avoid dangling pointers.
</div>
</div>
<div class="section" id="common-patterns">
<h2>Common Patterns & Best Practices</h2>
<h3>Safe String Input</h3>
<div class="code">
#include <stdio.h>
#include <string.h>
// Safe string input function
void safe_gets(char *buffer, size_t buffer_size) {
if (fgets(buffer, buffer_size, stdin)) {
// Remove newline if present
size_t len = strlen(buffer);
if (len > 0 && buffer[len-1] == '\n') {
buffer[len-1] = '\0';
}
}
}
int main() {
char name[50];
printf("Enter your name: ");
safe_gets(name, sizeof(name));
printf("Hello, %s!\n", name);
return 0;
}
</div>
<h3>Error Handling Patterns</h3>
<div class="code">
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
// Function with proper error handling
char *safe_string_duplicate(const char *source) {
if (!source) {
fprintf(stderr, "Error: NULL pointer passed to safe_string_duplicate\n");
return NULL;
}
size_t len = strlen(source);
char *duplicate = malloc(len + 1);
if (!duplicate) {
fprintf(stderr, "Error: Memory allocation failed: %s\n", strerror(errno));
return NULL;
}
memcpy(duplicate, source, len + 1); // Include null terminator
return duplicate;
}
// File reading with error checking
int read_file_to_string(const char *filename, char **content) {
FILE *file = fopen(filename, "r");
if (!file) {
fprintf(stderr, "Error opening file '%s': %s\n", filename, strerror(errno));
return -1;
}
// Get file size
fseek(file, 0, SEEK_END);
long size = ftell(file);
fseek(file, 0, SEEK_SET);
*content = malloc(size + 1);
if (!*content) {
fprintf(stderr, "Memory allocation failed\n");
fclose(file);
return -1;
}
size_t bytes_read = fread(*content, 1, size, file);
(*content)[bytes_read] = '\0';
fclose(file);
return 0;
}
</div>
<h3>Memory Layout Debugging</h3>
<div class="code">
#include <stdio.h>
// Function to print memory contents as hex
void print_memory(const void *ptr, size_t size) {
const unsigned char *byte_ptr = (const unsigned char*)ptr;
printf("Memory contents at %p:\n", ptr);
printf("Offset: ");
for (size_t i = 0; i < size; i++) {
printf("%02zX ", i);
}
printf("\n");
printf("Value: ");
for (size_t i = 0; i < size; i++) {
printf("%02X ", byte_ptr[i]);
}
printf("\n");
printf("ASCII: ");
for (size_t i = 0; i < size; i++) {
if (byte_ptr[i] >= 32 && byte_ptr[i] <= 126) {
printf(" %c ", byte_ptr[i]);
} else {
printf(" . ");
}
}
printf("\n\n");
}
int main() {
char string[] = "Hello\0Hidden";
int number = 0x12345678;
printf("String analysis:\n");
print_memory(string, sizeof(string));
printf("Integer analysis:\n");
print_memory(&number, sizeof(number));
return 0;
}
</div>
<h3>Performance Considerations</h3>
<div class="tip">
<strong>Performance Tips:</strong>
<ul>
<li>Use <span class="inline-code">memcpy()</span> instead of <span class="inline-code">strcpy()</span> when you know the length</li>
<li>Cache string lengths in loops to avoid repeated <span class="inline-code">strlen()</span> calls</li>
<li>Use <span class="inline-code">const</span> for read-only string parameters</li>
<li>Consider using <span class="inline-code">static</span> buffers for temporary strings in frequently called functions</li>
<li>Use string builders or dynamic arrays for string concatenation in loops</li>
</ul>
</div>
<h3>Common Pitfalls</h3>
<div class="warning">
<strong>Watch Out For:</strong>
<ul>
<li><strong>Buffer Overflows:</strong> Always check bounds when copying strings</li>
<li><strong>Missing Null Terminators:</strong> <span class="inline-code">strncpy()</span> doesn't always add '\0'</li>
<li><strong>Dangling Pointers:</strong> Don't use pointers after freeing memory</li>
<li><strong>Memory Leaks:</strong> Every <span class="inline-code">malloc()</span> needs a corresponding <span class="inline-code">free()</span></li>
<li><strong>Modifying String Literals:</strong> String literals are read-only</li>
<li><strong>Uninitialized Arrays:</strong> Local arrays contain garbage values</li>
</ul>
</div>
</div>
<div class="section">
<h2>Quick Reference</h2>
<h3>Essential Functions</h3>
<table>
<tr>
<th>Function</th>
<th>Purpose</th>
<th>Example</th>
</tr>
<tr>
<td>strlen()</td>
<td>Get string length</td>
<td>size_t len = strlen("hello");</td>
</tr>
<tr>
<td>strcpy()</td>
<td>Copy string</td>
<td>strcpy(dest, src);</td>
</tr>
<tr>
<td>strncpy()</td>
<td>Copy n characters</td>
<td>strncpy(dest, src, n);</td>
</tr>
<tr>
<td>strcat()</td>
<td>Concatenate strings</td>
<td>strcat(dest, src);</td>
</tr>
<tr>
<td>strcmp()</td>
<td>Compare strings</td>
<td>int cmp = strcmp(s1, s2);</td>
</tr>
<tr>
<td>strchr()</td>
<td>Find character</td>
<td>char *p = strchr(str, 'c');</td>
</tr>
<tr>
<td>strstr()</td>
<td>Find substring</td>
<td>char *p = strstr(str, "sub");</td>
</tr>
<tr>
<td>malloc()</td>
<td>Allocate memory</td>
<td>char *p = malloc(100);</td>
</tr>
<tr>
<td>free()</td>
<td>Free memory</td>
<td>free(p);</td>
</tr>
</table>
</div>
</div>
</body>
</html>