int M=7;
int N=6;
int i=0;
int x=N*M;
int val3[x] = {};
for(int i=0;i<x;i++)
{
//some calculations
if (my condition)
{
//if this condition ok, change value of val[i]
}
cout << i << " " << val[i] << endl;
}
I want to initialize a zero array(val), I used above codes, but I got an error which says variable size object may not be initialized. is it not possible to initialize zero array? need your help....thanks
C++ does not include variable-length arrays; int val3[ x ] with x non-constant is a feature of C99. Not all C99 features are part of C++. Try using std::vector.
#include <vector>
// contains an array of length x, automatically filled with zeroes
std::vector< int > val3( x );
int val3[x] = {};
C++ doesn't allow arrays to be initialized with a variable that isn't a compile-time constant. Use a const int for all the variables (except i).
Btw, you don't use that first int i (outside the loop).
Alternatively to the std::vector suggested above, you could also do:
int M=7;
int N=6;
int x=N*M;
int* val3 = new int[x];
memset(val3, 0, x * sizeof (int));
for (int i = 0; i < x; i++)
{
// ...
}
// ...
delete [] val3;
Related
I am trying to write a function that swap two arrays in O(1) time complexity. However, when i try to write the function parameters, I get the error:
error: cannot convert ‘int (*)[4]’ to ‘int**’
Here is my code:
#include <iostream>
using namespace std;
void swap_array_by_ptr(int* a[], int* b[]) {
int* temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int fr[] = {1,2,3,4};
int rv[] = {4,3,2,1};
swap_array_by_ptr(&fr, &rv);
for (int i = 0; i < 4 ; i++) {
cout << fr[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << rv[i] << " ";
}
}
However, when i tried to define the arrays with 'new' command, this works as expected as below:
#include <iostream>
using namespace std;
void swap_array_by_ptr(int** a, int** b) {
int* temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int fr = new int[4]{1,2,3,4};
int rv = new int[4]{4,3,2,1};
swap_array_by_ptr(&fr, &rv);
for (int i = 0; i < 4 ; i++) {
cout << fr[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << rv[i] << " ";
}
}
Is there any way that i can define the arrays with [] method and swap the arrays by sending these arrays with '&array' method ?
As I believe, there must be a way to do that, I only achieve this when I'm trying to do with 'new' method. However, is there any way to swap two arrays in O(1) complexity with sending parameters as
swap_array_by_ptr(&fr, &rv);
?
Thanks for help.
You can not swap two arrays with O( 1 ). You need to swap each pairs of corresponding elements of two arrays.
In the first program
int fr[] = {1,2,3,4};
int rv[] = {4,3,2,1};
swap_array_by_ptr(&fr, &rv);
the expressions &fr and &rv have type int( * )[4] while the corresponding function parameters in fact has the type int **
void swap_array_by_ptr(int* a[], int* b[]) {
after adjusting the parameters having array types to pointers to the array element types by the compiler.
So the compiler issues an error.
You could use standard function std::swap declared in the header <utility> the following way
std::swap( fr, rv );
But in any case its complexity is O( n ).
In the second program there are at least typos. Instead of
int fr = new int[4]{1,2,3,4};
int rv = new int[4]{4,3,2,1};
you have to write
int *fr = new int[4]{1,2,3,4};
int *rv = new int[4]{4,3,2,1};
In this case you are not swapping arrays themselves. That is the arrays will still store their initial values. You are swapping pointers that point to the dynamically allocated arrays.
To be sure that arrays are not swapped consider the following demonstration program.
#include <iostream>
using namespace std;
void swap_array_by_ptr(int** a, int** b) {
int* temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int fr[] = { 1,2,3,4};
int rv[] = {4,3,2,1};
int *p1 = fr;
int *p2 = rv;
swap_array_by_ptr( &p1, &p2 );
for (int i = 0; i < 4 ; i++) {
cout << p1[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << p2[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << fr[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << rv[i] << " ";
}
cout << endl;
}
It is a syntactic quirk inherited from C that a declaration of a function parameter as an array is automatically converted to a declaration as a corresponding pointer. This is not as odd as it might first seem, however, because it dovetails with the automatic conversion of function arguments of array type to corresponding pointers, also inherited from C.*
Thus, this declaration ...
void swap_array_by_ptr(int* a[], int* b[]) {
... is equivalent to this one:
void swap_array_by_ptr(int **a, int **b) {
. But the arguments you are passing do not match. This, for example,
int fr[] = {1,2,3,4};
declares fr as an array of 4 int. If it were passed as a function argument, it would be automatically converted to a pointer to the first element, thus of type int *. Types int * and int ** are not compatible.
On the other hand, what you actually try to pass, &fr is the address of an array 4 int, of type int(*)[4]. This also is incompatible with int **, because arrays are not pointers.
You could write your function like this:
void swap_array_by_ptr(int (*a)[4], int (*b)[4]) {
int temp[4];
memcpy(temp, a, sizeof(a));
memcpy(a, b, sizeof(b));
memcpy(b, temp, sizeof(temp));
}
That would be compatible with the call in your code. Do note, however, that that is specific to array size 4, and you're not really gaining anything useful from that. You could, however, convert it to a template:
template<class T, std::size_t n>
void swap_array(T (*a)[n], T (*b)[n]) {
T temp[n];
memcpy(temp, a, sizeof(a));
memcpy(a, b, sizeof(b));
memcpy(b, temp, sizeof(temp));
}
That handles arrays of any element type and size,** as long as the sizes match. Of course, it scales as O(N) with array size, in both time and auxiliary space.
Such time scaling is unavoidable. To swap two objects you need to read each at least once and write each at least once, and that requires time proportional to the size of the objects. But you could reduce the space overhead to O(1) by swapping the arrays element by element in a loop. That would very likely be slower, but the time complexity would still be O(N).
Of course, you can also use std::swap() on arrays. It is quite similar to the template above, but uses references to the arrays instead of pointers to them.
*This is a specific case of a much more general behavior.
**So long as the temporary array does not turn out to be too large for the stack.
Change the swap_array_by_ptr function from 'swap_array_by_ptr(int** a, int** b)'
to 'swap_array_by_ptr(int* a, int* b)'.
void swap_array_by_ptr(int* a, int* b) {
int* temp = *a;
*a = *b;
*b = temp;
}
here's a link to a similar question: Swapping 2 arrays in C
class Solution {
public:
int numSquares(int n) {
int dp[n+1];
for(int i=0;i<=n;i++) dp[i]=0; //initializing all the elements to zero
for(int i=1;i<=n;i++){
int t = INT_MAX;
for(int j=1;j<=(int)sqrt(i);j++){
t = min(t,dp[i-j*j]);
}
dp[i] = t+1;
}
return dp[n];
}
};
The above method works perfectly fine but when I tried to initialize the array like this
int dp[n] = {0} //variable sized array cannot be initialized
I am getting error like variable sized array cannot be initialized .
Is there any why to initialize this array instead of using for loop and please explain me why I am getting this error?.
The problem is that in C++, the size of an array must be a compile time constant. So,
int n = 10;
int arr[n] ; //incorrect
The correct way would be:
const int n = 10;
int arr[n]; //correct
You can solve your problem by using:
const int n = 10;
int arr[n] = {0}; //correct now because n is a constant expression
Some more examples:
void func(int n)
{
int arr[n] = {0}; //incorrect because n is passed as a function argument and is therefore not a compile time constant
}
Another example
int n;
cin >> n;
int arr[n] = {0}; //incorrect
You can use std::vector as it is a dynamic sized container.
what are all the different ways to initialize a c++ array?
They are:
default initialisation (which means "no initialisation" in case of trivial objects)
list initialisation
value initialisation (which is list initialisation with an empty list)
why I am getting this error?.
Your program is ill-formed. The size of an array variable must be compile time constant, but n+1 is not.
You are using a language extension. As the error message implies, the language extension doesn't allow all forms of initialisation to be used. You can use default initialisation i.e. "no" initialisation as you did in the first code example.
but what if you are getting the array size as a parameter in a function in class?
Then create a dynamic array. I recommend using std::vector.
what are all the different ways to initialize a c++ array?
That's described here: Aggregate initialization.
The main problem is that VLA:s (variable length arrays) do not exist in standard C++ so instead of int dp[n+1]; you should use std::vector<int> dp(n+1);
Example:
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
class Solution {
public:
int numSquares(int n) {
std::vector<int> dp(n + 1); // instead of `int dp[n+1];`
// for(int i=0;i<=n;i++) dp[i]=0; // no need
for(int i = 1; i <= n; i++) {
int t = INT_MAX;
for(int j = 1, end = (int) std::sqrt(i); j <= end; ++j) {
t = std::min(t, dp[i - j * j]);
}
dp[i] = t + 1;
}
return dp[n];
}
};
Here I'm trying to user c++11 range base loop for tow integer arrays. one declared using new keyword and other not.
#include <iostream>
#include <stdlib.h>
#define ARRAY_LENGTH 100
int main()
{
int* heap_array = new int[ARRAY_LENGTH];
int stack_aray[ARRAY_LENGTH];
for(int i=0; i < ARRAY_LENGTH; i++)
{
int val = (rand() % ARRAY_LENGTH) + 1;
heap_array[i] = val;
stack_array[i] = val;
}
for(int& i : stack_array){ std::cout << i << std::endl;}
for(int& i : *heap_array){ std::cout << i << std::endl;} // compile error
delete[] heap_array;
return 0;
}
Why range base loop doesn't work for the array declared with new keyword? my view is it doesn't matter heap or stack both are heap_array & stack_array are pointers to the first element.
Your heap_array isn't really an array but a raw pointer to an int. A raw pointer does not know anything about the number of elements allocated.
i'm willing to write a code to create an array with a changeable index(meaning having a static array in a function and adding values to it and then getting out of the loop and coming back again and adding another value to the end of it)
but my code doesn't compile:
#include <iostream>
#include <conio.h>
using namespace std;
void arrarr(int);
int main()
{
for (int i = 1; i < 5; i++)
{
arrarr(i);
}
_getch();
return 0;
}
void arrarr(int y)
{
static int x[y];
x[y] = 5;
cout << x[y];
}
Variables can not have variable size. You have to define explicitly the size of the array x, for example: static int x[5].
Also, arrays are zero-indexed, meaning the first element starts at 0. So your loop condition should be for (int i = 0; i < 5; i++)
C++ doesn't support variable length array, you need to define constant size for the static array x. You can do something like:
void arrarr(int y)
{
static int x[SOME_CONSTANT_SIZE]; //SOME_CONSTANT_SIZE known at compile time
x[y] = 5; //y < SOME_CONSTANT_SIZE
cout << x[y];
}
And as #Bruno pointed out, array indices start from 0 to (size-1)
If you are looking to dynamically increase the size of your array, you cannot do that. Use a vector instead. See here: http://www.cplusplus.com/reference/vector/vector/resize/
Your code doesn't compile because of this:
static int x[y];
The compiler doesn't know what x is, e.g.
int [0]
int [1]
int [2]
So you can do
void arrarr(int y) {
static int x[10];
x[y] = 5;
cout << x[y];
}
but what you were doing won't work.
If you share what the expected output is, we might be able to help you more.
In my code I input the sizes of both dimensions and then declare a two-dimensional array. My question is, how do I use that array as a function parameter? I know that I need to write the number of columns in the function specification but how do I pass the number of columns?
void gameDisplay(gameCell p[][int &col],int a,int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i][j].getStat()==closed)cout<<"C ";
if(p[i][j].getStat()==secure)cout<<"S ";
if(p[i][j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i][j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i][j].getNum()==0)cout<<"0 ";
else cout<<p[i][j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[][col],row,col);
}
I tried this way but it doesn't work.
Thank you.
In C++, you cannot have variable length arrays. That is, you can't take an input integer and use it as the size of an array, like so:
std::cin >> x;
int array[x];
(This will work in gcc but it is a non-portable extension)
But of course, it is possible to do something similar. The language feature that allows you to have dynamically sized arrays is dynamic allocation with new[]. You can do this:
std::cin >> x;
int* array = new int[x];
But note, array here is not an array type. It is a pointer type. If you want to dynamically allocate a two dimensional array, you have to do something like so:
std::cin >> x >> y;
int** array = new int*[x]; // First allocate an array of pointers
for (int i = 0; i < x; i++) {
array[i] = new int[y]; // Allocate each row of the 2D array
}
But again, this is still not an array type. It is now an int**, or a "pointer to pointer to int". If you want to pass this to a function, you will need the argument of the function to be int**. For example:
void func(int**);
func(array);
That will be fine. However, you almost always need to know the dimensions of the array inside the function. How can you do that? Just pass them as extra arguments!
void func(int**, int, int);
func(array, x, y);
This is of course one way to do it, but it's certainly not the idiomatic C++ way to do it. It has problems with safety, because its very easy to forget to delete everything. You have to manually manage the memory allocation. You will have to do this to avoid a memory leak:
for (int i = 0; i < x; i++) {
delete[] array[i];
}
delete[] array;
So forget everything I just told you. Make use of the standard library containers. You can easily use std::vector and have no concern for passing the dimensions:
void func(std::vector<std::vector<int>>);
std::cin >> x >> y;
std::vector<std::vector<int>> vec(x, std::vector<int>(y));
func(vec);
If you do end up dealing with array types instead of dynamically allocating your arrays, then you can get the dimensions of your array by defining a template function that takes a reference to an array:
template <int N, int M>
void func(int (&array)[N][M]);
The function will be instantiated for all different sizes of array that are passed to it. The template parameters (dimensions of the array) must be known at compile time.
I made a little program:
#include <iostream>
using namespace std;
void fun(int tab[][6], int first)
{}
int main(int argc, char *argv[])
{
int tab[5][6];
fun(tab, 5);
return 0;
}
In function definition you must put size of second index. Number of column is passed as argument.
I'm guessing from Problems with 'int' that you have followed the advices of the validated question and that you are using std::vector
Here is a function that returns the number of columns of an "array" (and 0 if there is a problem).
int num_column(const std::vector<std::vector<int> > & data){
if(data.size() == 0){
std::cout << "There is no row" << std::endl;
return 0;
}
int first_col_size = data[0].size();
for(auto row : data) {
if(row.size() != first_col_size){
std::cout << "All the columns don't have the same size" << std::endl;
return 0;
}
}
return first_col_size;
}
If you're using C-style arrays, you might want to make a reference in the parameter:
int (&array)[2][2]; // reference to 2-dimensional array
is this what you're looking for?
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
example . . .
#include <iostream>
#include <stdio.h>
int* generate2DArray(int rowSize, int colSize);
int random(int min, int max);
int main()
{
using namespace std;
int row, col;
cout << "Enter row, then colums:";
cin >> row >> col;
//fill array and display
int *ptr = generate2DArray(row, col);
for(int i=0; i<row; ++i)
for(int j=0; j<col; ++j)
{
ptr[i,j] = random(-50,50);
printf("[%i][%i]: %i\n", i, j, ptr[i,j]);
}
return 0;
}
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
int random(int min, int max)
{
return (rand() % (max+1)) + min;
}
instead of accessing p[i][j] you should access p[i*b + j] - this is actually what the compiler do for you since int[a][b] is flattened in the memory to an array in size of a*b
Also, you can change the prototype of the function to "void gameDisplay(gameCell p[],int a,int b)"
The fixed code:
void gameDisplay(gameCell p[],int a, int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i*a +j].getStat()==closed)cout<<"C ";
if(p[i*a +j].getStat()==secure)cout<<"S ";
if(p[i*a +j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i*a +j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i*a +j].getNum()==0)cout<<"0 ";
else cout<<p[i*a +j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[],row,col);
}