What is being referenced for this matrix? - c++

I was given the following code to use as part of an exercise. I am instructed to create a 3x3 matrix and assign specific values to it.
Here is the code:
void minput(int* m, int row, int col) {
/* assign 3X3 matrix to following value
8 1 6
3 5 7
4 9 2
*/
*(m+0) = 8;
}
What I am trying to figure out is what this piece of code *(m+0) = 8; is for. I know that adding a * in front of any variable means to "give me whatever is that the address".
What does the +0 do?

*(m+0) is equivalent to m[0]. So the whole statement is assigning 8 to m[0].

it dereferences m (gives you the value at it) I'm guessing it's + 0 so that you can add in different values and get the resulting part of the matrix
Arrays are contiguous in memory, so if you were to add 1 instead of 0, you would set the next value in the matrix to 8.

*(m+0) = 8 is the same as m[0] = 8, it dereferences the pointer to the first element then assigns to it the value 8. In your code you represent the matrix via a one-dimensional array, so you probably want to index your (i,j) component as
m+i*col + j or, equivalently, m[i*col+j], i.e. the line
*(m+i*col+j) = x // can also write is as m[i*col+j] = x
assigns x to the (i,j) component.

Related

Shifting elements in array by N elements

I have an array where each 'element' is composed of 4 consecutive values. Upon update I move the array by 4 values towards the end and insert 4 new values in the beginning.
Shift:
int m = 4;
for (int i = _vsize - 1; i + 1 - m != 0; i--){
_varray[i] = std::move(_varray[i - m]);
}
Insertion:
memcpy(&_varray[0], glm::value_ptr(new_element), 4 * sizeof(float));
where new_element is of type glm::vec4 containing said 4 new values.
Any suggestions on how to improve this?
(Right now Im only shifting by one element, but want the flexibility of being able to shift say 8 times, without having to put this in a loop)
Thank you.
You can try std::copy_backward. You want to copy a range of values to another range in the same container. Since the ranges overlap and you are copying to the right you can't use regular std::copy but must use std::copy_backward instead.
int m = 4; // make this a multiple of your 'element' size
std::copy_backward(&_varray[0], &_varray[_vsize - m], &_varray[_vsize]);
There is also std::move_backward but that doesn't really matter since your float values aren't movable.

C++ arrays - limit and size

How do you declare an array for a matrix that contains say 4 numbers (2x2)? I assume that int m[4] only allows numbers up to 4. Or does it mean any four numbers? I don't understand the difference.
In a declaration
type array_name[ array_size];
type is the data type that this array stores. The particular value of array under index i, i.e. array_name[i] can be any of the values that type can represent.
In your example int m[4]; declares an array of four integers. The particular value of any of these integers can be any of the values that integer can represent. To know these limits you can print them:
#include <limits>
int imin = std::numeric_limits<int>::min(); // minimum value
int imax = std::numeric_limits<int>::max(); // maximum value
The use of STD should simplify your life in the construction of a matrix :
std::vector<std::vector<int>> M(2, std::vector<int>(2));
But if you want to use arrays :
int x[2][2];
int m [4] would declare an array with 4 uninitialized values of type integer. Remember that these values are zero-indexed,
meaning that to call a value in the array you would call m[0-3]. You may assign any values you like to the array by the following command: m[4] = {Value1, Value2, Value3, Value4} If you prefer, you may also create a loop that will assign values to an array, which can be immensely useful at times.
Keep in mind that arrays are not commonly used in C++, std::vector is far more used, and for good reason.
http://www.cplusplus.com/reference/vector/vector/
int m[4] declares an array of 4 integers. The indexes of the integers will be 0, 1, 2, 3, while the values at those indexes can be any integers. so m[2] = 2003; sets the 3rd value in the array to 2003. As for the 2x2 aspect, you probably want to do something like int m[2][2]; . I think about this as declaring an array of size 2, containing arrays at each spot, instead of ints or floats or whatever. The arrays contained at each spot (there are only two spots so only two arrays in this case) each hold two ints. So if the first value in your matrix is 32, you could set that by doing m[0][0] = 32; or more generally, m[x][y] = value_of_(x,y);
The quickest way to do what you described is probably this, if you know the values ahead of time:
int row0col0 = value at 0th row 0th column;
int row0col1 = value at 0th row 1st column;
int row1col0 = value at 1st row 0th column;
int row1col1 = value at 1st row 1st column;
int m[2][2] = { {row0col0, row0col1}, {row1col0, row1col1} };
or equivalently:
int m[2][2] = {row0col0, row0col1, row1col0, row1col1};
This is referred to as row-major order: elements in a 2d array are sorted first by row, then by column.

