What is the meaning of new int[25,2]? - c++

What is the meaning of using the second parameter with a comma in the below code?
int *num = new int[25,2];

That's the comma operator in action: it evaluates it's operand and returns the last one, in your case 2.
So that is equivalent with:
int *num = new int[2];
It's probably safe to say that the 25,2 part was not what was intended, unless it's a trick question.
Edit: thank you Didier Trosset.

That's the comma operator in action: it evaluates it's operand and returns the last one, in your case 2. So that is equivalent with:
int *num = new int[2];

You are using the comma operator, which is making the code do something that you might not expect at a first glance.
The comma operator evaluates the LHS operand then evaluates and returns the RHS operand. So in the case of 25, 2 it will evaluate 25 (doing nothing) then evaluate and return 2, so that line of code is equivalent to:
int *num = new int[2];

// Declare a single-dimensional array
int[] array1 = new int[5];
// Declare and set array element values
int[] array2 = new int[] { 1, 3, 5, 7, 9 };
// Alternative syntax
int[] array3 = { 1, 2, 3, 4, 5, 6 };
// Declare a two dimensional array
int[,] multiDimensionalArray1 = new int[2, 3];
// Declare and set array element values
int[,] multiDimensionalArray2 = { { 1, 2, 3 }, { 4, 5, 6 } };
// Declare a array
int[][] Array = new int[6][];
// Set the values of the first array in the array structure
Array[0] = new int[4] { 1, 2, 3, 4 };

Related

How to place variadic template arguments into an array?

I want to have a variable number of arguments to a function and inside that function I want to place them into an array. I tried to use a fold expression for this because I didn't understand what they did. I thought they just simply expanded the arguments with a comma in between:
template <typename ... var_args_t>
void putArgumentsToArray(var_args_t&& ... values)
{
constexpr int num_args = sizeof ... (var_args_t);
int values_array[num_args] = {
(values, ...)
};
for (int i = 0; i < num_args; ++i)
std::cout << values_array[i] << "\n";
/* PRINTS [6, 0, 0, 0, 0, 0]*/
}
int main()
{
putArgumentsToArray(1, 2, 3, 4, 5, 6);
}
The end result is that the array is only initialised with one value(6), because all six arguments are evaluated as expressions, however the comma operator works so that only the last argument is returned. So the array has only one initialiser.
I know I can use a std::vector or a loop, but it would be really nice and clean if I could do this directly into the array initialiser.
You have confused the syntax a bit. You wished parentheses on other places
int values_array[num_args] = {
(values)...
};
or the same but without parentheses
int values_array[num_args] = {
values...
};
values... expands to
1, 2, 3, 4, 5, 6
Whereas (values, ...) expands to the comma operator in the parentheses
(1, 2, 3, 4, 5, 6)
that returns the single 6, the value of the last operand of the comma operator.

Calculating an array's number of elements... Able to refer to its index values by just stating the return type? What? How? Why? (C++)

I am learning how to calculate the size and number of elements in an array and came across a question. In a tutorial I see
we can calculate the number of elements in an array as follows ...
int array_variable [] = {1, 5, 8, 10};
int array_variable_number_of_elements = sizeof(array_variable) / sizeof (int);
I am aware and fully understand why you could replace
sizeof (int);
with
sizeof (array_variable[0]); // or use any index value from the array_variable
The video appears to suggest using just int is good practice which I don't understand. The computer obviously isn't psychic and int is simply a data type. What happens when there are two int type arrays in the same function? Why does this work? Does this work because it is in the same line as the following?
int array_variable_number_of_elements = sizeof(array_variable)
Thanks :)
Second approach is better and more generic, when you need to change the type of array int to char, you don't have to edit second line at all.
char array_variable [] = {'a', 'b', 'c' }; //changed this line only
int array_variable_number_of_elements = sizeof(array_variable) / sizeof
(array_variable[0]);
To answer your below comment;
above lines you can interpret like below;
int array_variable = {1, 2, 3, 4, 5 };
int array_variable_number_of_elements = sizeof(array_variable) / sizeof ( int);
// ^^^^^^^^^ ^^^^ ^^^
// array_variable_number_of_elements = 20 / 4 ; // 20 / 4 = 5
total array size in bytes 20 and size of int is 4 bytes in my system;
total number of elements in array is 5;

