C++ Arrays & Strings Quiz

C++
0 Passed
0% acceptance

40 comprehensive questions on C++ arrays and strings, covering fixed-size arrays, C-style strings, std::string fundamentals, string operations, and array iteration patterns — with 20 code examples to master memory management and string handling.

40 Questions
~80 minutes
1

Question 1

When declaring a fixed-size array in C++, what fundamental constraint must be known at compile time?

cpp
#include <iostream>

int main() {
    // Fixed-size array - size must be compile-time constant
    int numbers[5] = {1, 2, 3, 4, 5};
    
    for(int i = 0; i < 5; ++i) {
        std::cout << numbers[i] << " ";
    }
    return 0;
}
A
The array size must be a compile-time constant expression, not a runtime variable, because the memory layout is determined during compilation
B
The array can be any size as long as there's enough memory at runtime
C
The size must be a power of 2 for optimal performance
D
The size can be determined by the number of initializer elements
2

Question 2

In a scenario where you need to store a collection of integers that won't change size during program execution, what array type provides the most efficient memory usage and access performance?

A
Fixed-size arrays offer the best performance with direct memory access and no dynamic allocation overhead
B
std::vector provides better performance through contiguous memory and cache-friendly access
C
std::array combines the performance of C-style arrays with the safety of standard library containers
D
Dynamic arrays allocated with new[] offer the most flexibility for size changes
3

Question 3

When working with C-style strings that contain user input, what critical safety issue must be addressed to prevent buffer overflow vulnerabilities?

cpp
#include <iostream>
#include <cstring>

int main() {
    char buffer[10];
    std::cout << "Enter text: ";
    std::cin >> buffer;  // Dangerous - no bounds checking
    
    // What if user enters more than 9 characters?
    std::cout << "You entered: " << buffer << std::endl;
    return 0;
}
A
C-style strings require manual bounds checking because input operations don't prevent writing beyond array limits, leading to buffer overflows
B
C-style strings automatically resize when input exceeds the buffer size
C
The null terminator prevents any overflow issues
D
Modern compilers automatically add bounds checking to C-style string operations
4

Question 4

What fundamental difference exists between C-style strings and std::string when it comes to memory management and safety?

A
std::string automatically manages memory and tracks size, while C-style strings require manual memory management and are prone to buffer overflows
B
C-style strings are safer because they include null termination
C
std::string cannot be used with C APIs that expect char*
D
Both types have identical memory management and safety characteristics
5

Question 5

When initializing a fixed-size array with fewer values than its declared size, what happens to the remaining elements?

cpp
#include <iostream>

int main() {
    int arr[5] = {1, 2, 3};  // Only 3 values provided
    
    for(int i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";  // What are arr[3] and arr[4]?
    }
    return 0;
}
A
Remaining elements are zero-initialized, so arr[3] and arr[4] will be 0
B
Remaining elements contain garbage values from uninitialized memory
C
The array size automatically adjusts to match the number of initializers
D
Compilation fails due to insufficient initializers
6

Question 6

In a performance-critical application that processes text data from external sources, what string type provides the best balance between safety and the ability to work with C APIs?

A
std::string offers safety and convenience while providing c_str() method for C API compatibility
B
C-style strings are always faster and should be used for performance-critical code
C
std::string cannot be used safely with external text data
D
Custom string classes provide better performance than both options
7

Question 7

When concatenating multiple strings in a loop where the total size is unknown beforehand, what approach avoids repeated memory allocations and copying?

cpp
#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> words = {"Hello", " ", "World", "!"};
    std::string result;
    
    // Inefficient: reallocates and copies on each append
    for(const auto& word : words) {
        result += word;
    }
    
    std::cout << result << std::endl;
    return 0;
}
A
Reserve capacity beforehand with result.reserve(total_size) to avoid reallocations, or use a stringstream for complex concatenations
B
Use C-style string concatenation with strcat() which is always efficient
C
The compiler automatically optimizes string concatenation in loops
D
Use fixed-size arrays to avoid dynamic memory allocation entirely
8

