c++ twodimensional array passed to function - c++

I like to pass a two dimensional array to a function to print it.
Here is my code so far. As you can see on the comment it does not compile, because of an incompatible type.
QUESTION
How can I pass the two dimensional array to printIt ?
If I adjust it to printIt(int a(*)[50][50]) I get the another error during compilation, because returning array is not allowed
using namespace std;
void printIt(int a[50][50]);
int main(int args, char *argv[])
{
int a[50][50];
int j = 0;
for (int i = 1; i < 6; i++)
{
a[i][j] = i;
// the same should be printed out inside printIt
cout << " " << a[i][j];
// not compiling
// argument of type int is incompatible with int(*)[50]
printIt(a[i][j]);
}
}
void printIt( int a[50][50] )
{
cout << " " << a[50][50];
}

Given
int a[50][50];
a[i][j] evaluates to an int.
a[i] evaluates to int [50], an array of 50 integers. If used as an argument to a function call, a[i] decays to a int* in most cases. In rare cases it converts to int (&)[50].
If used as an argument to a function call, a decays to int (*)[50] in most cases. In rare cases it converts to int (&)[50][50].
In your case, the function declaration
void printIt(int a[50][50]);
is equivalent to
void printIt(int a[][50]);
and
void printIt(int (*a)[50]);
Hence, using
printIt(a);
is the right method of calling the function.
However
Given the way you are using the argument in printIt, you probably meant to use:
void printIt(int num)
{
cout << " " << num;
}
After that, it OK to use:
printIt(a[i][j]);
in main.

Because a[i][j] in an integer, it is a value. You are passing a value not an double array Your code should look like that :
#include <iostream>
using namespace std;
void printIt(int a)
{
cout << " " << a;
}
int main(int args, char *argv[])
{
int a[50][50];
int j = 0;
for (int i = 1; i < 6; i++)
{
a[i][j] = i;
// the same should be printed out inside printIt
cout << " " << a[i][j];
// not compiling
// argument of type int is incompatible with int(*)[50]
printIt(a[i][j]);
}
}

Related

error: cannot convert ‘int (*)[4]’ to ‘int**’ | SWAPPING ARRAYS

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

When Declaring a Function in C++, Does It Need to Have the Parameters That the Function Itself Has?

(Please keep in mind I've only recently delved into C++ functions.)
Let's say that you want a function that will count from 1 to a specific number.
#include <iostream>
int countTo(int num);
int countTo(int num) {
for (int i = 1; i <= num; i++) {
std::cout << i << "\n";
}
return num;
}
int main() {
int num;
std::cout << "Enter a number to which the program will count: ";
std::cin >> num;
countTo(num);
return 0;
}
I've put the same code into the compiler, just without the parameters on the function declaration, like so:
int countTo();
int countTo(int num) {
for (int i = 1; i <= num; i++) {
std::cout << i << "\n";
}
return num;
}
And it worked just as well. Do I need to include parameters when declaring int countTo(int num)? Or for any function?
std::cout << "Thanks!!";
There are two different things going on when you write this:
int countTo(int num) {
for (int i = 1; i <= num; i++) {
std::cout<<i<<"\n";
}
return num;
}
You are declaring a function called countTo that takes an int and returns an int, and you are also defining the function.
When you have the line above it saying
int countTo(int num);
you are declaring the same function, but not defining it.
When you changed that line to
int countTo();
you declared a different function (an overload) that takes no parameters. It doesn't matter that you didn't define that function, because no one ever tried to call it.

Pointer to array in function in c++

I am a beginner to c++. Pointer is quite confusing to me. Especially on how to use it in functions and array. I tried to create a pointer to array in function and just output it. However it keeps giving me the address of the array instead of the value.
void testing(int* arr){
cout << arr << endl;
}
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr);
string y;
getline(cin, y);
return 0;
}
I tried using testing(&my_arr); to output value but it give me errors:
argument of type "int (*)[3]" is incompatible with parameter of type
"int *
'void testing(int *)': cannot convert argument 1 from 'int (*)[3]' to 'int *'
Thanks a lot for any help!
To print the values in an array rather than the starting address, you need to use a loop.
#include <iostream>
#include <string>
// note extra param for length of array.
void testing(int* arr, int len){
for (int i = 0; i < len; ++i)
std::cout << arr[i] << " ";
std::cout << "\n";
}
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr, 3);
return 0;
}
You can't pass testing(&my_arr) because &my_arr is of type int (*)[] as per the error message you received. That is not the same as int*.
for printing the arrays, you can either use the array index or pointers arithmetic. The test function could also be written as
void testing(int* arr, int len) {
for (int ctr = 0; ctr < len; ctr++) {
std::cout << *(arr + ctr) << std::endl;
}
}
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr, 3);
return 0;
}
In testing() you are trying to use arr element without its index.
Here arr is the only base memory address of that memory. To get value from there you have to specify index.
void testing(int* arr, int len)
{
for(int i = 0; i < len; i++)
{
cout << arr[i] << endl;
}
}
In main() you can pass a length of an array.
int main()
{
int my_arr[]{ 4,7,1 };
testing(my_arr, sizeof(my_arr) / sizeof(int));
return 0;
}

