Defining 2D arrays in C++ - c++

int train [4] [3] = { 0, 0, 0,
0, 1, 0,
1, 0, 0,
1, 1, 1 };
Is that a valid initialization of a 2d array in C++
And the rows will be 0,0,0 (row 1), (0,1,0) (row2), (1,0,0) (row3) and (1,1,1) (row 4) ?
And is it equivalent to
int train [4] [3] = {{0, 0, 0},
{0, 1, 0},
{1, 0, 0},
{1, 1, 1}};

int train [4] [3] = { 0, 0, 0,
0, 1, 0,
1, 0, 0,
1, 1, 1 };
is a valid initialization of a 2D array in C++.
From the C++11 Standard:
8.5.1 Aggregates
10 When initializing a multi-dimensional array, the initializer-clauses initialize the elements with the last (right-most) index of the array varying the fastest (8.3.4). [ Example:
int x[2][2] = { 3, 1, 4, 2 };
initializes x[0][0] to 3, x[0][1] to 1, x[1][0] to 4, and x[1][1] to 2. On the other hand,
float y[4][3] = {
{ 1 }, { 2 }, { 3 }, { 4 }
};
initializes the first column of y (regarded as a two-dimensional array) and leaves the rest zero. — end example ]

Yes! It is a valid intialization in c++.

Related

How can I make something happen x percentage?