Strange array initialization (porting from C to C++) [duplicate]

What is the meaning of following Code? Code is from the regression test suite of GCC.
static char * name[] = {
[0x80000000] = "bar"
};
In C99 you can specify the array indices to assigned value, For example:
static char * name[] = {
[3] = "bar"
};
is same as:
static char * name[] = { NULL, NULL, NULL, "bar"};
The size of array is four. Check an example code working at ideaone. In your code array size is 0x80000001 (its an hexadecimal number).
Note: Uninitialized elements initialized with 0.
5.20 Designated Initializers:
In ISO C99 you can give the elements in any order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C89 mode as well. This extension is not implemented in GNU C++.
To specify an array index, write [index] = before the element value. For example,
int a[6] = { [4] = 29, [2] = 15 };
is equivalent to
int a[6] = { 0, 0, 15, 0, 29, 0 };
One more interesting declaration is possible in a GNU extension:
An alternative syntax for this which has been obsolete since GCC 2.5 but GCC still accepts is to write [index] before the element value, with no =.
To initialize a range of elements to the same value, write [first ... last] = value. For example,
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
Note: that the length of the array is the highest value specified plus one.
Additionally, we can combine this technique of naming elements with ordinary C initialization of successive elements. Each initializer element that does not have a designator applies to the next consecutive element of the array or structure. For example:
int a[6] = { [1] = v1, v2, [4] = v4 };
is equivalent to
int a[6] = { 0, v1, v2, 0, v4, 0 };
Labeling the elements of an array initializer is especially useful when the indices are characters or belong to an enum type. For example:
int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1
};
It's called designated initializer which is introduced in C99, gcc also supports it in GNU89 as an extension, see here for detail.
int a[6] = { [4] = 29, [2] = 15 };
is equivalent to
int a[6] = { 0, 0, 15, 0, 29, 0 };
It's a C99 designated initializer. the value in brackets specifies the index to receive the value.

Initialize new c++ array with different specified values

I am able to initialize an array with default values
int arrayWithDefault[5] = { 0 };
Also able to initialize new array with default values
int *ptrArrayWithDefault = new int[2]();
How can i initialize a new array with different values such that
ptrArrayWithDefault[0] == 1 && ptrArrayWithDefault[1] == 2
I can simply solve it with
int arrayWithDefault[] = { 1, 2, 3, 4 };
but i was wondering if there is a way to initialize new array in such way?
I would really avoid such a scenario and follow proper practices.
However, I was able to do similar task using
int *ptr = new int[]{1, 2, 3, 4, 5};
and with this way
ptr[0] = 1
.
.
.
ptr[4] = 5

C++ casting static two-dimensional double array to double**