I don't understand how to create and use dynamic arrays in C++

Okay so I have;
int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
Should line 3 create an array with 5 elements? Or fill the first element with the number 5?
Line 4 fills the first element, how do I fill the rest?
Without line 4, line 5 reads "-842150451".
I don't understand what is going on, I'm trying to create a 2 dimensional array using x and y values specified by the user, and then fill each element one by one with numeric values also specified by the user. My above code was an attempt to try it out with a 1 dimensional array first.
The default C++ way of creating a dynamic(ally resizable) array of int is:
std::vector<int> grid;
Don't play around with unsafe pointers and manual dynamic allocation when the standard library already encapsulates this for you.
To create a vector of 5 elements, do this:
std::vector<int> grid(5);
You can then access its individual elements using []:
grid[0] = 34;
grid[1] = 42;
You can add new elements to the back:
// grid.size() is 5
grid.push_back(-42);
// grid.size() now returns 6
Consult reference docs to see all operations available on std::vector.
Should line 3 create an array with 5 elements?
Yes. It won't initialise them though, which is why you see a weird value.
Or fill the first element with the number 5?
new int(grid_x), with round brackets, would create a single object, not an array, and specify the initial value.
There's no way to allocate an array with new and initialise them with a (non-zero) value. You'll have to assign the values after allocation.
Line 4 fills the first element, how do I fill the rest?
You can use the subscript operator [] to access elements:
grid[0] = 34; // Equivalent to: *(grid) = 34
grid[1] = 42; // Equivalent to: *(grid+1) = 42
// ...
grid[4] = 77; // That's the last one: 5 elements from 0 to 4.
However, you usually don't want to juggle raw pointers like this; the burden of having to delete[] the array when you've finished with it can be difficult to fulfill. Instead, use the standard library. Here's one way to make a two-dimensional grid:
#include <vector>
std::vector<std::vector<int>> grid(grid_x, std::vector<int>(grid_y));
grid[x][y] = 42; // for any x is between 0 and grid_x-1, y between 0 and grid_y-1
Or might be more efficient to use a single contiguous array; you'll need your own little functions to access that as a two-dimenionsal grid. Something like this might be a good starting point:
template <typename T>
class Grid {
public:
Grid(size_t x, size_t y) : size_x(x), size_y(y), v(x*y) {}
T & operator()(size_t x, size_t y) {return v[y*size_x + x];}
T const & operator()(size_t x, size_t y) const {return v[y*size_x + x];}
private:
size_t size_x, size_y;
std::vector<T> v;
};
Grid grid(grid_x,grid_y);
grid(x,y) = 42;
Should line 3 create an array with 5 elements? Or fill the first element with the number 5?
Create an array with 5 elements.
Line 4 fills the first element, how do I fill the rest?
grid[n] = x;
Where n is the index of the element you want to set and x is the value.
Line 3 allocates memory for 5 integers side by side in memory so that they can be accessed and modified by...
The bracket operator, x[y] is exactly equivalent to *(x+y), so you could change Line 4 to grid[0] = 34; to make it more readable (this is why grid[2] will do the same thing as 2[grid]!)
An array is simply a contiguous block of memory. Therefore it has a starting address.
int * grid;
Is the C representation of the address of an integer, you can read the * as 'pointer'. Since your array is an array of integers, the address of the first element in the array is effectively the same as the address of the array. Hence line 3
grid = new int[grid_x];
allocates enough memory (on the heap) to hold the array and places its address in the grid variable. At this point the content of that memory is whatever it was when the physical silicon was last used. Reading from uninitialised memory will result in unpredictable values, hence your observation that leaving out line 4 results in strange output.
Remember that * pointer? On line four you can read it as 'the content of the pointer' and therefore
*grid = 34;
means set the content of the memory pointed to by grid to the value 34. But line 3 gave grid the address of the first element of the array. So line 4 sets the first element of the array to be 34.
In C, arrays use a zero-based index, which means that the first element of the array is number 0 and the last is number-of-elements-in-the-array - 1. So one way of filling the array is to index each element in turn to set a value to it.
for(int index = 0; index < grid_x; index++)
{
grid[index] = 34;
}
Alternatively, you could continue to use a pointer to do the same job.
for(int* pointerToElement = grid; 0 < grid_x; grid_x-- )
{
// save 34 to the address held by the pointer
/// and post-increment the pointer to the next element.
*pointerToElement++ = 34;
}
Have fun with arrays and pointers, they consistently provide a huge range of opportunities to spend sleepless hours wondering why your code doesn't work, PC reboots, router catches fire, etc, etc.
int grid_x = 5
int * grid;
grid = new int[grid_x];
*grid = 34;
cout << grid[0];
Should line 3 create an array with 5 elements? Or fill the first
element with the number 5?
Definitely the former. With the operator "new" you are allocating memory
Line 4 fills the first element, how do I fill the rest?
Use operator [], e.g.:
for int (i=0; i < grid_x; i++) { //Reset the buffer
grid[i] = 0;
}
Without line 4, line 5 reads "-842150451".
You are just reading uninitialized memory, it could be any value.
I don't understand what is going on, I'm trying to create a 2
dimensional array using x and y values specified by the user, and then
fill each element one by one with numeric values also specified by the
user. My above code was an attempt to try it out with a 1 dimensional
array first.
Other users explained how to use vectors. If you have to set only once the size of your array, I usually prefer boost::scoped_array which takes care of deleting when the variable goes out of scope.
For a two dimensional array of size not known at compile time, you need something a little bit trickier, like a scoped_array of scoped_arrays. Creating it will require necessarily a for loop, though.
using boost::scoped_array;
int grid_x;
int grid_y;
///Reading values from user...
scoped_array<scoped_array<int> > grid(new scoped_array<int> [grid_x]);
for (int i = 0; i < grid_x; i++)
grid[i] = scoped_array<int>(new int[grid_y] );
You will be able then to access your grid elements as
grid[x][y];
Note:
It would work also taking scoped_array out of the game,
typedef int* p_int_t;
p_int_t* grid = new p_int_t [grid_x];
for (int i = 0; i < grid_x; i++)
grid[i] = new int[grid_y];
but then you would have to take care of deletion at the end of the array's life, of ALL sub arrays.