I have to write a piece of code in the form of c*b, where c and b are random numbers and the product is smaller than INT_MAx. But b or c has to be equal to 0 10% of the time and I don't know how to do that.
srand ( time(NULL) );
int product = b*c;
c = rand() % 10000;
b = rand() % INT_MAX/c;
b*c < INT_MAX;
cout<<""<<endl;
cout << "What is " << c << "x" << b << "?"<<endl;
cin >> guess;
You can use std::piecewise_constant_distribution
std::random_device rd;
std::mt19937 gen(rd());
double interval[] = {0, 0, 1, Max};
double weights[] = { .10, 0, .9};
std::piecewise_constant_distribution<> dist(std::begin(interval),
std::end(interval),
weights);
dist(gen);
An int is always less than or equal to INT_MAX therefore you can simply multiply a random boolean variable that is true with 90% probability with the product of two uniformly distributed integers:
std::random_device rd;
std::mt19937 generator(rd());
std::uniform_int_distribution<int> uniform;
std::bernoulli_distribution bernoulli(0.9); // 90% 1 ; 10% 0
const int product = bernoulli(generator) * uniform(generator) * uniform(generator)
If you had a specific limit in mind, like say N for the individual numbers and M for the product of the two numbers you can do:
std::default_random_engine generator;
std::uniform_int_distribution<int> uniform(0,N);
std::bernoulli_distribution bernoulli(0.9); // 90% 1 ; 10% 0
int product;
do { product = bernoulli(generator) * uniform(generator) * uniform(generator) }
while(!(product<M));
edit: std::piecewise_constant_distribution is more elegant, didn't know about it until I read the other answer.
If you want a portable solution that does not depend on the standard C++ library and also which is faster, and maybe simpler to understand, you can use the following snippet. The variable random_sequence is a pre-generated array of random numbers where the 0 happens 10% of the time. The variable runs and len are used to index into this array as an endless sequence. This is however, a simple solution, since the pattern will repeat after 90 runs. But if you don't care about the pattern repeating then this method will work fine.
int runs = 0;
int len = 90; //The length of the random sequence.
int random_sequence[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int coefficient = random_sequence[runs % len];
runs++;
Then, whatever variable you want to be 0 10% of the time you do it like this:
float b = coefficient * rand();
or
float c = coefficient * rand();
If you want both variables to be 0 10% of the times individidually then it's like this:
float b = coefficient * rand();
coefficient = random_sequence[runs % len];
float c = coefficient * rand();
And if you want them to be 0 10% of the times jointly then the random_sequence array must be like this:
int len = 80;
int random_sequence[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
And use
float b = coefficient * rand();
float c = coefficient * rand();
I gave it a shot here #[ http://codepad.org/DLbVfNVQ ]. Average value is somewhere in the neighborhood of 0.4. -CR

Generating permutations from a template

My goal is to create a general function that creates a two-dimensional vector filled with permutations (vector) based on a template given and on parameters, as follows:
some positions of the vector have to be fixed, based on a template as a function parameter vector. For example, if the given template is {0, 1, 0, -1, 3, -1}, this means that permutations will only vary by the numbers in places of -1.
n. n-1 is the range of integers the permutation can include. E.g. if n = 4, only 0, 1, 2, 3 can appear in the vector
length, which is the length of the vector
Note, that if a number from the template already appears in it, it will not be generated in the permutations.
So, to give an example:
n = 6, length = 5, template = {2, 1, 0, -1, 0, -1}
the permutations are:
{2, 1, 0, 3, 0, 3}
{2, 1, 0, 3, 0, 4}
{2, 1, 0, 3, 0, 5}
{2, 1, 0, 4, 0, 3}
{2, 1, 0, 4, 0, 4}
{2, 1, 0, 4, 0, 5}
{2, 1, 0, 5, 0, 3}
{2, 1, 0, 5, 0, 4}
{2, 1, 0, 5, 0, 5}
As you can see, the numbers are only generated in indexes 3 and 5 (places, where it was -1), also, the places to do not include 0, 1 or 2, since they already appear in the template.
I need to generate these permutations without using the <algorithm> library.
I assume creating a recursive function is the best option, but I do not know how to move forward. Any suggestions would help.
Thanks
Since you've offered no visible attempt, I assume it might be helpful for you to study some working code. This is in JavaScript (I hope it's producing the expected output). I hope it can help give you some ideas you could translate to C++.
function f(template){
console.log(JSON.stringify(template));
var used = template.reduce((acc, x) => { if (x != -1) acc.add(x); return acc; }, new Set());
console.log(`used: ${Array.from(used)}`);
var needed = new Set(template.reduce((acc, x, i) => { if (!used.has(i)) acc.push(i); return acc; }, []));
console.log(`needed: ${Array.from(needed)}`);
var indexes = template.reduce((acc, x, i) => { if (x == -1) return acc.concat(i); else return acc; }, []);
console.log(`indexes: ${indexes}`);
function g(needed, indexes, template, i=0){
if (i == indexes.length)
return [template];
var result = [];
// Each member of 'needed' must appear in
// each position, indexes[i]
for (x of needed){
let _template = template.slice();
_template[ indexes[i] ] = x;
result = result.concat(
g(needed, indexes, _template, i + 1));
}
return result;
}
return g(needed, indexes, template);
}
var template = [2, 1, 0, -1, 0, -1];
var result = f(template);
var str = '\n';
for (let r of result)
str += JSON.stringify(r) + '\n';
console.log(str);

Cuda Thrust - How to optimize a code using sort_by_key, merge_by_key and reduce_by_key

I am using c++ and cuda/thrust to perform a calculation on the GPU, which is a new field for me. Unfortunately, my code (MCVE below) is not very efficient, so I would like to know how to optimize it. The code performs the following operations:
There are two key vector and two value vector. The key vectors contain basically the i and j of an upper triangular matrix (in this example: of size 4x4).
key1 {0, 0, 0, 1, 1, 2} value1: {0.5, 0.5, 0.5, -1.0, -1.0, 2.0}
key2 {1, 2, 3, 2, 3, 3} value2: {-1, 2.0, -3.5, 2.0, -3.5, -3.5}
The task is to sum over all values which have the same key. To achieve that, I sorted the second value vector using sort_by_key. The result is:
key1 {0, 0, 0, 1, 1, 2} value1: {0.5, 0.5, 0.5, -1.0, -1.0, 2.0}
key2 {1, 2, 2, 3, 3, 3} value2: {-1.0, 2.0, 2.0, -3.5, -3.5, -3.5}
After that, I merged both value vector using merge_by_key, which leads to a new key and value vector with a size double as big than before.
key_merge {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3}
value_merge {0.5, 0.5, 0.5, -1.0, -1.0, -1.0, 2.0, 2.0, 2.0, -3.5, -3.5, -3.5}
The last step is to use reduce_by_key to sum over all values with the same key. The result is:
key {0, 1, 2, 3} value: {1.5, -3.0, 6.0, -10.5}
The code below which perform this operations is quiet slowly and I am afraid that the performance for larger size will be bad. How can it be optimized? Is it possible to fusion sort_by_key, merge_by_key and reduce_by_key? Since I know the resulting key vector from sort_by_key in advance, is it possible to transform the value vector "from an old to a new key"? Does it make sense, to merge two vectors before reducing them or is it faster to use reduce_by_key separately for each pair of value/key vector? Is it possible to speed up the reduce_by_key calculation by using the fact, that here the number of different key value is known and the number of equal keys is always the same?
#include <stdio.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>
#include <thrust/reduce.h>
#include <thrust/merge.h>
int main(){
int key_1[6] = {0, 0, 0, 1, 1, 2};
int key_2[6] = {1, 2, 3, 2, 3, 3};
thrust::device_vector<double> k1(key_1,key_1+6);
thrust::device_vector<double> k2(key_2,key_2+6);
double value_1[6] = {0.5, 0.5, 0.5, -1.0, -1.0, 2.0};
double value_2[6] = {-1, 2.0, -3.5, 2.0, -3.5, -3.5};
thrust::device_vector<double> v1(value_1,value_1+6);
thrust::device_vector<double> v2(value_2,value_2+6);
thrust::device_vector<double> mk(12);
thrust::device_vector<double> mv(12);
thrust::device_vector<double> rk(4);
thrust::device_vector<double> rv(4);
thrust::sort_by_key(k2.begin(), k2.end(), v2.begin());
thrust::merge_by_key(k1.begin(), k1.end(), k2.begin(), k2.end(),v1.begin(), v2.begin(), mk.begin(), mv.begin());
thrust::reduce_by_key(mk.begin(), mk.end(), mv.begin(), rk.begin(), rv.begin());
for (unsigned i=0; i<4; i++) {
double tmp1 = rk[i];
double tmp2 = rv[i];
printf("key value %f is related to %f\n", tmp1, tmp2);
}
return 0;
}
Result:
key value 0.000000 is related to 1.500000
key value 1.000000 is related to -3.000000
key value 2.000000 is related to 6.000000
key value 3.000000 is related to -10.500000
Here is one possible approach that I think might be quicker than your sequence. The key idea is that we want to avoid sorting data where we know the order ahead of time. If we can leverage the order knowledge that we have, instead of sorting the data, we can simply reorder it into the desired arrangement.
Let's make some observations about the data. If your key1 and key2 are in fact the i,j indices of an upper triangular matrix, then we can make some observations about the concatenation of these two vectors:
The concatenated vector will contain equal numbers of each key. (I believe you may have pointed this out in your question.) So in your case, the vector will contain three 0 keys, three 1 keys, three 2 keys, and three 3 keys. I believe this pattern should hold for any upper triangular pattern independent of matrix dimension. So a matrix of dimension N that is upper triangular will have N sets of keys in the concatenated index vector, each set consisting of N-1 like elements.
In the concatenated vector, we can discover/establish a consistent ordering of keys (based on matrix dimension N), which allows us to reorder the vector in like-key-grouped order, without resorting to a traditional sort operation.
If we combine the above 2 ideas, then we can probably solve the entire problem with some scatter operations to replace the sort/merge activity, followed by the thrust::reduce_by_key operation. The scatter operations can be accomplished with thrust::copy to an appropriate thrust::permutation_iterator combined with an appropriate index calculation functor. Since we know exactly what the reordered concatenated key vector will look like (in your dimension-4 example: {0,0,0,1,1,1,2,2,2,3,3,3}), we need not perform the reordering explicitly on it. However we must reorder the value vector using the same mapping. So let's develop the arithmetic for that mapping:
dimension (N=)4 example
vector index: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11
desired (group) order: 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3
concatenated keys: 0, 0, 0, 1, 1, 2, 1, 2, 3, 2, 3, 3
group start idx: 0, 0, 0, 3, 3, 6, 3, 6, 9, 6, 9, 9
group offset idx: 0, 1, 2, 0, 1, 0, 2, 1, 0, 2, 1, 2
destination idx: 0, 1, 2, 3, 4, 6, 5, 7, 9, 8,10,11
dimension (N=)5 example
vector index: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19
desired (group) order: 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4
concatenated keys: 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 1, 2, 3, 4, 2, 3, 4, 3, 4, 4
group start idx: 0, 0, 0, 0, 4, 4, 4, 8, 8,12, 4, 8,12,16, 8,12,16,12,16,16
group offset idx: 0, 1, 2, 3, 0, 1, 2, 0, 1, 0, 3, 2, 1, 0, 3, 2, 1, 3, 2, 3
destination idx: 0, 1, 2, 3, 4, 5, 6,10, 7, 8,11,14, 9,12,15,17,13,16,18,19
We can observe that in each case, the destination index (i.e. the location to move the selected key or value to, for the desired group order) is equal to the group start index plus the group offset index. The group start index is simply the key multiplied by (N-1). The group offset index is a pattern similar to an upper or lower triangular index pattern (in 2 different incarnations, for each half of the concatenated vector). The concatenated keys is simply the concatenation of the key1 and key2 vectors (we will create this concatenation virtually using permutation_iterator). The desired group order is known a-priori, it is simply a sequence of integer groups, with N groups consisting of N-1 elements each. It is equivalent to the sorted version of the concatenated key vector. Therefore we can directly compute the destination index in a functor.
For the creation of the group offset index patterns, we can subtract your two key vectors (and subtract an additional 1):
key2: 1, 2, 3, 2, 3, 3
key1: 0, 0, 0, 1, 1, 2
key1+1: 1, 1, 1, 2, 2, 3
p1 = key2-(key1+1): 0, 1, 2, 0, 1, 0
p2 = (N-2)-p1: 2, 1, 0, 2, 1, 2
grp offset idx=p1|p2: 0, 1, 2, 0, 1, 0, 2, 1, 0, 2, 1, 2
Here is a fully-worked example demonstrating the above concepts using your example data:
$ cat t1133.cu
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <thrust/copy.h>
#include <thrust/transform.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <iostream>
// "triangular sort" index generator
struct idx_functor
{
int n;
idx_functor(int _n): n(_n) {};
template <typename T>
__host__ __device__
int operator()(const T &t){
int k1 = thrust::get<0>(t);
int k2 = thrust::get<1>(t);
int id = thrust::get<2>(t);
int go,k;
if (id < (n*(n-1))/2){ // first half
go = k2-k1-1;
k = k1;
}
else { // second half
go = n-k2+k1-1;
k = k2;
}
return k*(n-1)+go;
}
};
const int N = 4;
using namespace thrust::placeholders;
int main(){
// useful dimensions
int d1 = N*(N-1);
int d2 = d1/2;
// iniitialize keys
int key_1[] = {0, 0, 0, 1, 1, 2};
int key_2[] = {1, 2, 3, 2, 3, 3};
thrust::device_vector<int> k1(key_1, key_1+d2);
thrust::device_vector<int> k2(key_2, key_2+d2);
// initialize values
double value_1[] = {0.5, 0.5, 0.5, -1.0, -1.0, 2.0};
double value_2[] = {-1, 2.0, -3.5, 2.0, -3.5, -3.5};
thrust::device_vector<double> v(d1);
thrust::device_vector<double> vg(d1);
thrust::copy_n(value_1, d2, v.begin());
thrust::copy_n(value_2, d2, v.begin()+d2);
// reorder (group) values by key
thrust::copy(v.begin(), v.end(), thrust::make_permutation_iterator(vg.begin(), thrust::make_transform_iterator(thrust::make_zip_iterator(thrust::make_tuple(thrust::make_permutation_iterator(k1.begin(), thrust::make_transform_iterator(thrust::counting_iterator<int>(0), _1%d2)), thrust::make_permutation_iterator(k2.begin(), thrust::make_transform_iterator(thrust::counting_iterator<int>(0), _1%d2)), thrust::counting_iterator<int>(0))), idx_functor(N))));
// sum results
thrust::device_vector<double> rv(N);
thrust::device_vector<int> rk(N);
thrust::reduce_by_key(thrust::make_transform_iterator(thrust::counting_iterator<int>(0), _1/(N-1)), thrust::make_transform_iterator(thrust::counting_iterator<int>(d1), _1/(N-1)), vg.begin(), rk.begin(), rv.begin());
// print results
std::cout << "Keys:" << std::endl;
thrust::copy_n(rk.begin(), N, std::ostream_iterator<int>(std::cout, ", "));
std::cout << std::endl << "Sums:" << std::endl;
thrust::copy_n(rv.begin(), N, std::ostream_iterator<double>(std::cout, ", "));
std::cout << std::endl;
return 0;
}
$ nvcc -std=c++11 -o t1133 t1133.cu
$ ./t1133
Keys:
0, 1, 2, 3,
Sums:
1.5, -3, 6, -10.5,
$
The net effect is that your thrust::sort_by_key and thrust::merge_by_key operations have been replaced by a single thrust::copy operation which should be more efficient.

How to search for a vector in a matrix in C++ and which algorithm?

Suppose I have a matrix and a vector given by. How can I perform a search algorithm like binary search to return the index?
Example:
const int V_SIZE = 10,H_SIZE = 7;
int a1[V_SIZE][H_SIZE] = {
{1,2,0,0,0,0,0},
{1,3,0,0,0,0,0},
{2,2,4,0,0,0,0},
{2,2,6,0,0,0,0},
{3,2,4,7,0,0,0},
{4,1,3,5,9,0,0},
{4,1,4,6,8,0,0},
{4,2,3,4,7,0,0},
{5,2,3,5,7,8,0},
{6,1,3,4,5,7,10}
}; // sorted
int a2 [H_SIZE] = {4,1,3,5,9,0,0};
Perform a search for the vector a2 in the matrix a1 and the return value is 6
Thank a lot
You could use a 2D std::array in combination with std::lower_bound:
const int V_SIZE = 10,H_SIZE = 7;
std::array<std::array<int, H_SIZE>, V_SIZE> a1 {
{{{1,2,0,0,0,0,0}},
{{1,3,0,0,0,0,0}},
{{2,2,4,0,0,0,0}},
{{2,2,6,0,0,0,0}},
{{3,2,4,7,0,0,0}},
{{4,1,3,5,9,0,0}},
{{4,1,4,6,8,0,0}},
{{4,2,3,4,7,0,0}},
{{5,2,3,5,7,8,0}},
{{6,1,3,4,5,7,10}}
}}; // sorted
std::array<int, H_SIZE> a2 {{4,1,3,5,9,0,0}};
int idx = std::lower_bound(std::begin(a1), std::end(a1), a2) - std::begin(a1);
LIVE DEMO
If the matrix is sorted on the first number, you could use binary search to find an approximate index. You then have to go back until you find the first row starting with the same number as in the vector, as well as forward to find the last row starting with the same number. Then you loop over the vector, searching for a match for the second, third, etc. number in the range of rows you have.
What about something like this using std::array?
template <int HSIZE>
bool operator<(const std::array<int, HSIZE> &lhs, const std::array<int, HSIZE> &rhs)
{
for (int i = 0; i < HSIZE; i++)
if (lhs[i] != rhs[i])
return lhs[i] < rhs[i];
return false;
}
std::array<int, 7> a1[] =
{
{ 1, 2, 0, 0, 0, 0, 0 },
{ 1, 3, 0, 0, 0, 0, 0 },
{ 2, 2, 4, 0, 0, 0, 0 },
{ 2, 2, 6, 0, 0, 0, 0 },
{ 3, 2, 4, 7, 0, 0, 0 },
{ 4, 1, 3, 5, 9, 0, 0 },
{ 4, 1, 4, 6, 8, 0, 0 },
{ 4, 2, 3, 4, 7, 0, 0 },
{ 5, 2, 3, 5, 7, 8, 0 },
{ 6, 1, 3, 4, 5, 7, 10 }
};
void search(void)
{
std::array<int, 7> a2 = { 4, 1, 3, 5, 9, 0, 0 };
std::array<int, 7> *a1_end = a1 + sizeof(a1) / sizeof(std::array<int, 7>);
std::array<int, 7> *it = std::lower_bound(a1, a1_end, a2);
}

c++ dynamic array initialization with declaration

I have function like this:
void findScarf1(bool ** matrix, int m, int n, int radius, int connectivity);
and in main function I create 2d dynamic array to pass in this function
bool matrix[6][7] = {
{0, 0, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 0, 0}
};
The problem is:
findScarf1(matrix, 6, 7, 3, 4);
causes
error C2664: 'findScarf1' : cannot convert parameter 1 from 'bool [6][7]' to 'bool **'
How to initialize array compactly(simultaneously with declaration)?
p.s. sorry if it's duplicate question but I've spent 1.5 hours figuring it out
If you look at how your array is laid out in memory, and compare it how a pointer-to-pointer "matrix" is laid out, you will understand why you can't pass the matrix as a pointer to pointer.
You matrix is like this:
[ matrix[0][0] | matrix[0][1] | ... | matrix[0][6] | matrix[1][0] | matrix[1][1] | ... ]
A matrix in pointer-to-pointer is like this:
[ matrix[0] | matrix[1] | ... ]
| |
| v
| [ matrix[1][0] | matrix[1][1] | ... ]
v
[ matrix[0][0] | matrix[0][1] | ... ]
You can solve this by changing the function argument:
bool (*matrix)[7]
That makes the argument matrix a pointer to an array, which will work.
And by the way, the matrix variable you have is not dynamic, it's fully declared and initialized by the compiler, there's nothing dynamic about it.
Technically, a 2D array is an array of 1D arrays. So it cannot convert into pointer to pointer. It can convert into pointer to array, though.
So this should work:
void findScarf1(bool (*matrix)[7], int m, int n, int radius, int connectivity);
Here bool (*matrix)[7] declares a pointer to array of 7 bool.
Hope that helps.
You may define the function as:
void findScarf1(bool * matrix, int m, int n, int radius, int connectivity);
Or
void findScarf1(bool matrix[][7], int m, int n, int radius, int connectivity);
No matter how many dimensions an array has, it's just a block of linear memory.
When you use the first manner, you may need to do a cast when call this function:
findScarf1((bool *)marix, 6, 7, 3, 4);
My Following example may be helpful for you:
#include<stdio.h>
void f(int (*m)[7]){ // As Nawaz answred
printf("%d\n", m[3][3]);
}
void _f(int m[6][7]){ // As I commented to your question
printf("%d\n", m[3][3]);
}
void _f_(int m[][7]){// Second form of Nawaz's answe
printf("%d\n", m[3][3]);
}
void f_(int (*m)[6][7]){// Pointer of 2D array
printf("%d\n", (*m)[3][3]);
}
int main(){
int matrix[6][7] = {
{0, 0, 1, 1, 1, 0, 0},
{0, 0, 1, 3, 1, 0, 0},
{0, 0, 1, 4, 1, 0, 0},
{0, 0, 1, 5, 1, 0, 0},
{0, 0, 1, 6, 1, 0, 0},
{0, 0, 1, 7, 1, 0, 0}
};
f(matrix);
_f(matrix);
_f_(matrix);
f_(&matrix);
return 1;
}
question not tanged to c, but I compiled with gcc (I have not installed g++).
~$ gcc -Wall -pedantic 2d.c
~$ ./a.out
5
5
5
5
I was not intended to post an answer, but because I commented wrong to Nawaz answer so during an experiment I written this code.
Here one can find it working at codepacde