SlideShare a Scribd company logo
Mul$dimensional arrays
Ilio Catallo - info@iliocatallo.it
Outline
• Arrays of arrays
• Arrays of arrays vs. pointers
• Pointer arithme4c
• Arrays of arrays vs. func4ons
• The array of arrays type
• Bibliography
Arrays of arrays
How to define an array
Arrays are defined by specifying:
• The type common to each element
• The name of the array
• Its size
How to define an array
int numbers[4];
• Element type: int
• Name: numbers
• Size: 4
Array representa+on
0 ... 3
┌───┬───┬───┬───┐
numbers: │ │ │ │ │ int[4]
└───┴───┴───┴───┘
Type aliases
C++ supports type aliases, i.e., new names for previously defined
types1
using integer = int;
integer a = 5; // the same as: int a = 5
1
Star'ng from C++11, type aliases can be introduced by means of the using keyword (in addi'on to the already
available typedef keyword)
Type aliases for array types
We can introduce type aliases for array types as well.
For instance, let us introduce a type alias for the type int[4]
using int4 = int[4];
Type aliases for array types
We can now define numbers in terms of the type alias int4
using int4 = int[4];
int4 numbers = {1, 7, 13, 10};
Can we now take advantage of our newly-defined alias to define an
array of, e.g., 3 elements of type int4?
Array of int4's
int4 m[3];
• Element type: ?
• Name: ?
• Size: ?
Array of int4's
int4 m[3];
• Element type: int4
• Name: m
• Size: 3
Arrays of arrays
Since each element of m is in turn an array, we have effec6vely
defined an array of arrays
int4 m[3];
Arrays of arrays
Specifically, m is an array of 3 elements, where each element is in
turn an array of 4 elements
int4 m[3];
Array arrays representa+on
0 1 2
┌─────────────────────┬─────────────────────┬─────────────────────┐
│ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │
m: │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ int4[3]
│ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │
└─────────────────────┴─────────────────────┴─────────────────────┘
Ini$alizing an array
We know that arrays can be ini1alized using an ini#alizer list
int numbers[4] = {1, 7, 13, 10};
Ini$alizing an array
In case of numbers, the ini.alizer list is composed of int values
// 1 is a int, 7 is a int, ...
int numbers[4] = {1, 7, 13, 10};
Ini$alizing an array of arrays
In case of m, the ini.alizer list is composed of int4 values
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2}, // {1, 7, 14, 2} is an int4
{8, 16, 12, 10}, // {8, 16, 12, 10} is an int4
{27, 32, 5, 15} }; // {27, 32, 5, 15} is an int4
Accessing inner elements
It would be convenient to be able to access inner elements in m
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
Accessing inner elements
For example, being able to access the element in (2, 1)
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
Accessing inner elements
In order to do so, it is sufficient to specify the right amount of
indices (as many as the number of dimensions)
m[2][1]
Accessing inner elements
In order to do so, it is sufficient to specify the right amount of
indices (as many as the number of dimensions)
m[2][1] → {27, 32, 5, 15}[1]
Accessing inner elements
In order to do so, it is sufficient to specify the right amount of
indices (as many as the number of dimensions)
m[2][1] → {27, 32, 5, 15}[1] → 32
Accessing inner elements
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
std::cout << m[2][1]; // output: 32
Mul$dimensional arrays
Note that m can therefore act as a mul$dimensional array, and,
specifically, it can be treated as a matrix
Mul$dimensional arrays
Mul$dimensional arrays extend the concept of array to one or
more dimensions
Mul$dimensional arrays
For common arrays, elements are addressed by specifying one
index
┌───┬───┬───┬───┐
│ │ │ │ │
└───┴───┴───┴───┘
▲
│
i
Mul$dimensional arrays
For mul(dimensional arrays, each element is iden(fied by a tuple of
indexes (as many as the number of dimensions)
┌───┬───┬───┬───┐
│ │ │ │ │
├───┼───┼───┼───┤
│ │ │ │ │
├───┼───┼───┼───┤
│ │ │ │ │◀─── i
└───┴───┴───┴───┘
▲
│
j
Arrays of arrays
C++ does not provide proper mul1dimensional arrays. Instead,
mul1dimensional arrays are approximated as arrays of arrays
Memory layout
Since mul*dim. arrays are approximated as arrays of arrays, it
follows that elements are organized in memory as a sequence
m[0] m[1] m[2]
◀──────────────▶◀────────────▶◀─────────────▶
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
m: │ │ │ │ │ │ │ │ │ │ │ │ │ int4[3]
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
Arrays of arrays vs. pointers
Pointer to first element
Assume we want to store the address of the first element of m
// {1, 7, 14, 2} is the 1st element
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
Pointer to first element
We start by no,cing that the element type of m is int4
int4 m[3] = { {1, 7, 14, 2}, // {1, 7, 14, 2} is an int4
{8, 16, 12, 10}, // {8, 16, 12, 10} is an int4
{27, 32, 5, 15} }; // {27, 32, 5, 15} is an int4
Pointer to first element
Since the element type is equal to int4, a pointer2
to any element
in the array has to be of type int4*
using int4 = int[4];
int4* first = ...
2
The int4 type alias provides a convenient way to introduce pointers to arrays. Without the intermediate type alias,
one would define first to be of type int(*)[4], which is arguably less readable
What to write on the RHS?
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
int4* first = ???
What to write on the RHS?
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
int4* first = &m[0]; // the address of {1, 7, 14, 2}
Pointer decay
As with any array, pointer decay can be used
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
// array-to-pointer decay (int4[3] → int4*)
int4* first = m;
Pointer decay
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
0 1 2
│┌─────────────────────┬┼────────────────────┬─────────────────────┐
│ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │
m: ││ │ │ │ │ │ ││ │ │ │ │ │ │ │ │ │ │ │ │ int4[3]
│ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │
│└─────────────────────┴┼────────────────────┴─────────────────────┘
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
▲
│
│
│
│
┌───┐
first:│ │ int4*
└───┘
Pointer arithme,c
Pointer arithme,c
Given that arrays of arrays are only a par1cular case of arrays,
pointer arithme,c can be applied on them without any special
considera1on
Pointer arithme,c: addi,on
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
int4* first = m; // ptr to {1, 7, 14, 2}
int4* second = m + 1; // ptr to {8, 16, 12, 10}
int4* third = m + 2; // ptr to {27, 32, 5, 15}
Pointer arithme,c
No#ce that pointer arithme#c allows moving between the rows of
our 2-dimensional array m
int4* first = m; // ptr to {1, 7, 14, 2}
int4* second = m + 1; // ptr to {8, 16, 12, 10}
int4* third = m + 2; // ptr to {27, 32, 5, 15}
Deriving the indexing operator
Let us now try to reduce inner element access to a sequence of
pointer arithme,c opera,ons
Deriving the indexing operator
To this end, let us consider the following expression:
m[2][1]
Deriving the indexing operator
By replacing [1] with its defini3on we obtain:
m[2][1] → *(m[2] + 1)
Deriving the indexing operator
If we do the same for [2] we obtain:
m[2][1] → *(m[2] + 1) → *(*(m + 2) + 1)
Indexing operator on arrays of arrays
Accessing inner elements of a array of arrays is therefore s2ll
defined in terms of pointer arithme,c
Given an array of arrays m, and a pair of indexes i and j, the
opera3on a[i][j] is implemented as *(*(m + i) + j)
Arrays of arrays vs. func.ons
The sum_int func)on
Assume we would like to write a func3on named sum_int, which
computes the summa3on of all the elements in a 2-dimensional
array
What we know
• We can model 2-dimensional arrays as arrays of arrays
• Arrays of arrays follow the same rules as normal arrays
• We cannot pass arrays by value
• The common workaround is to design func>ons that accept a
pointer to the 1st
element, together with the array size
An interface for sum_int
As a first step, let us write sum_int so that it works properly when
m is fed as an input
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
An interface for sum_int
int sum_int(??? first, ??? n);
An interface for sum_int
int sum_int(int4* first, std::size_t n);
An interface for sum_int
Since we want sum_int to work with m, we impose first to be of
type int4
int sum_int(int4* first, std::size_t n);
An interface for sum_int
Hence, sum_int can only work with 2-dimensional arrays of
exactly 4 columns
int sum_int(int4* first, std::size_t n);
An interface for sum_int
int sum_int(int4* first, std::size_t n);
• The number of rows is determined by the parameter n
• The number of columns is fixed by the type of first (int4)
An interface for sum_int
If we need to work with 2-dimensional arrays of, e.g., 5 columns,
we need to write a new func(on4
int sum_int(int4* first, std::size_t n);
int sum_int5(int5* first, std::size_t n);
4
This can be automated by using a func%on template
sum_int → sum_int4
In light of this, let us rename sum_int as sum_int4
int sum_int4(int4* first, std::size_t n);
Implemen'ng sum_int4
int sum_int4(int4* first, std::size_t n) {
int sum = 0;
for (std::size_t i = 0; i < n; ++i)
for (std::size_t j = 0; j < 4; ++j)
sum += ???
return sum;
}
Implemen'ng sum_int4
int sum_int4(int4* first, std::size_t n) {
int sum = 0;
for (std::size_t i = 0; i < n; ++i)
for (std::size_t j = 0; j < 4; ++j)
sum += *(*(first + i) + j);
return sum;
}
Implemen'ng sum_int4
int sum_int4(int4* first, std::size_t n) {
int sum = 0;
for (std::size_t i = 0; i < n; ++i)
for (std::size_t j = 0; j < 4; ++j)
sum += first[i][j];
return sum;
}
Invoking sum_int4
int main() {
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
int r = sum_int4(???, ???);
std::cout << "the elements sum up to " << r;
}
Invoking sum_int4
int main() {
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
int r = sum_int4(m, 3);
std::cout << "the elements sum up to " << r;
}
The array of arrays type
The int4 type alias
Up to now, we took advantage of the int4 type alias for the
defini7on of m
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
The int4 type alias
We did so in order to stress the true nature of mul1dimensional
arrays in C++
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
The data type of m
A"er introducing int4, we can say that m is of type int4[3]
(i.e., an array of 3 elements of type int4)
using int4 = int[4];
int4 m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
The data type of m
However, one could wonder how to express the data type of m
without introducing the int4 type alias
??? m[3] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
The data type of m
This amounts to asking what is the result of applying the [3] type
constructor on int[4]
Applying [3] on int
Construct a type "array of 3 elements of type int"
Input type int
Type constructor: [3]
Output type: int[3]
Applying [3] on int[4]
Construct a type "array of 3 elements of type int[4]"
Input type: int[4]
Type constructor: [3]
Output type: int[3][4]
The data type of m
Therefore, we conclude that m is of type int[3][4]
int m[3][4] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
Arrays of arrays
The common C++ syntax for defining arrays of arrays gives the
illusion of working with mul;dimensional arrays
int m[3][4] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
Arrays of arrays
However - though the syntax would suggest otherwise - the
element type of m is s8ll int[4], not int
int m[3][4] = { {1, 7, 14, 2},
{8, 16, 12, 10},
{27, 32, 5, 15} };
The alterna*ve signature
As with normal arrays, C++ admits func6on signatures that may
appear more natural when dealing with mul6dimensional arrays
The alterna*ve signature
Namely, we can change the signature of sum_int4 from this...
int sum_int4(int4* first, std::size_t n);
The alterna*ve signature
...to this:
int sum_int4(int m[][4], std::size_t n);
The alterna*ve signature
int sum_int4(int m[][4], std::size_t n) {
int sum = 0;
for (std::size_t i = 0; i < n; ++i)
for (std::size_t j = 0; j < 4; ++j)
sum += m[i][j];
return sum;
}
Bibliography
Bibliography
• S.B. Lippman et al., C++ Primer (5th
Ed.)
• B. Stroustrup, The C++ Programming Language (4th
Ed.)
• StackOverflow FAQ, "How do I use arrays in C++?"

More Related Content

PPTX
Data Structures in Python
PPTX
Strings in C language
PPTX
Array in c programming
PPTX
Two dimensional arrays
PPTX
Loops in Python
PPTX
Python- Regular expression
PPTX
6-Python-Recursion PPT.pptx
PDF
Python strings
Data Structures in Python
Strings in C language
Array in c programming
Two dimensional arrays
Loops in Python
Python- Regular expression
6-Python-Recursion PPT.pptx
Python strings

What's hot (20)

PPTX
Array Introduction One-dimensional array Multidimensional array
PPTX
Programming in c Arrays
PDF
PPTX
Python Functions
PPTX
Tuple in python
PPTX
Functions in c language
PPT
Chapter 11 - Sorting and Searching
PPT
Basics of pointer, pointer expressions, pointer to pointer and pointer in fun...
PPTX
Deletion from single way linked list and search
PDF
Python list
PPTX
PPTX
Tuple in python
PPT
Arrays in c
PPTX
Python-Encapsulation.pptx
PPTX
Vector class in C++
PPTX
Arrays In C++
PPTX
Pointers and Structures.pptx
PPTX
PPT
Introduction to Python
Array Introduction One-dimensional array Multidimensional array
Programming in c Arrays
Python Functions
Tuple in python
Functions in c language
Chapter 11 - Sorting and Searching
Basics of pointer, pointer expressions, pointer to pointer and pointer in fun...
Deletion from single way linked list and search
Python list
Tuple in python
Arrays in c
Python-Encapsulation.pptx
Vector class in C++
Arrays In C++
Pointers and Structures.pptx
Introduction to Python
Ad

Viewers also liked (13)

PPT
CBSE Class XI Programming in C++
PPTX
Cs1123 3 c++ overview
PPT
Overview of c++
PPTX
C++ Overview PPT
PPTX
Understand Decision structures in c++ (cplusplus)
PPTX
Overview of c++ language
PPT
Multidimensional array in C
PPTX
Learn c++ Programming Language
PDF
Revision notes for exam 2011 computer science with C++
PPT
Structure of C++ - R.D.Sivakumar
PPTX
c++ programming Unit 2 basic structure of a c++ program
PPS
CS101- Introduction to Computing- Lecture 26
CBSE Class XI Programming in C++
Cs1123 3 c++ overview
Overview of c++
C++ Overview PPT
Understand Decision structures in c++ (cplusplus)
Overview of c++ language
Multidimensional array in C
Learn c++ Programming Language
Revision notes for exam 2011 computer science with C++
Structure of C++ - R.D.Sivakumar
c++ programming Unit 2 basic structure of a c++ program
CS101- Introduction to Computing- Lecture 26
Ad

Similar to Multidimensional arrays in C++ (20)

PDF
Arrays in C++
PPTX
arrays.pptx
PPTX
Generative Coding Lecture notes using coding
PPT
PPT
Basics of Data structure using C describing basics concepts
PPTX
Python Datatypes by SujithKumar
PPTX
Visual Programing basic lectures 7.pptx
PPTX
Chap1 array
PPTX
Chapter 13.pptx
PPTX
Arrays
PPTX
Arrays 1D and 2D , and multi dimensional
PDF
ARRAYS
PDF
Array and Pointers
PPT
Data Structure Midterm Lesson Arrays
PDF
PPT
Multi dimensional arrays
PPT
PPT
Lecture 15 - Array
PPTX
Arrays in programming
Arrays in C++
arrays.pptx
Generative Coding Lecture notes using coding
Basics of Data structure using C describing basics concepts
Python Datatypes by SujithKumar
Visual Programing basic lectures 7.pptx
Chap1 array
Chapter 13.pptx
Arrays
Arrays 1D and 2D , and multi dimensional
ARRAYS
Array and Pointers
Data Structure Midterm Lesson Arrays
Multi dimensional arrays
Lecture 15 - Array
Arrays in programming

More from Ilio Catallo (20)

PDF
C++ Standard Template Library
PDF
Regular types in C++
PDF
Resource wrappers in C++
PDF
Memory management in C++
PDF
Operator overloading in C++
PDF
Pointers & References in C++
PDF
Spring MVC - Wiring the different layers
PDF
Java and Java platforms
PDF
Spring MVC - Web Forms
PDF
Spring MVC - The Basics
PDF
Web application architecture
PDF
Introduction To Spring
PDF
Gestione della memoria in C++
PDF
Array in C++
PDF
Puntatori e Riferimenti
PDF
Java Persistence API
PDF
JSP Standard Tag Library
PDF
Internationalization in Jakarta Struts 1.3
PDF
Validation in Jakarta Struts 1.3
PDF
Introduction to Struts 1.3
C++ Standard Template Library
Regular types in C++
Resource wrappers in C++
Memory management in C++
Operator overloading in C++
Pointers & References in C++
Spring MVC - Wiring the different layers
Java and Java platforms
Spring MVC - Web Forms
Spring MVC - The Basics
Web application architecture
Introduction To Spring
Gestione della memoria in C++
Array in C++
Puntatori e Riferimenti
Java Persistence API
JSP Standard Tag Library
Internationalization in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3
Introduction to Struts 1.3

Recently uploaded (20)

PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Cloud computing and distributed systems.
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPT
Teaching material agriculture food technology
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Electronic commerce courselecture one. Pdf
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Spectroscopy.pptx food analysis technology
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
KodekX | Application Modernization Development
Encapsulation_ Review paper, used for researhc scholars
Dropbox Q2 2025 Financial Results & Investor Presentation
Chapter 3 Spatial Domain Image Processing.pdf
Machine learning based COVID-19 study performance prediction
Cloud computing and distributed systems.
NewMind AI Weekly Chronicles - August'25 Week I
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Teaching material agriculture food technology
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Mobile App Security Testing_ A Comprehensive Guide.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Network Security Unit 5.pdf for BCA BBA.
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Building Integrated photovoltaic BIPV_UPV.pdf
Electronic commerce courselecture one. Pdf
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Per capita expenditure prediction using model stacking based on satellite ima...
Spectroscopy.pptx food analysis technology
Review of recent advances in non-invasive hemoglobin estimation
KodekX | Application Modernization Development

Multidimensional arrays in C++

  • 1. Mul$dimensional arrays Ilio Catallo - info@iliocatallo.it
  • 2. Outline • Arrays of arrays • Arrays of arrays vs. pointers • Pointer arithme4c • Arrays of arrays vs. func4ons • The array of arrays type • Bibliography
  • 4. How to define an array Arrays are defined by specifying: • The type common to each element • The name of the array • Its size
  • 5. How to define an array int numbers[4]; • Element type: int • Name: numbers • Size: 4
  • 6. Array representa+on 0 ... 3 ┌───┬───┬───┬───┐ numbers: │ │ │ │ │ int[4] └───┴───┴───┴───┘
  • 7. Type aliases C++ supports type aliases, i.e., new names for previously defined types1 using integer = int; integer a = 5; // the same as: int a = 5 1 Star'ng from C++11, type aliases can be introduced by means of the using keyword (in addi'on to the already available typedef keyword)
  • 8. Type aliases for array types We can introduce type aliases for array types as well. For instance, let us introduce a type alias for the type int[4] using int4 = int[4];
  • 9. Type aliases for array types We can now define numbers in terms of the type alias int4 using int4 = int[4]; int4 numbers = {1, 7, 13, 10};
  • 10. Can we now take advantage of our newly-defined alias to define an array of, e.g., 3 elements of type int4?
  • 11. Array of int4's int4 m[3]; • Element type: ? • Name: ? • Size: ?
  • 12. Array of int4's int4 m[3]; • Element type: int4 • Name: m • Size: 3
  • 13. Arrays of arrays Since each element of m is in turn an array, we have effec6vely defined an array of arrays int4 m[3];
  • 14. Arrays of arrays Specifically, m is an array of 3 elements, where each element is in turn an array of 4 elements int4 m[3];
  • 15. Array arrays representa+on 0 1 2 ┌─────────────────────┬─────────────────────┬─────────────────────┐ │ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │ m: │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ int4[3] │ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │ └─────────────────────┴─────────────────────┴─────────────────────┘
  • 16. Ini$alizing an array We know that arrays can be ini1alized using an ini#alizer list int numbers[4] = {1, 7, 13, 10};
  • 17. Ini$alizing an array In case of numbers, the ini.alizer list is composed of int values // 1 is a int, 7 is a int, ... int numbers[4] = {1, 7, 13, 10};
  • 18. Ini$alizing an array of arrays In case of m, the ini.alizer list is composed of int4 values using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, // {1, 7, 14, 2} is an int4 {8, 16, 12, 10}, // {8, 16, 12, 10} is an int4 {27, 32, 5, 15} }; // {27, 32, 5, 15} is an int4
  • 19. Accessing inner elements It would be convenient to be able to access inner elements in m using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 20. Accessing inner elements For example, being able to access the element in (2, 1) using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 21. Accessing inner elements In order to do so, it is sufficient to specify the right amount of indices (as many as the number of dimensions) m[2][1]
  • 22. Accessing inner elements In order to do so, it is sufficient to specify the right amount of indices (as many as the number of dimensions) m[2][1] → {27, 32, 5, 15}[1]
  • 23. Accessing inner elements In order to do so, it is sufficient to specify the right amount of indices (as many as the number of dimensions) m[2][1] → {27, 32, 5, 15}[1] → 32
  • 24. Accessing inner elements using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; std::cout << m[2][1]; // output: 32
  • 25. Mul$dimensional arrays Note that m can therefore act as a mul$dimensional array, and, specifically, it can be treated as a matrix
  • 26. Mul$dimensional arrays Mul$dimensional arrays extend the concept of array to one or more dimensions
  • 27. Mul$dimensional arrays For common arrays, elements are addressed by specifying one index ┌───┬───┬───┬───┐ │ │ │ │ │ └───┴───┴───┴───┘ ▲ │ i
  • 28. Mul$dimensional arrays For mul(dimensional arrays, each element is iden(fied by a tuple of indexes (as many as the number of dimensions) ┌───┬───┬───┬───┐ │ │ │ │ │ ├───┼───┼───┼───┤ │ │ │ │ │ ├───┼───┼───┼───┤ │ │ │ │ │◀─── i └───┴───┴───┴───┘ ▲ │ j
  • 29. Arrays of arrays C++ does not provide proper mul1dimensional arrays. Instead, mul1dimensional arrays are approximated as arrays of arrays
  • 30. Memory layout Since mul*dim. arrays are approximated as arrays of arrays, it follows that elements are organized in memory as a sequence m[0] m[1] m[2] ◀──────────────▶◀────────────▶◀─────────────▶ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ m: │ │ │ │ │ │ │ │ │ │ │ │ │ int4[3] └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
  • 31. Arrays of arrays vs. pointers
  • 32. Pointer to first element Assume we want to store the address of the first element of m // {1, 7, 14, 2} is the 1st element int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 33. Pointer to first element We start by no,cing that the element type of m is int4 int4 m[3] = { {1, 7, 14, 2}, // {1, 7, 14, 2} is an int4 {8, 16, 12, 10}, // {8, 16, 12, 10} is an int4 {27, 32, 5, 15} }; // {27, 32, 5, 15} is an int4
  • 34. Pointer to first element Since the element type is equal to int4, a pointer2 to any element in the array has to be of type int4* using int4 = int[4]; int4* first = ... 2 The int4 type alias provides a convenient way to introduce pointers to arrays. Without the intermediate type alias, one would define first to be of type int(*)[4], which is arguably less readable
  • 35. What to write on the RHS? using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; int4* first = ???
  • 36. What to write on the RHS? using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; int4* first = &m[0]; // the address of {1, 7, 14, 2}
  • 37. Pointer decay As with any array, pointer decay can be used using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; // array-to-pointer decay (int4[3] → int4*) int4* first = m;
  • 38. Pointer decay ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ 0 1 2 │┌─────────────────────┬┼────────────────────┬─────────────────────┐ │ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │ ┌───┬───┬───┬───┐ │ m: ││ │ │ │ │ │ ││ │ │ │ │ │ │ │ │ │ │ │ │ int4[3] │ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │ └───┴───┴───┴───┘ │ │└─────────────────────┴┼────────────────────┴─────────────────────┘ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▲ │ │ │ │ ┌───┐ first:│ │ int4* └───┘
  • 40. Pointer arithme,c Given that arrays of arrays are only a par1cular case of arrays, pointer arithme,c can be applied on them without any special considera1on
  • 41. Pointer arithme,c: addi,on using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; int4* first = m; // ptr to {1, 7, 14, 2} int4* second = m + 1; // ptr to {8, 16, 12, 10} int4* third = m + 2; // ptr to {27, 32, 5, 15}
  • 42. Pointer arithme,c No#ce that pointer arithme#c allows moving between the rows of our 2-dimensional array m int4* first = m; // ptr to {1, 7, 14, 2} int4* second = m + 1; // ptr to {8, 16, 12, 10} int4* third = m + 2; // ptr to {27, 32, 5, 15}
  • 43. Deriving the indexing operator Let us now try to reduce inner element access to a sequence of pointer arithme,c opera,ons
  • 44. Deriving the indexing operator To this end, let us consider the following expression: m[2][1]
  • 45. Deriving the indexing operator By replacing [1] with its defini3on we obtain: m[2][1] → *(m[2] + 1)
  • 46. Deriving the indexing operator If we do the same for [2] we obtain: m[2][1] → *(m[2] + 1) → *(*(m + 2) + 1)
  • 47. Indexing operator on arrays of arrays Accessing inner elements of a array of arrays is therefore s2ll defined in terms of pointer arithme,c Given an array of arrays m, and a pair of indexes i and j, the opera3on a[i][j] is implemented as *(*(m + i) + j)
  • 48. Arrays of arrays vs. func.ons
  • 49. The sum_int func)on Assume we would like to write a func3on named sum_int, which computes the summa3on of all the elements in a 2-dimensional array
  • 50. What we know • We can model 2-dimensional arrays as arrays of arrays • Arrays of arrays follow the same rules as normal arrays • We cannot pass arrays by value • The common workaround is to design func>ons that accept a pointer to the 1st element, together with the array size
  • 51. An interface for sum_int As a first step, let us write sum_int so that it works properly when m is fed as an input using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 52. An interface for sum_int int sum_int(??? first, ??? n);
  • 53. An interface for sum_int int sum_int(int4* first, std::size_t n);
  • 54. An interface for sum_int Since we want sum_int to work with m, we impose first to be of type int4 int sum_int(int4* first, std::size_t n);
  • 55. An interface for sum_int Hence, sum_int can only work with 2-dimensional arrays of exactly 4 columns int sum_int(int4* first, std::size_t n);
  • 56. An interface for sum_int int sum_int(int4* first, std::size_t n); • The number of rows is determined by the parameter n • The number of columns is fixed by the type of first (int4)
  • 57. An interface for sum_int If we need to work with 2-dimensional arrays of, e.g., 5 columns, we need to write a new func(on4 int sum_int(int4* first, std::size_t n); int sum_int5(int5* first, std::size_t n); 4 This can be automated by using a func%on template
  • 58. sum_int → sum_int4 In light of this, let us rename sum_int as sum_int4 int sum_int4(int4* first, std::size_t n);
  • 59. Implemen'ng sum_int4 int sum_int4(int4* first, std::size_t n) { int sum = 0; for (std::size_t i = 0; i < n; ++i) for (std::size_t j = 0; j < 4; ++j) sum += ??? return sum; }
  • 60. Implemen'ng sum_int4 int sum_int4(int4* first, std::size_t n) { int sum = 0; for (std::size_t i = 0; i < n; ++i) for (std::size_t j = 0; j < 4; ++j) sum += *(*(first + i) + j); return sum; }
  • 61. Implemen'ng sum_int4 int sum_int4(int4* first, std::size_t n) { int sum = 0; for (std::size_t i = 0; i < n; ++i) for (std::size_t j = 0; j < 4; ++j) sum += first[i][j]; return sum; }
  • 62. Invoking sum_int4 int main() { using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; int r = sum_int4(???, ???); std::cout << "the elements sum up to " << r; }
  • 63. Invoking sum_int4 int main() { using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} }; int r = sum_int4(m, 3); std::cout << "the elements sum up to " << r; }
  • 64. The array of arrays type
  • 65. The int4 type alias Up to now, we took advantage of the int4 type alias for the defini7on of m using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 66. The int4 type alias We did so in order to stress the true nature of mul1dimensional arrays in C++ using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 67. The data type of m A"er introducing int4, we can say that m is of type int4[3] (i.e., an array of 3 elements of type int4) using int4 = int[4]; int4 m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 68. The data type of m However, one could wonder how to express the data type of m without introducing the int4 type alias ??? m[3] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 69. The data type of m This amounts to asking what is the result of applying the [3] type constructor on int[4]
  • 70. Applying [3] on int Construct a type "array of 3 elements of type int" Input type int Type constructor: [3] Output type: int[3]
  • 71. Applying [3] on int[4] Construct a type "array of 3 elements of type int[4]" Input type: int[4] Type constructor: [3] Output type: int[3][4]
  • 72. The data type of m Therefore, we conclude that m is of type int[3][4] int m[3][4] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 73. Arrays of arrays The common C++ syntax for defining arrays of arrays gives the illusion of working with mul;dimensional arrays int m[3][4] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 74. Arrays of arrays However - though the syntax would suggest otherwise - the element type of m is s8ll int[4], not int int m[3][4] = { {1, 7, 14, 2}, {8, 16, 12, 10}, {27, 32, 5, 15} };
  • 75. The alterna*ve signature As with normal arrays, C++ admits func6on signatures that may appear more natural when dealing with mul6dimensional arrays
  • 76. The alterna*ve signature Namely, we can change the signature of sum_int4 from this... int sum_int4(int4* first, std::size_t n);
  • 77. The alterna*ve signature ...to this: int sum_int4(int m[][4], std::size_t n);
  • 78. The alterna*ve signature int sum_int4(int m[][4], std::size_t n) { int sum = 0; for (std::size_t i = 0; i < n; ++i) for (std::size_t j = 0; j < 4; ++j) sum += m[i][j]; return sum; }
  • 80. Bibliography • S.B. Lippman et al., C++ Primer (5th Ed.) • B. Stroustrup, The C++ Programming Language (4th Ed.) • StackOverflow FAQ, "How do I use arrays in C++?"