Question 8

What happens when you attempt to access an array element beyond its bounds in C++?

cpp
#include <iostream>

int main() {
    int arr[3] = {1, 2, 3};
    
    // This is undefined behavior
    std::cout << arr[5] << std::endl;  // Accessing out of bounds
    
    return 0;
}
A
Undefined behavior occurs - the program may crash, produce garbage values, or appear to work correctly depending on memory layout
B
The program throws an exception that can be caught
C
The array automatically resizes to accommodate the access
D
The compiler prevents out-of-bounds access at compile time
9

Question 9

When comparing two std::string objects for equality, what factors determine whether they are considered equal?

cpp
#include <iostream>
#include <string>

int main() {
    std::string s1 = "Hello";
    std::string s2 = "Hello";
    
    if(s1 == s2) {
        std::cout << "Strings are equal" << std::endl;
    }
    
    return 0;
}
A
std::string comparison is lexicographical and case-sensitive, comparing character by character until a difference is found or both end
B
Strings are equal only if they refer to the same memory location
C
Comparison ignores case differences between strings
D
Only the first character is compared for equality
10

Question 10

In a situation where you need to iterate through a fixed-size array while performing complex operations on each element, what iteration pattern provides the most readable and maintainable code?

cpp
#include <iostream>

int main() {
    int numbers[5] = {1, 2, 3, 4, 5};
    
    // Range-based for loop - modern and safe
    for(int num : numbers) {
        std::cout << num * 2 << " ";
    }
    
    return 0;
}
A
Range-based for loops provide the cleanest syntax and eliminate off-by-one errors while working with any iterable type
B
Traditional for loops with indices are always more efficient and should be preferred
C
While loops provide better control flow for array iteration
D
Recursion is the most readable way to process array elements
11

Question 11

When working with C-style strings that may contain embedded null characters, what critical limitation affects their usability?

A
C-style strings use null termination, so embedded null characters are treated as string terminators, truncating the string unexpectedly
B
C-style strings cannot contain any special characters
C
C-style strings have a maximum length of 255 characters
D
C-style strings automatically resize when null characters are encountered
12

Question 12

What is the most efficient way to initialize a large fixed-size array with all elements set to the same value?

cpp
#include <iostream>
#include <algorithm>

int main() {
    const int SIZE = 1000;
    int arr[SIZE];
    
    // Efficient initialization with std::fill
    std::fill(std::begin(arr), std::end(arr), 42);
    
    std::cout << "First element: " << arr[0] << std::endl;
    std::cout << "Last element: " << arr[SIZE-1] << std::endl;
    
    return 0;
}
A
Use std::fill with std::begin and std::end for efficient initialization of large arrays with a single value
B
Use a loop to set each element individually for maximum control
C
Initialize with an initializer list containing the repeated value
D
Use memset from C standard library for the fastest initialization
13

Question 13

When passing a fixed-size array to a function, what happens to the array's size information and how can it be preserved?

cpp
#include <iostream>

