Hello,
I have some questions about multidimensional arrays in the Rust-Lang, and please answer my questions briefly.
A two Dimensional Array in C++ is as follow:
Arrays don't have an intrinsic orientation, they are just bits in memory. What you consider rows and columns is merely a convention.
For exactly the same reason as variables of every other type must be.
I mean, because the language is defined like so? You should read the relevant documentation for language features instead of trying to guess how they are defined.
I don't understand that. What do you mean by initializing only rows or columns? If you initialize all rows (or equivalently, all columns) of the array, then you initialized all of it to all 0s.
This smells like homework? But anyway, you don't want j to run from 0 to i, because that only prints a triangular half of the array, above/below the diagonal. If you want to print all 16 elements, then you need both indices to run from 0 to 4.
N and M are the dimensions of the array, which is indexed like x[m][n]. Whether you consider the inner dimension N to be the width or height is a matter of perspective, and Rust doesn't really care which one you use.
In safe Rust, you (mostly) can't have partially initialized types, and this includes arrays. If you want to have some initialized and some uninitialized elements, you'll have to use something like MaybeUninit.
Rust only has language support for one-dimensional arrays, so a two-dimensional array is really just an array of arrays. An array literal looks like [value;count]¹, where value is an expression that evaluates to the element type. When that element type is also an array, this syntax turns into the [[value;inner_count];outer_count] syntax that you use later.
@H2CO3 has already identified the core problem with the code you've written, but you might want to consider a less error-prone approach than looping over the array indices:
for (_j, inner) in x.iter().enumerate() {
for (_i, element) in inner.iter().enumerate() {
println("{element}");
}
}
Hello,
Thank you so much for your reply.
No, this is not homework. I have started to learn Rust-Lang, and these are the questions that have arisen for me.
Hello,
Thank you so much for your reply.
Why x=[[0;4];[0;4]] is wrong? It could initialize all rows and columns to zero.
About the number 4, in C++ you can use the following code to initialize all items of an array to zero:
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COLUMN; j++)
array[i][j] = 0;
And:
fn main() {
let mut x=[[0;4];4];
for i in 0..3 {
for j in 0..i {
println!("{}",x[i][j]);
}
}
}
It will:
i=0
x[0][0]
i=1
x[0][0]
x[0][1]
And so on. Am I right?
Please consider let mut x = [[[0; 4]; 8]; 15];, why the last item is x[14][7][3] not x[3][7][14] ?
let initializer = [[0; 4]; 8];
let mut x = [initializer; 15];
So x is an array of length 15. The last element of x is therefore x[14]. x[14] is itself an array whose last element is (x[14])[7] = x[14][7]. That again is an array whose last element is x[14][7][3].
Hello,
Thank you so much for your reply.
I have a little C++ background and the Rust-Lang is new for me. When I write let initializer = [[0; 4]; 8];, then it creates an array with 4 rows and 8 columns and initialized all of its items with zero. Am I right?
So this creates an array of 8 elements, each of which is an array of 4 elements, each of which is the number 0.
Whether you visualize the arrays horizontally or vertically is up to your imagination, they don't have an inherent direction in space, they are just sequences of elements. You can think of it as a row of rows, a column of columns, a row of columns, or a column of rows. It's up to you.
Instead of thinking of it as a multidimensional array, think of it as an array of arrays. That way when seeing [0;N] you know it's an array of length N and when seeing [[0;N];M] you know it's an array of length M containing arrays of length N.
All data in rust must be initialized, unless it's a MaybeUninit type.
Suppose you have a statement let foo = bar[i]. You know that foo will be an element of bar. Now suppose you have another statement following the previous one: let foobar = foo[j]. That would mean foobar is an element of foo. So in a statement let foobar = bar[i][j] you can conclude that foobar is the j'th element of the i'th array.
What nobody has mentioned here is "row major order" or "column major order".
An N * M two dimensional array is a contiguous sequence of N * M elements in memory.
But is that N lots of M or M lots of N?
It's important to know when one is traversing the array, should we iterate over columns inside rows or rows inside columns? Important because Conway around is cache friendly and fast, the other way around causes lots of cache misses and is slow.