In book i found example
static int categoryTable[ 2 ][ 2 ][ 2 ] = {
//!b!c !bc b!c bc
0, 3, 2, 2, //!a
1, 2, 1, 1 // a
};
category = categoryTable[ a ][ b ][ c ]
There is mistake, right?
Right variant is
static int categoryTable[ 2 ][ 2 ][ 2 ] = {
//!b!c !bc b!c bc
{{0, 3}, {2, 2}}, //!a
{{1, 2}, {1, 1}} // a
};
Or original is right and I don't understand something?
As Beefster said both ways are correct and will compile.
Multidimensional arrays are just plain single-dimension arrays for the compiler but for programmers they are a nice sugar syntax for complex pointer arithmetics.
Because the multidimensional array is in the reality a single dimension array with syntax improvements then there's no point to disallow initialization with single initializer list.
Expression
a[0][2][3] = x;
is equivalent of *(a+(0*DIM_1+2)*DIM_2+3) = x;
What's not a part of your question but also interesting that because it's just pointer arithmetics you could write:
3[a]
That is equivalent of array subscription:
a[3]
So as a fun fact - you can do similar stuff with multidimensional arrays:
#include <stdio.h>
static int categoryTable[ 2 ][ 2 ][ 2 ] = {
//!b!c !bc b!c bc
0, 3, 2, 2, //!a
1, 2, 1, 1 // a
};
int main() {
// This two printf's are equivalent
printf("%d\n", 0[0[categoryTable][1]]);
printf("%d\n", categoryTable[0][1][0]);
return 0;
}
This is rather an ugly never-do-it thing, but funny anyway.
So you can think about subscription as some kind of mathematical expression to access single plain array - nothing special really.
Both are correct. You can use any one of them.
Related
I am initializing an array in two different ways depending a macro:
# if feature_enabled
const int v[4] = {1, 2, 3, 4};
#else
const int v[5] = {0, 1, 2, 3, 4};
#endif
The problem is that the data in the assignment is actually large matrices, and for various reasons it's not a good solution to just copy the data with a minor modification (just one more element at the beginning of the array.)
I was wondering if there is a way to do the same thing that I did here, without essentially duplicating the last n-1 elements.
If you don't specify the size on the array but let it be auto-deduced, you can just add the 0 in the front conditionally:
const int v[] = {
# if feature_enabled
0,
#endif
1, 2, 3, 4
};
If you need to keep the array size, then:
# if feature_enabled
const int v[4] = {
#else
const int v[5] = {0,
#endif
1, 2, 3, 4
};
I've got a C-style array called board that contains some char's. I'm trying to create a std::array or std::vector (either would be fine, although std::array would be preferable) to store all the indices of board that are a certain value (in my case, 0).
This code I wrote is functional and works well:
std::vector<int> zeroes;
zeroes.reserve(16);
//board has 16 elements, so zeroes.size() will never be larger than 16.
//I used this reserve for speedup - the compiler doesn't require it.
for (int i = 0; i < 16; ++i)
{
if (board[i] == 0)
{
zeroes.push_back(i);
}
}
However, from past experience, whenever a std function exists that could replace part of my code, it is terser and hence stylistically preferred and also faster. My function seems like a fairly basic operation - I know there is a standard function* to access the index of an array that contains a value when that value only occurs once** in the array. So, is there a standard function to create an array of the indices that contain a value, assuming that more than one such index exists?
* Technically, two nested function calls: int x = std::distance(board, std::find(board, board + 16, 0));. See the accepted answer here.
** Well, it still works if more than one index with the desired value is present, but it returns only the first such index, which isn't very useful in my context.
Edit:
As one of the answers misunderstood the question, I'll clarify what I'm seeking. Let's say we have:
char board[16] = {0, 2, 0, 4,
2, 4, 8, 2,
0, 0, 8, 4,
2, 0, 0, 2};
Now, the indices which I'm looking for are {0, 2, 8, 9, 13, 14} because board[0] = 0, board[2] = 0, board[8] = 0, etc. and these are the only numbers which satisfy that property.
Here's a solution using std::iota and std::remove_if:
#include <algorithm>
#include <iostream>
int main () {
const std::size_t board_size = 16;
char board [board_size] = {
0, 2, 0, 4,
2, 4, 8, 2,
0, 0, 8, 4,
2, 0, 0, 2
};
// Initialize a zero-filled vector of the appropriate size.
std::vector<int> zeroes(board_size);
// Fill the vector with index values (0 through board_size - 1).
std::iota(zeroes.begin(), zeroes.end(), 0);
// Remove the index values that do not correspond to zero elements in the board.
zeroes.erase(std::remove_if(zeroes.begin(), zeroes.end(), [&board] (int i) {
return board[i] != 0;
}), zeroes.end());
// Output the resulting contents of the vector.
for (int i : zeroes) {
std::cout << i << std::endl;
}
}
Output of the program (demo):
0
2
8
9
13
14
I'm working on a program using arrays and I'm trying to figure out
First, with the following array declaration, what is the value stored in the scores[2][2] element?
int scores[3][3] = { {1, 2, 3} };
And also with this array declaration, what is the value stored in the scores[2][3] element?
int scores[5][5] = {5};
Could someone please explain this for me.
int scores[3][3] = { {1, 2, 3} };
is equivalent to:
int scores[3][3] = { {1, 2, 3}, {0, 0, 0}, {0, 0, 0}};
The other one is similar. You know the answer.
Array indexing is zero-based.
Which means that for: int foo[3] = {10, 20, 30};
foo[0] is 10
foo[1] is 20
foo[2] is 30
For multidimensional arrays, you should think of them as arrays of arrays.
So this would create an array containing two int[3]s: int foo[2][3] = {{10, 20, 30}, {40, 50, 60}};
foo[0][0] is 10
foo[0][1] is 20
foo[0][2] is 30
foo[1][0] is 40
foo[1][1] is 50
foo[1][2] is 60
C supports partial initialization. In which it will default all non initialized values to 0.
So if you were to do this: int foo[3] = {5};
foo[0] is 5
foo[1] is 0
foo[2] is 0
Similarly for a multidimensional array: int foo[2][3] = {5};
foo[0][0] is 5
foo[0][1] is 0
foo[0][2] is 0
foo[1][0] is 0
foo[1][1] is 0
foo[1][2] is 0
The Phobos documentation shows the following example of ranges passed to a variadic function
int[] a = [ 1, 2, 4, 5, 7, 9 ];
int[] b = [ 0, 1, 2, 4, 7, 8 ];
int[] c = [ 0, 1, 4, 5, 7, 8 ];
assert(equal(setIntersection(a, a), a));
assert(equal(setIntersection(a, b), [1, 2, 4, 7][]));
assert(equal(setIntersection(a, b, c), [1, 4, 7][]));
But what if you have a range of ranges, and you don't know in advance how many elements it will contain, like
int[][] a = [[1,2,3,4],[1,2,4,5],[1,3,4,5]];
The only thing I can think of is
if (a.length > 1) {
auto res = array(setIntersection(a[0], a[1]));
for (int i = 2; i < a.length; i++)
res = array(setIntersection(res, a[i]));
writeln(res);
}
Which works. But I was hoping to be able to pass the argument directly to the function, like setIntersection(a.tupleof) or something like that (I know that tupleof doesn't work here).
if you don't know how many elements a will have you won't be able to expand it into a tuple at compile time (and consequently pass it into a function)
so that for loop is your best bet (or implement your own setIntersection that can take a range of ranges)
I'm trying to rewrite code I've written in matlab in C++ instead.
I have a long cell in matlab containing 256 terms where every term is a 2x2 matrix. In matlab i wrote it like this.
xA = cell(1,256);
xA{1}=[0 0;3 1];
xA{2}=[0 0;13 1];
xA{3}=[0 0;3 2];
and so on...
What would be the easiest thing to use in c++?
Can I give an array with the dimensions [256][2][2] all the 4 values at a time or do I have to write one line for every specific valuen in the array?
/Mr.Buxley
You can certainly initialize them all at once, although it sounds like a lot of tedious typing:
float terms[256][4] = {
{ 0, 0, 3, 1 },
{ 0, 0, 13, 1 },
{ 0, 0, 3, 2}
...
};
I simplified it down to an array of 256 4-element arrays, for simplicity. If you wanted to really express the intended nesting, which of course is nice, you need to do:
float terms[256][2][2] = {
{ { 0, 0 }, { 3, 1 } },
{ { 0, 0 }, { 13, 1 } },
{ { 0, 0 }, { 3, 2 }}
...
};
That would be 256 lines, each of which has a "list" of two "lists" of floats. Each list needs braces. But, since C++ supports suppressing braces in things like these, you could also do:
float terms[256][2][2] = {
{ 0, 0, 3, 1 },
{ 0, 0, 13, 1 },
{ 0, 0, 3, 2}
...
};
In fact, you could even remove the braces on each line, they're optional too. I consider relying on the suppression slightly shady, though.
If you want to use higher-level types than a nested array of float (such as a Matrix<2,2> type, or something), initialization might become tricker.