// Array decays to pointer, size information lost
void printArray(int arr[], int size) {
    for(int i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}

// Template preserves size information
// template<size_t N>
// void printArray(int (&arr)[N]) {
//     for(int num : arr) {
//         std::cout << num << " ";
//     }
// }

int main() {
    int numbers[5] = {1, 2, 3, 4, 5};
    printArray(numbers, 5);  // Must pass size separately
    return 0;
}
A
Arrays decay to pointers losing size information, requiring size to be passed separately or using templates with reference syntax to preserve size
B
Array size is automatically preserved when passed to functions
C
Functions can use sizeof to determine array size from pointer parameters
D
Arrays cannot be passed to functions in C++
14

Question 14

In a program that needs to build a string incrementally from various sources, what std::string method provides the most efficient way to append data without creating temporary objects?

A
append() method allows direct appending to the string's internal buffer, avoiding temporary string creation
B
Using + operator creates more readable code and the compiler optimizes it automatically
C
push_back() method is most efficient for single character additions
D
insert() method provides the best performance for all append operations
15

Question 15

What is the key difference between array initialization syntax and assignment syntax in C++?

cpp
#include <iostream>

int main() {
    int arr1[3] = {1, 2, 3};  // Initialization
    
    int arr2[3];
    // arr2 = {1, 2, 3};  // This is invalid!
    
    // Must use assignment to individual elements or std::copy
    arr2[0] = 1; arr2[1] = 2; arr2[2] = 3;
    
    return 0;
}
A
Initializer lists can only be used during declaration/initialization, not in assignment statements after declaration
B
Both initialization and assignment use identical syntax
C
Assignment can use initializer lists but initialization cannot
D
Arrays cannot be assigned values after declaration
16

Question 16

When comparing C-style strings using strcmp(), what does the return value indicate about the relationship between the strings?

cpp
#include <iostream>
#include <cstring>

int main() {
    const char* str1 = "apple";
    const char* str2 = "banana";
    
    int result = strcmp(str1, str2);
    
    if(result < 0) {
        std::cout << str1 << " comes before " << str2 << std::endl;
    } else if(result > 0) {
        std::cout << str1 << " comes after " << str2 << std::endl;
    } else {
        std::cout << "Strings are equal" << std::endl;
    }
    
    return 0;
}
A
strcmp returns negative if first string is lexicographically less, positive if greater, zero if equal - providing three-way comparison
B
strcmp returns 1 for equal strings, 0 for unequal strings
C
strcmp returns the length difference between the strings
D
strcmp only works with strings of equal length
17

Question 17

In a performance-critical loop that processes array elements, what iteration method provides the best combination of safety and performance?

A
Range-based for loops offer safety and performance equivalent to manual indexing, with better readability
B
Iterator-based loops provide the best performance for complex operations
C
Manual indexing with size() calls in the loop condition is always fastest
D
Pointer arithmetic provides the ultimate performance but sacrifices safety
18

Question 18

What happens when you copy a std::string object, and how does this differ from copying a C-style string?

cpp
#include <iostream>
#include <string>

int main() {
    std::string s1 = "Hello World";
    std::string s2 = s1;  // Deep copy - safe and independent
    
    s2[0] = 'h';  // Modifies only s2
    
    std::cout << "s1: " << s1 << std::endl;
    std::cout << "s2: " << s2 << std::endl;
    
    return 0;
}
A
std::string performs deep copying creating independent copies, while C-style string copying requires manual memory management and careful handling of null termination
B
Both std::string and C-style strings perform shallow copying by default
C
std::string cannot be copied due to its complex internal structure
D
C-style strings automatically deep copy when assigned
19

Question 19

When working with multidimensional fixed-size arrays, what syntax correctly declares and initializes a 2D array?

cpp
#include <iostream>

int main() {
    // 2D array: 3 rows, 4 columns
    int matrix[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    
    // Access elements
    std::cout << matrix[1][2] << std::endl;  // 7
    
    return 0;
}
A
int array[rows][cols] = {{row1}, {row2}, ...} with nested initializer lists for each dimension
B
int array[rows, cols] using comma syntax for multidimensional arrays
C
Multidimensional arrays cannot be initialized with initializer lists
D
int array[rows][cols] with single initializer list containing all elements
20

Question 20

In a function that needs to modify a string passed by reference while maintaining the original, what parameter type provides the most efficient and safe approach?

A
Pass by value creates a copy automatically, allowing modification of the copy while preserving the original
B
Pass by reference always modifies the original string
C
Pass by pointer requires manual memory management
D
Pass by const reference prevents any modification
21

Question 21

When implementing a function that searches for a substring within a larger string, what std::string method provides the most straightforward and safe implementation?

cpp
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, World!";
    std::string pattern = "World";
    
    size_t found = text.find(pattern);
    
    if(found != std::string::npos) {
        std::cout << "Found at position: " << found << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }
    
    return 0;
}
A
find() method returns the position of the first occurrence or npos if not found, providing safe substring searching
B
Manual character-by-character comparison is more efficient
C
C-style strstr() function provides better performance
D
Regular expressions should be used for all substring searches
22

Question 22

What is the most significant limitation of using fixed-size arrays for storing collections of unknown size at runtime?

A
Fixed-size arrays cannot be resized after declaration, requiring compile-time knowledge of maximum size and potentially wasting memory
B
Fixed-size arrays cannot store different data types
C
Fixed-size arrays have slower access times than dynamic arrays
D
Fixed-size arrays cannot be passed to functions
23

Question 23

When concatenating strings where performance is critical and the total size is known, what approach minimizes memory allocations?

cpp
#include <iostream>
#include <string>

int main() {
    std::string part1 = "Hello";
    std::string part2 = " ";
    std::string part3 = "World";
    
    // Pre-calculate total size
    size_t totalSize = part1.size() + part2.size() + part3.size();
    
    std::string result;
    result.reserve(totalSize);  // Avoid reallocations
    
    result += part1;
    result += part2;
    result += part3;
    
    std::cout << result << std::endl;
    return 0;
}
A
Reserve the total required capacity beforehand to prevent multiple reallocations during concatenation
B
Use the + operator repeatedly since the compiler optimizes it automatically
C
Concatenate in reverse order for better performance
D
Use C-style string concatenation which never reallocates
24

Question 24

In a program that processes text files with varying line lengths, what string type handles dynamic content most safely and efficiently?

A
std::string automatically manages memory growth and provides safe operations for variable-length text
B
Fixed-size character arrays provide the best performance for file processing
C
C-style strings with manual memory management
D
Custom string classes for specialized text processing
25

Question 25

What is the correct way to determine the length of a C-style string, and why is this important?

cpp
#include <iostream>
#include <cstring>

int main() {
    const char* str = "Hello\0World";  // Embedded null
    
    std::cout << "strlen: " << strlen(str) << std::endl;  // 5
    std::cout << "sizeof: " << sizeof(str) << std::endl;  // Pointer size
    
    return 0;
}
A
Use strlen() which counts characters until null terminator, not sizeof which gives pointer size - crucial for correct string length calculation
B
Use sizeof to get the actual string length including null terminator
C
Both strlen and sizeof give the same result for C-style strings
D
String length is stored in the first byte of the string
26

Question 26

When iterating through an array using indices, what common mistake can lead to out-of-bounds access and how can it be avoided?

cpp
#include <iostream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // Correct: use < size, not <= size
    for(size_t i = 0; i < 5; ++i) {
        std::cout << arr[i] << " ";
    }
    
    // Wrong: i <= 5 would access arr[5] which is out of bounds
    
    return 0;
}
A
Using <= size instead of < size in loop condition accesses beyond array bounds - always use < size for valid indices 0 to size-1
B
Using size_t for the loop variable instead of int
C
Starting the loop from index 1 instead of 0
D
Using pre-increment instead of post-increment
27