Two dimensional arrays error [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
#include<iostream>
using namespace std;
double NUMB_COLS = 3;
void readMatrix(int matr[] [3], int numb_rows, int numb_cols)
{
for (int i = 0; i<numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout <<"[" << i << "] [" <<j <<"] =";
cin >> matr[i][j];
}
}
}
void printMatr(int matr[][3], int numb_rows, int numb_cols)
{
for (int i = 0; i < numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout << "[" << i << "][" << j << "] = " << matr[i][j];
}
cout << endl;
}
}
int main()
{
int matr[5][10];
printMatr(matr, 4, 5);
readMatrix(matr, 4, 5);
return 0;
}
The error is
31 23 C:\Users\Windows\Desktop\programs\arrays2.cpp [Error] cannot convert 'int ()[10]' to 'int ()[3]' for argument '1' to 'void readMatrix(int (*)[3], int, int)'
What to do??
The first error is, that you pass a pointer to matr to a function expecting a different array layout. Remember that all ints in matr are consecutive in memory. Even if you did cast your matr to the expected type before passing it to the function, what was at position matr[0][7] in main() will end up in position matr[2][1] inside readMatrix().
The second error is, that your function accepts a column count, even though it already declared the column count to be 3. Such inconsistencies are an ample source of bugs, and should be avoided at all cost. Unfortunately, C++ forbids you to use dynamically sized array types, so you cannot just change your function declaration to
void readMatrix(int numb_rows, int numb_cols, int matr[numb_rows][numb_cols]) {
as you can in C.
The easiest way to fix your problem is probably to use std::vector<>.
You need to specify the correct subscripts.
void readMatrix(int matr[5][10], int numb_rows, int numb_cols)
a std::vector would be a lot easier in this case.
You defined the array in main as
int matr[5][10];
but in the functions the corresponding parameter is defined as
int matr[][3]
They are different types.
If you want to use in the functions only a part of the array int matr[5][10]; that is only 4 first rows and 5 first columns then you have to define the corresponding parameter of the functions the same way as the original array that is as
int matr[][10];
For example
void printMatr(int matr[][10], int numb_rows, int numb_cols)
Or you have to change code in main and write
int matr[5][3];
printMatr(matr, 5, 3);
readMatrix(matr, 5, 3);
Also take into account that you defined variable
double NUMB_COLS = 3;
but do not use it (thogh it should be defined having integral type).
If you would write
const int NUMB_COLS = 3;
and then use it in array definitions there would not be such an error. For example
#include<iostream>
using namespace std;
const int NUMB_COLS = 3;
void readMatrix(int matr[] [NUMB_COLS], int numb_rows, int numb_cols)
{
for (int i = 0; i<numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout <<"[" << i << "] [" <<j <<"] =";
cin >> matr[i][j];
}
}
}
void printMatr(int matr[][NUMB_COLS], int numb_rows, int numb_cols)
{
for (int i = 0; i < numb_rows; i++)
{
for (int j = 0; j < numb_cols; j++)
{
cout << "[" << i << "][" << j << "] = " << matr[i][j];
}
cout << endl;
}
}
int main()
{
int matr[5][NUMB_COLS];
printMatr(matr, 5, NUMB_COLS);
readMatrix(matr, 5, NUMB_COLS);
return 0;
}
You can assign NUMB_COLS any number including 10 used in your original code. The code I showed will not depend on "magic numbers". It uses only named constant NUMB_COLS