Is a 2D array of C++ vectors suitable for keeping track of a 2D array's dynamic domain values?

Writing a C++ backtracking with CSP algorithm program, to solve a Sudoku puzzle.
Variables are mapped to a 9X9 grid (81 variables), so the program is row/column oriented.
To make backtracking smarter, the program needs to keep track of the possible values that each variable on the 9X9 grid can still accept.
(The list of numbers is 1 - 9 for each of the 81 variables and is constantly changing.)
My initial thought is to use a 2D array of vectors - to map to each variable.
For example vector[1][5] will contain all the possible values for variable[1][5].
In terms of efficiency and ease of use - is this the right container or is there something else that works better?
Using an std::vector for this sounds unnecessary and overkill. Since you know the exact domain of your variables, and it's only the numbers 1-9, I suggest using a two dimensional array where each position works as a bitmap.
Code sample (untested):
short vector[9][9] = { 0 };
/* v must be in the range [1-9] */
void remove_value(int x, int y, int v) {
vec[x][y] |= 1 << v;
}
int test_value(int x, int y, int v) {
return (vec[x][y] & (1 << v));
}
int next_value(int x, int y) {
int res = 1;
for (int mask = 2;
mask != (1 << 10) && (vector[x][y] & mask);
mask <<= 1, res++)
; /* Intentionally left blank */
return res;
}
Think of vector[x][y] as a binary integer initialized to 0:
...0000000000
The meaning is such that a bit i set to 1 means you have already tested number i, otherwise, you haven't tested it yet. Bit counting, as usual, is right to left, and starts from 0. You will only be using bits 1 to 9.
remove_value() should be called everytime you finished testing a new value (that is, to remove this value from the domain), and test_value() can be used to check if v has ever been tested - it will return 0 if v has not been used yet, and something that is not 0 otherwise (to be precise, 1 << v). next_value() will give you the next value to test for a position [x,y] sorted in ascending order, or 10 if every value in the range 1-9 has already been tested.