Question 27

What is the most efficient way to check if a std::string is empty, and why does this matter for performance?

cpp
#include <iostream>
#include <string>

int main() {
    std::string s = "Hello";
    
    // Efficient: O(1) check
    if(s.empty()) {
        std::cout << "Empty" << std::endl;
    }
    
    // Less efficient: O(n) check
    // if(s.size() == 0) or if(s == "")
    
    return 0;
}
A
Use empty() method which is O(1), while size() == 0 or comparison with empty string may be O(n) depending on implementation
B
All methods have the same O(1) performance
C
size() == 0 is always the most efficient
D
Comparing with empty string literal is the fastest method
28

Question 28

When working with arrays of strings, what iteration pattern provides the most readable code while maintaining type safety?

cpp
#include <iostream>
#include <string>
#include <vector>

int main() {
    std::vector<std::string> names = {"Alice", "Bob", "Charlie"};
    
    // Range-based for loop - clean and safe
    for(const std::string& name : names) {
        std::cout << name << " ";
    }
    
    return 0;
}
A
Range-based for loops with const references provide readable, safe iteration without copying strings unnecessarily
B
Traditional indexed loops are more efficient for string arrays
C
Iterator-based loops provide the best type safety
D
Pointer arithmetic is the most readable for string collections
29

Question 29