c++ two errors while compiling

I'm a beginner in c++ and I'm getting two errors in my code and I don't know how to fix them...
the first one
illegal indirection
and the second one is
'=' left operand must be a I-value. (in the line: ((ArrayPtr +i)+j)=rand()%55+1 )
Does anyone have an idea how to fix them? That's my code:
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 6;
void FillingRandomly(int (*)[AS]);
void printing(int (*)[AS]);
int c;
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
FillingRandomly(Array);
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
printing(Array);
system("PAUSE");
return 0;
}
void FillingRandomly(int *ArrayPtr)
{
for(int i=0;i<AS;i++)
{
for (int j=0;j<AS;j++)
{
*(*(ArrayPtr +i)+j)=rand()%55+1;
}
}
}
void printing(int *Array)
{
for(int i=0;i<AS;i++)
{
for (int j=0;j<AS*AS;j++)
{
int counter = 0;
cout<<((Array[i] +j))<<setw(5);
if ((Array[i] +j)%AS == 0)
cout << endl << endl;
}
}
}
void forsorting(int *Brray, int funny)
{
int dice = 0;
int super = 0;
int space=0;
//Sorting Array[][] which is treated like Array[]
{
for (int pass = 0; pass < AS - 1; pass++) {
for (int k = 0; k < AS - 1; k++) {
int temp;
if(*(Brray+k)==*(Brray+k+1))
{
temp=*(Brray+k);
*(Brray+k)=*(Brray+k+1);
*(Brray+k+1)=temp;
}
}
}
}
}
By
*(*(ArrayPtr +i)+j)=rand()%55+1;
it seems you want
ArrayPtr[i][j] = (rand() % 55) + 1;
You can try something along the line of
int const offset = AS * i + j;
int const elem = (rand() % 55) + 1;
*(ArrayPtr + offset) = elem;
Your function signature is:
void FillingRandomly(int *ArrayPtr)
where you are telling to compiler that you are passing a simple pointer, but in the line:
*(*(ArrayPtr +i)+j)=rand()%55+1;
you are doing a double derreference, which is illegal and causing the compiler to complain
COMPLEMENT
I was seeing the comments in the other answer and, as what I need to write is bigger than the reserved commentary space, I decided to complement my own answer.
You defined Array as:
int Array[AS][AS];
Indeed, what you are doing is a promise to compiler that you will use Array as defined, but the compiler doesn't believe in you too much, so that any time you use Array the compiler will make sure that it is being used as declared.
The problem arises when you declare your FillingRandomly function. Here you are broking your promise and are trying to use Array by declaring a differente type. Note how you declare your function:
void FillingRandomly(int *ArrayPtr)
Due the fact that c++ supports function overloading, the compiler doesn't warn you until it initiate the linking phase, when it is unable to find a function whose signature is:
void FillingRandomly(int ArrayPtr[][AS])
note that both are different.
Once you are a beginner, the best way to keep your programs correctly is to keep your promise immutable. Bellow I show you a piece of your own code, correcting those issues for FillingRandomly function (you have to correct it for the others functions too):
const int AS = 6;
void FillingRandomly(int [][AS]); // Note that I've changed your prototype here
....
void FillingRandomly(int ArrayPtr[][AS]) // Keep your function signature the same as your prototype signature
{
for(int i=0;i<AS;i++)
{
for (int j=0;j<AS;j++)
{
ArrayPtr[i][j]=rand()%55+1; // Note how ArrayPtr is being used exactly as your promised early
}
}
}