2-dimensional array, IF condition checking

I've came across a problem when coding with C++ 2D array.
Just a little question, what does the code below mean?
...
if(array[x][y] >= 9){
...
}
...
Does that mean when the sum of x and y of the array is greater or equal to 9, then only the body of the IF will run? Or ........?
Please explain and provide some simply examples.
the array is two dimensional, it means the element at array[x][y]
unlike 1D arrays, which only require 1 index, 2D arrays require 2 indices in the form of array[x][y] presumably in a nested for loop.
You can iterate through such an array like this
for (int x = 0; x < arrayLength; x++) {
for (int y = 0; y < array[x]Length; y++) {
// do something with array[x][y]
}
}
where arrayLength is the length of array and array[x] length is the length of array[x].
So in reference to the code that you posted, it's testing to see if the member of the 2D array is greater than or equal to 9.
Ok let's start with the basics.
1D Arrays
How can you imagine a normal array? You could say a normal array is like a number line:
|-------------------------------| where every - is one element in your array
The very first '-' on the left side is the element at myArray[0] (the '|' are just symbolizing that it has a start and a end).
2D Arrays
A 2D array can be visualized as checkerboard, bookshelf or a table with columns and rows.
|-------------------------------|
|-------------------------------|
|-------------------------------|
|-------------------------------|
Just like in chess you need 2 values in order to address an element. If you only specify one value the compiler might know the row of your value but not its column (or the other way around). That means you need x and y coordinates (which is a visual analogy for a coordinate system). In order to address a value you have to do it like this:
myArray[x][y] where x could be the row of our checkerboard and y the column.
In your case your 2D array is most likely filled with integers. The 'if' statement checks if the value stored in myArray[x][y] is larger than 9. If myArray[x][y] is larger than 9 this statement returns true and the code inside will get executed.
After executing the code inside of the 'if' statement the program will continue to execute the code after the if statement. 2D arrays can be understood as an array containing arrays.
If you are thinking 3 dimensional arrays are possible you're right. Here you need 3 coordinates in order to describe a point since you have depth, height and length (here I'm talking about the visual length not the length in terms of total amount of elements.).
I don't know whether this helped but this is of course a very visual approach of explaining how multi-dimensional arrays work.
Example
int myArray[3][3] = {{1, 2, 3}, // row 0
{4, 5, 6}, // row 1
{7, 8, 10}}; // row 2
In this case your if statement would only be executed if x = 2 and y = 2 since myArray[2][2] = 10
It means "IF the element at coordinates (x,y) is greater or equal than 9...".
There is no addition operation. The array is probably declared with the minimum dimensions (x+1, y+1).
int array[2][2] = {{12, 6}, {3, -2}};
int x=1, y=0;
if(array[x][y] >= 9){...} // array[1][0] equals 3, condition is false