What happens when you assign one C-style string to another using simple assignment, and why is this problematic?

cpp
#include <iostream>
#include <cstring>

int main() {
    const char* str1 = "Hello";
    const char* str2;
    
    str2 = str1;  // Only copies pointer, not content!
    
    std::cout << str2 << std::endl;  // Works by accident
    
    // But if str1 goes out of scope or is modified...
    
    return 0;
}
A
Only the pointer is copied, not the string content, leading to shared memory and potential dangling pointer issues when the original string is modified or deallocated
B
The entire string content is copied to create independent strings
C
Assignment automatically allocates new memory for the copy
D
C-style strings cannot be assigned to each other
30

Question 30

In a function that needs to extract a substring from a std::string, what method provides the most flexible and safe substring extraction?

cpp
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, World!";
    
    // Extract "World" (position 7, length 5)
    std::string substring = text.substr(7, 5);
    
    std::cout << substring << std::endl;
    
    return 0;
}
A
substr(position, length) method provides safe, bounds-checked substring extraction with flexible position and length parameters
B
Manual character copying with loops is more efficient
C
C-style string functions like strncmp provide better substring extraction
D
Regular expressions are required for all substring operations
31

Question 31

When declaring a fixed-size array as a function parameter, what syntax correctly accepts any size array of that type?

cpp
#include <iostream>

// Function accepting any size int array
void printArray(int arr[], size_t size) {
    for(size_t i = 0; i < size; ++i) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}

// Template version that preserves size
// template<size_t N>
// void printArray(int (&arr)[N]) {
//     for(int num : arr) {
//         std::cout << num << " ";
//     }
// }

int main() {
    int arr1[3] = {1, 2, 3};
    int arr2[5] = {1, 2, 3, 4, 5};
    
    printArray(arr1, 3);
    printArray(arr2, 5);
    
    return 0;
}
A
Use int arr[] as parameter which decays to pointer, requiring separate size parameter, or use templates with reference syntax to preserve size
B
Declare the exact size in the parameter like int arr[10]
C
Use int arr[] with automatic size detection
D
Arrays cannot be passed as function parameters
32

Question 32

What is the most significant advantage of std::string over C-style strings for international text processing?

A
std::string handles UTF-8 encoding correctly and provides proper length calculation for multi-byte characters, while C-style functions may count bytes incorrectly
B
std::string automatically converts between different character encodings
C
C-style strings are better for international text because they use wide characters
D
Both handle international text equally well
33

Question 33

When implementing a function that reverses the contents of a fixed-size array in-place, what algorithm provides the most efficient implementation?

cpp
#include <iostream>
#include <algorithm>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // Use std::reverse for efficiency and correctness
    std::reverse(std::begin(arr), std::end(arr));
    
    for(int num : arr) {
        std::cout << num << " ";
    }
    
    return 0;
}
A
std::reverse algorithm provides optimal O(n/2) performance with correct boundary handling and no risk of off-by-one errors
B
Manual loop with swap operations is more efficient
C
Create a new array and copy elements in reverse order
D
Use recursion to reverse the array elements
34

Question 34

In a program that frequently searches for characters within strings, what std::string method provides the most efficient character finding?

