2026-04-22 01:46:03 +08:00
* Why can't you return a raw C-style array :cpp:arrays:elaborative-why:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508138
2026-04-22 01:46:03 +08:00
:END:
** Front
Why is returning a raw C-style array illegal in C++?
** Back
Arrays /decay to pointers/ when passed around. Returning one would return a pointer to a local variable that's destroyed when the function returns — undefined behavior. The compiler forbids it.
#+begin_src c++
int arr [ 26 ] ;
return arr ; // ❌ returns pointer to dead stack memory
#+end_src
* std::array vs int[]: key differences :cpp:arrays:comparative:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508134
2026-04-22 01:46:03 +08:00
:END:
** Front
How does ~std::array<int, 26>~ differ from ~int[26]~ ?
** Back
| Feature | ~int[26]~ | ~std::array<int,26>~ |
2026-04-22 23:23:33 +08:00
|----------------------+---------+--------------------|
| Return by value | No | Yes |
| Copy/assign | No | Yes |
| Knows its own size | No | ~.size()~ |
| Works with STL algos | No | Yes |
| Zero-init with ~{}~ | No | Yes |
2026-04-22 01:46:03 +08:00
Same machine code — zero overhead.
* Task: return character frequency count from string :cpp:arrays:production:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508129
2026-04-22 01:46:03 +08:00
:END:
** Front
Write a function that counts character frequencies in a string and returns the result. The string has only lowercase letters.
** Back
#+begin_src c++
std : : array < int , 26 > calc ( const std : : string & str ) {
std : : array < int , 26 > arr { } ;
for ( char c : str ) {
arr [ c - ' a ' ] + + ;
}
return arr ;
}
#+end_src
* Stack vs heap: std::array vs std::vector :cpp:arrays:comparative:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508124
2026-04-22 01:46:03 +08:00
:END:
** Front
Where is the data stored for ~std::array<int,26>~ vs ~std::vector<int>(26)~ ?
** Back
- ~std::array~ → *stack* . Data stored inline inside the struct, no dynamic allocation.
- ~std::vector~ → *heap* . Internally calls ~new[]~ , pointer indirection.
Rule: use ~std::array~ when size is known at compile time (fast, no alloc). Use ~std::vector~ when size is dynamic.
* Why const in const T& parameter :cpp:references:elaborative-why:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508119
2026-04-22 01:46:03 +08:00
:END:
** Front
Why write ~const std::string&~ instead of ~std::string&~ for a read-only parameter?
** Back
Two reasons:
1. *Enforces intent* — compiler catches accidental mutation inside the function.
2. *Allows more callers* — without ~const~ , you can't pass temporaries or const variables:
#+begin_src c++
calc ( " hello " ) ; // ❌ without const
const std : : string s = " hi " ;
calc ( s ) ; // ❌ without const
#+end_src
* Why & instead of pass-by-value for string param :cpp:references:elaborative-why:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508114
2026-04-22 01:46:03 +08:00
:END:
** Front
Why pass ~std::string~ by reference (~const std::string&~ ) instead of by value?
** Back
~std::string~ contains a heap allocation. Passing by value copies it — allocating memory and copying every character.
#+begin_src c++
calc ( std : : string str ) // copies entire string — heap allocation
calc ( const std : : string & str ) // passes address only — no copy
#+end_src
For a function that only reads, the copy is pure waste.
* Reference vs pointer for function parameters :cpp:references:comparative:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508109
2026-04-22 01:46:03 +08:00
:END:
** Front
When do you use ~T&~ vs ~T*~ for a function parameter?
** Back
2026-04-22 23:23:33 +08:00
| Feature | Reference ~T&~ | Pointer ~T*~ |
|-------------------+--------------+------------|
| Can be null | No | Yes |
| Dereference | ~str[i]~ | ~(*str)[i]~ |
| Can be reassigned | No | Yes |
2026-04-22 01:46:03 +08:00
Use ~T*~ when null is a valid input. Use ~T&~ when the value is *guaranteed to exist* — which is almost always the case for function parameters.
* Rule of thumb: C++ function parameter types :cpp:references:factual:
:PROPERTIES:
:ANKI_NOTE_TYPE: Basic
2026-04-22 23:23:33 +08:00
:ANKI_NOTE_ID: 1776793508102
2026-04-22 01:46:03 +08:00
:END:
** Front
What's the general rule for choosing parameter types in C++ functions?
** Back
- *Non-trivial types* (~string~ , ~vector~ , structs): use ~const T&~ for read-only, ~T&~ for mutating
- *Cheap types* (~int~ , ~char~ , ~bool~ , pointers): pass by value
- *Nullable input* : use ~T*~
- *Guaranteed non-null* : use ~T&~