I have such matrix in my program:
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
And I'd like to cast it to double** type.
I've already tried simple double** a = (double**)m;, but it doesn't work (when I try to read any value, I get "Access violation reading location 0x00000000.", which means I'm trying to read from NULL adress.
I found almost working solution:
double *b = &m[0][0];
double **c = &b;
It works when I read field c[0][any]
But same NULL adress reading problem occurs, when I try to read value from field c[1][0].
What is the proper way to cast my double m[3][4] array to type double**?
edit:
You say that's impossible. So I'll change a problem a little bit. How can I pass two-dimensional double array as a parameter to a function? My function has prototype:
void calculate(double **matrix, int n); //where matrix size is always n by n+1
And it's working fine with dynamically-allocated arrays. I doubt that only way to make it work is allocating new dynamical array and copy original static array one element by another...
You can't.
The notation double** refers to an array of pointers. You don't have an array of pointers, you have an array of arrays of doubles.
You can't just cast the array. You are going to have to create something like this:
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
double *marray[3] = {m[0],m[1],m[2]};
calculate(marray,3);
Or you can use a loop:
const size_t n = 3;
double *marray[n];
for (size_t i=0; i!=n; ++i) {
marray[i] = m[i];
}
calculate(marray,n);
When you write
double m[3][4]
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
The compiler actually creates an array of doubles as if you had written
double _m[] = {2, 4, 5, 7, 4, 5, 1, 12, 9, 12, 13, -4};
However, thanks to C/C++ type system, the compiler remembers that m's type
is double [3][4]. In particular it remembers the sizes 3 and 4.
When you write
m[i][j]
the compiler replaces it by
_m[i * 4 + j];
(The 4 comes from the second size in double [3][4].) For instance,
m[1][2] == 1 and _m[1 * 4 + 2] == _m[6] == 1 as well.
As others said, a double** is a different type which doesn't carry the
sizes with it. To consider double** a as a 3 x 4 matrix, a[0], a[1] and
a[2] must be pointers to double (that is, double*) pointing to the
first element of the corresponding row. You can achieve this with
double* rows[] = { &m[0][0], &m[1][0], &m[2][0] };
double** a = &rows[0];
A simple cast doesn't create the variable rows above. Let me present other
alternative (but equivalent) ways to define rows
double* rows[] = { &m[0][0], &m[0][0] + 4, &m[0][0] + 2 * 4};
double* rows[] = { &_m[0], &_m[4], &_m[2 * 4]};
As you can see, only the second size (i.e. 4) is necessary. In general, for
multi-dimensional arrays, all sizes but the first are required. For this
reason a 1-dimensional array
double x[4] = { 1, 2, 3, 4 };
can be implicitly converted to a double*
double* y = x;
Using this fact we can also write
double* rows[] = { _m, _m + 4, _m + 2 * 4};
Indeed, _m is converted to a double* pointing to m[0]. Then, in _m + 4,
_m is is converted to a double* pointing to m[0] and to this pointer
it's added 4. Hence, _m + 4 is a pointer the fourth double following
_m[0], which is _m[4] and so on.
So far I have explained why you cannot cast a double [3][4] (or any other sizes) to a double**. Now, I'shall show, in your particular case, how calculate can be defined.
template <int N>
void calculate(double (&m)[N][N+1]) {
// use m as a double[N][N+1]
}
You call
calculate(m);
and the compiler will deduce the size N for you. In general (i.e, when the second dimension is not the N + 1) you can write
template <int N, int M>
void calculate(double (&m)[N][M]) {
// use m as a double[N][M]
}
If you're always using arrays (no pointers) for initialization, and you are able to avoid the pointer stuff in your calculate function, you might consider the following option, which uses size deduction by templates.
template<int m, int n>
void doubleFunc(double (&mat)[m][n])
{
for (auto i = 0; i < m; i++)
{
for (auto j = 0; j < n; j++)
{
std::cout << mat[i][j] << std::endl;
}
}
}
It worked during my quick test.
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
doubleFunc(m);
You can pass a 2d array as a function parameter:
void calculate(double matrix[][y], int n);
Until variable-length arrays are in the C++ standard, your choices include:
If your compiler supports variable-length arrays as an extension, you can likely pass them with a function declaration such as void foo(std::size_t n, double a[][n+1]). Note that the compiler likely requires n to be passed before a parameter declaration that uses n or requires some special syntax.
You can pass a double * and do index arithmetic manually in the function: void foo(std::size_t n, double *a) { … a[row*(n+1) + column] … }
You can create a class the implements variable-length arrays by doing the index arithmetic in its accessor functions.
You can allocate space for n pointers to double, fill those pointers with pointers to each row of the array, and pass the address of the space.