cpp
#include <iostream>
#include <string>

int main() {
    std::string text = "Hello, World!";
    
    // Find first space
    size_t spacePos = text.find(' ');
    
    if(spacePos != std::string::npos) {
        std::cout << "Space found at: " << spacePos << std::endl;
    }
    
    return 0;
}
A
find(char) method provides efficient character searching with clear return semantics indicating found position or npos
B
Manual character-by-character loops are more efficient
C
C-style strchr() function provides better performance
D
Regular expressions should be used for all character searches
35

Question 35

What is the key safety advantage of using std::string::at() instead of operator[] for array-like access?

cpp
#include <iostream>
#include <string>

int main() {
    std::string s = "Hello";
    
    try {
        char c = s.at(10);  // Throws exception for out of bounds
    } catch(const std::out_of_range& e) {
        std::cout << "Out of bounds access detected" << std::endl;
    }
    
    // s[10] would cause undefined behavior
    
    return 0;
}
A
at() performs bounds checking and throws std::out_of_range exception for invalid access, while operator[] causes undefined behavior
B
operator[] is safer because it automatically resizes the string
C
Both methods have identical safety characteristics
D
at() is slower but provides the same safety as operator[]
36

Question 36

When working with arrays of objects that have expensive copy constructors, what iteration pattern minimizes unnecessary copying?

A
Range-based for loops with const references avoid copying objects while providing readable iteration syntax
B
Traditional indexed loops always copy objects
C
Iterator-based loops provide the best performance for expensive objects
D
Pointer-based iteration is required to avoid copying
37

Question 37

What is the most efficient way to clear a std::string and prepare it for new content?

cpp
#include <iostream>
#include <string>

int main() {
    std::string s = "Hello World";
    
    s.clear();  // Efficient: keeps capacity, just resets size
    
    // Now s is empty but retains allocated memory
    s = "New content";
    
    std::cout << s << std::endl;
    
    return 0;
}
A
clear() method resets size to 0 while preserving capacity, avoiding deallocation/reallocation when reusing the string
B
Assign empty string literal to deallocate memory immediately
C
Use resize(0) which has the same effect as clear()
D
Create a new string object to ensure clean memory state
38

Question 38

In a function that processes array elements and may need to exit early based on a condition, what iteration pattern provides the most control?

cpp
#include <iostream>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    
    // Traditional loop allows early exit and complex control flow
    for(size_t i = 0; i < 5; ++i) {
        if(arr[i] == 3) {
            std::cout << "Found 3 at index " << i << std::endl;
            break;  // Exit early
        }
        std::cout << arr[i] << " ";
    }
    
    return 0;
}
A
Traditional indexed loops provide full control with break, continue, and access to loop variables for complex iteration logic
B
Range-based for loops allow early exit with break
C
All iteration patterns provide equal control over loop execution
D
Only while loops allow conditional early exit
39

Question 39

What is the primary reason C-style strings cannot safely store binary data containing null bytes?

A
Null termination means any embedded null byte is treated as the string end, truncating the data and causing information loss
B
C-style strings have a maximum length limit
C
C-style strings cannot contain any special characters
D
C-style strings automatically convert null bytes to spaces
40

Question 40

When implementing a function that needs to modify individual characters in a string, what std::string method provides the safest indexed access?

cpp
#include <iostream>
#include <string>

int main() {
    std::string s = "Hello";
    
    // Safe indexed access with bounds checking
    if(s.length() > 0) {
        s[0] = 'h';  // Valid index
    }
    
    // s.at(10) would throw exception
    // s[10] would cause undefined behavior
    
    std::cout << s << std::endl;
    
    return 0;
}
A
operator[] with manual bounds checking provides direct access, while at() offers exception-based safety for invalid indices
B
at() method should be used for all string character access
C
Both methods have identical safety and performance
D
Manual pointer arithmetic provides the safest character access

QUIZZES IN C++