What is going wrong with my multidimentional array function? - c++

here I have a problem. I want to manipulate the following Matrix
Matrix A =
1---------2----------3
4---------5----------6
7---------8----------9
into
7---------8----------9
4---------5----------6
1---------2----------3
#include<iostream>
using namespace std;
void f(int ArrayName, int Size);
int main()
{
int x[3][3]={{1,2,3}, {4, 5,6},{7,8,9}};
f(x, 3);
system("pause");
}
void f(int ArrayName, int Size)
{
int holder;
for(int i=0; i<Size; i++){
for(int j=0; j<Size; j++)
{
holder=ArrayName[i][j];
ArrayName[i][j]=ArrayName[i+2][j+2];
ArrayName[i+2][j+2]=holder;
}
}
for(int k=0; k<Size; k++)
for(int l=0; l<Size; l++)
{
cout<<ArrayName[k][l];
if(l=3) cout<<"\n";
}
}
Errors:
E:\Semester 2\CPrograms\Array2.cpp In function `int main()':
10 E:\Semester 2\CPrograms\Array2.cpp invalid conversion from `int (*)[3][3]' to `int'
10 E:\Semester 2\CPrograms\Array2.cpp initializing argument 1 of `void f(int, int)'
E:\Semester 2\CPrograms\Array2.cpp In function `void f(int, int)':
22 E:\Semester 2\CPrograms\Array2.cpp invalid types `int[int]' for array subscript
(Last error repeated for five times)

All is done before us.:)
You can do quickly the assignment using standard algorithm std::reverse declared in header <algorithm>
For example
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int a[3][3] =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
for ( const auto &row : a )
{
for ( int x : row ) std::cout << x << ' ';
std::cout << std::endl;
}
std::cout << std::endl;
std::reverse( std::begin( a ), std::end( a ) );
for ( const auto &row : a )
{
for ( int x : row ) std::cout << x << ' ';
std::cout << std::endl;
}
return 0;
}
The program output is
1 2 3
4 5 6
7 8 9
7 8 9
4 5 6
1 2 3
As for your code then already this function declaration
void f(int ArrayName, int Size);
is wrong.
The first parameter should be either a reference to the array or a pointer to its first element.
For example
void f( int ( &ArrayName )[3][3] );
or
void f( int ( *ArrayName )[3], int Size );
If you want to write the function yourself then it can look the following way
#include <iostream>
void reverse( int ( *ArrayName )[3], size_t Size )
{
for ( size_t i = 0; i < Size / 2; i++ )
{
for ( size_t j = 0; j < 3; j++ )
{
int tmp = ArrayName[i][j];
ArrayName[i][j] = ArrayName[Size - i - 1][j];
ArrayName[Size - i - 1][j] = tmp;
}
}
}
int main()
{
int a[3][3] =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
};
for ( const auto &row : a )
{
for ( int x : row ) std::cout << x << ' ';
std::cout << std::endl;
}
std::cout << std::endl;
::reverse( a, 3 );
for ( const auto &row : a )
{
for ( int x : row ) std::cout << x << ' ';
std::cout << std::endl;
}
return 0;
}
The program output will be the same as above.

The prototype and declaration of your function should be :
void f(int ArrayName[][3], int Size)
Modify the code as:
#include<iostream>
using namespace std;
void f(int ArrayName[][3], int Size); //change here
int main()
{
int x[3][3]={{1,2,3}, {4, 5,6},{7,8,9}};
f(x, 3);
system("pause");
}
void f(int ArrayName[][3], int Size) //change here
{
int holder;
for(int i=0; i<Size/2; i++){ //change here
for(int j=0; j<Size; j++)
{
holder=ArrayName[i][j];
ArrayName[i][j]=ArrayName[size-i-1][size-i-1]; //change here
ArrayName[size-i-1][size-i-1]=holder; //change here
}
}

Try the solution in the code below. It uses the matrix as a vector, but has no dimension dependencies in the f() function prototype.
You have some errors in your code:
The array x[][] has to be passed by reference/pointer and not by value, then the function f() has to receive a pointer (or a reference) to int and not an int!
The for-loop scanning the matrix rows doesn't have to be for(int i=0; i<Size; i++), but for(int i=0; i<Size/2; i++). Using i<Size you swaps two times all the rows and then it seems nothing happens!
The following code:
ArrayName[i][j]=ArrayName[i+2][j+2];
ArrayName[i+2][j+2]=holder;
should be:
ArrayName[i][j]=ArrayName[Size-i-1][j];
ArrayName[Size-i-1][j]=holder;
The following code:
if(l=3) cout<<"\n";
l=3 assigns a value, don't do a comparison.
It should be:
if(l==Size-1) cout<<"\n";
#include<iostream>
using namespace std;
void f(int * ArrayName, int Size);
int main()
{
static const int Size=4;
int x[Size][Size];
//Loads the numbes into the matrix
for(int i=0;i<Size;i++)
for(int j=0;j<Size;j++)
x[i][j]=i*Size+j+1;
f(&x[0][0], Size);
}
void f(int *ArrayName, int Size)
{
int holder;
cout << "Input\n";
for(int k=0; k<Size; k++) {
for(int l=0; l<Size; l++)
cout<<ArrayName[k*Size+l]<<" ";
cout << "\n";
}
// Elaborate the matrix
// ----------------------------------------
for(int i=0; i<Size / 2; i++){
for(int j=0; j<Size; j++) {
holder=ArrayName[i*Size+j];
ArrayName[i*Size+j]=ArrayName[(Size-i-1)*Size+j];
ArrayName[(Size-i-1)*Size+j]=holder;
}
}
// ----------------------------------------
cout << "----------\n" << "Output\n";
for(int k=0; k<Size; k++) {
for(int l=0; l<Size; l++)
cout<<ArrayName[k*Size+l]<<" ";
cout << "\n";
}
}

Related

Argument of type int(*)[] is incompatible with parameter of type "int**"

I was creating a function that would give me random values of a matrix. I know how to make it in the main function but I want a separate one. I also tried with void and the same thing happened, and I keep getting the same error. I am beginner and I understand that the issue is something to do with pointers but I still don't know what should I do to make it work and fix it. I already Googled it but I can't make this work.
#include<stdlib.h>
#include<iostream>
#include<time.h>
int row, coll;
int random(int *mat[])
{
srand(time(0));
for(int i=0; i<row; i++)
{
for(int j=0; j<coll; j++)
{
mat[i][j] = rand()%10;
}
}
}
main()
{
std::cin >> row >> coll;
int mat[row][coll];
random(mat);
}
You are trying to mix features of two different languages in one program.
The presented program is not a valid C++ program nor a valid C program.
For example variable length arrays as in your program
std::cin >> row >> coll;
int mat[row][coll];
is not a standard C++ feature.
The function main shall have the return type int.
Your function random
int random(int *mat[])
has the return type int but returns nothing.
The argument has the type (if to assume that variable length arrays are supported)
int ( * )[coll]
but the function parameter type is
int **.
If you are going to write a C++ program then instead of a variable length array use the standard container std::vector<std::vector<int>>.
For example
std::cin >> row >> coll;
std::vector<std::vector<int>> mat( row, std::vector<int>( coll ) );
Otherwise write a C program that can look like
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void random( size_t row, size_t col, int mat[row][col], int limit )
{
srand( ( unsigned int )time( NULL ) );
for ( size_t i = 0; i < row; i++ )
{
for ( size_t j = 0; j < col; j++ )
{
mat[i][j] = rand() % limit;
}
}
}
int main( void )
{
size_t row, col;
scanf( "%zu %zu", &row, &col );
int mat[row][col];
random( row, col, mat, 10 );
return 0;
}
I wrote a simple struct of matrix for you to carry the data around functions. Also, a output overload to make it easier to demo. Please look over it, and don't hesitate to ask, if you need more elaborations.
#include<stdlib.h>
#include<iostream>
#include<time.h>
#include <iomanip>
struct Matrix
{
int *arr;
const int row, col;
Matrix() = delete;
Matrix(const int i, const int j): row(i), col(j)
{
arr = new int [i*j];
}
~Matrix() { delete [] arr; }
int operator()(const int i, const int j) const {return arr[i*col+j];}
int&operator()(const int i, const int j) {return arr[i*col+j];}
};
std::ostream& operator<<(std::ostream&osm, const Matrix&M)
{
for (int i=0; i<M.row; i++) {
for (int j=0; j< M.col; j++) osm << std::setw(8) << M(i,j);
osm << std::endl;
}
return osm;
}
void random(Matrix& amtx)
{
srand(time(0));
for(int i=0; i<amtx.row; i++)
{
for(int j=0; j<amtx.col; j++)
{
amtx(i,j) = rand()%10;
}
}
}
int main()
{
int r, c;
std::cout << "Input row and column : ";
std::cin >> r >> c;
Matrix mtx(r, c);
random(mtx);
std::cout << mtx;
return 0;
}
and the test run:
Input row and column : 5 5
6 3 1 9 3
6 5 1 4 1
1 2 7 5 5
9 3 2 8 1
7 4 8 3 5

Unresolved external symbol error when compiling [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
when ever am trying to compile it, i get an error message
unresolved external symbol "void __cdecl showarray(int * const,int)"
am not sure what i am doing wrong? what should I do, my code looks like this
#include<iostream>
#include<string>
using namespace std;
void sortArray(int [], int );
void showarray(int [],int );
int main(){
int endtime[10] = { 70, 38, 8, 101, 11, 127, 313, 14, 16, 127 };
cout << "unsorted" << endl;
showarray(endtime, 10);
sortArray(endtime, 10);
cout << "the sorted value are :" << endl;
showarray(endtime, 10);
return 0;
}
void sortArray(int array[], int size){
bool swap;
int temp;
do{
swap = false;
for (int count = 0; count < (size - 1); count++){
if (array[count] > array[count+1]){
temp = array[count];
array[count] = array[count + 1];
array[count + 1] = temp;
swap = true;
}
}
} while (swap);
}
void showarray(const float array[], int size){
for (int i = 0; i < size; i++)
cout << array[i] <<" "<< endl;
}
At first you declared function
void showarray(int [],int );
but defined function
void showarray(const float array[], int size)
{
//...
}
Change the both declaration and the definition like
void showArray( const int [], int );
^^^^^^^^^ ^^^^^^^^^^^^
For example (the function definition)
void showArray( const int array[], int size )
{
for ( int i = 0; i < size; i++ )
{
cout << array[i] << ' ';
}
cout << endl;
}
And do not forget to change function calls using name showArray.
Take into account that the variable temp should be declared inside the if statement. Also you could use standard function std::swap as for example
std::swap( array[count], array[count+1] );
The program can look like
#include <iostream>
void sortArray( int a[], size_t n )
{
while ( !( n < 2 ) )
{
size_t last = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[i] < a[i-1] )
{
int temp = a[i];
a[i] = a[i-1];
a[i-1] = temp;
last = i;
}
}
n = last;
}
}
void showArray( const int a[], size_t n )
{
for ( size_t i = 0; i < n; i++ ) std::cout << a[i] << ' ';
std::cout << std::endl;
}
int main()
{
const size_t N = 10;
int endtime[N] = { 70, 38, 8, 101, 11, 127, 313, 14, 16, 127 };
std::cout << "unsorted: ";
showArray( endtime, N );
sortArray( endtime, N );
std::cout << " sorted: ";
showArray( endtime, N );
}
Its output is
unsorted: 70 38 8 101 11 127 313 14 16 127
sorted: 8 11 14 16 38 70 101 127 127 313
With using standard function std::swap the function sortArray can be more compact and clear
void sortArray( int a[], size_t n )
{
while ( not ( n < 2 ) )
{
size_t last = 0;
for ( size_t i = 1; i < n; i++ )
{
if ( a[i] < a[i-1] )
{
std::swap( a[i], a[i-1] );
last = i;
}
}
n = last;
}
}
You are declaring a
void showarray(int [],int );
but defining a
void showarray(const float array[], int size)
Both are not the same. At the point the compiler tries to compile the function call, he only knows about the first one and uses this. But the linker can only find the second one, which is why he produces an error.
Your function declaration needs to match your function definition:
void showarray(int [],int );
And
void showarray(const float array[], int size){
for (int i = 0; i < size; i++)
cout << array[i] <<" "<< endl;
}
Need to have matching function signatures.

C++: Pass two-dimensional array to function

This is probably so simple, but I can't figure out why this won't compile.
void display(int);
const int rows = 2;
const int cols = 2;
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
void display(const int ray[][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
invalid conversion from ‘int (*)[2]’ to ‘int’ [-fpermissive]|
This code will work
const int rows = 2;
const int cols = 2;
void display( const int ray[][cols]);
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
void display( const int ray[][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
Your function definition and function declaration do not match, one of them is of type int while the other is type void
Your function declaration is
void display(int);
and the definition is
int display(const int ray[0][cols])
and
int display(const int ray[0][cols])
^
0 ?
I think I see the problem here
The prototype is wrong. If you want a 2D array arg, it's more like this
int display(const int ray**);
The forward declaration of display is wrong. Either fix forward declaration or change order of functions:
#include <iostream>
using namespace std;
const int rows = 2;
const int cols = 2;
int display(const int ray[0][cols]){
for(int i = 0; i < 2; i ++){
for(int j = 0; j < 2; j ++){
cout << ray[i][j] << endl;
}
}
}
int main()
{
int ray[rows][cols] = {{1,2 },
{3,4}};
display(ray);
return 0;
}
Live Example
Since you use global variables anyway, the easy thing is to change your declaration of display:
Declare display like this:
void display(int** array)
{...}
In this case you will actually be able to send your 2D array to the function because the type will match. A 2D array is an array of arrays and an array is just a pointer associated with some memory.
I am not giving the appropriate answer to this question. But an alternative.
As C++ suggests to use std::string inplace of char* . It also suggests to use vectors instead of array wherever applicable.
#include <iostream>
#include <vector>
void display( std::vector<std::vector<int>> );
int main()
{
std::vector<std::vector<int>> int_vec{ { 1 , 2 } , { 3 , 4 } };
display( int_vec );
system("PAUSE");
return EXIT_SUCCESS;
}
void display( std::vector<std::vector<int>> integer_vector )
{
for( auto& i : integer_vector )
{
for( auto& j : i )
{
std::cout << j << std::endl;
}
}
}
The global variables as rows and cols are gone :).

C++ Passing Dynamic Pointer to a 2D Array

This is an extension to a previous question I previously asked. I can use a template to submit a dynamic 2D array and access the elements. Now, let's say I have a pointer to such an array. I am currently using the method shown here to assign my pointer to the original 2d array. I initially thought I could just change the expected input of the template function to (*A)[M][N] but that's a no-go. Am I missing some concept regarding pointers that someone could kindly explain?
header.h
#pragma once
#include <cstddef>
#include <iostream>
using namespace std;
template<size_t N, size_t M>
void printPtr( int(*A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
main.cpp
#include "header.h"
#include <iostream>
using namespace std;
int main() {
int A[][3] = {
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
};
int (*ptrA)[3] = A;
printPtr(ptrA);
}
If you're not interested in knowing why your code isn't working in the first place just skip to the end of this post
The problem with your code is that you're "simulating" an array decaying by passing your pointer along:
int A[][2] = {
{1,2,3},
{4,5,6},
{7,8,9},
{10,11,12}
};
int (*ptrA)[3] = A;
This is confirmed by the following code which uses C++11 features:
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T, typename U>
struct decay_equiv :
std::is_same<typename std::decay<T>::type, U>::type
{};
int main() {
int A[][4] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 }
};
std::cout << std::boolalpha
<< decay_equiv<decltype(A), int(*)[3]>::value << '\n'; // Prints "true"
}
Example
You should either pass a non-decayed type (i.e. a type that has all the information regarding the array dimension) to the function via a pointer or a reference:
#include <cstddef>
#include <iostream>
using namespace std;
template<size_t N, size_t M>
void printPtr(int (*A)[M][N] /* Also a reference could work */) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << (*A)[i][j] << " ";
}
cout << endl;
}
}
int main() {
int A[][6] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 }
};
int(*ptrA)[4][7] = &A; // Not a decayed type
printPtr(ptrA);
}
Example
Another solution would be to not use a pointer to the array in the first place or dereference it when passing a reference to the array:
template<size_t N, size_t M>
void printPtr( int(&A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
...
printPtr(A);
printPtr(*ptrA);
Example
You defined the function parameter as a pointer to a two-dimensional array
int(*A)[M][N])
while are trying to call the function passing as the argument a pointer to a one-dimensional array
int (*ptrA)[3] = A;
printPtr(ptrA);
Moreover the function itself is invalid. It shall look like
template<size_t N, size_t M>
void printPtr( int(*A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << ( *A )[i][j] << " ";
}
cout << endl;
}
}
that is you have to use expression ( *A )[i][j] instead of A[i][j]
So you need to change the function the way shown above and to use appropriate pointer as the argument
int (*ptrA)[4][3] = &A;
printPtr(ptrA);
Of course it would be better to define the function parameter as reference to a two-dimensional array. For example
template<size_t N, size_t M>
void printPtr( int(&A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
In this case you could call the function like
printPtr( A );
It should be
template<size_t N, size_t M>
void printPtr(const int(&A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << A[i][j] << " ";
}
cout << endl;
}
}
calling with:
printPtr(A);
or
template<size_t N, size_t M>
void printPtr(const int(*A)[M][N]) {
for(int i=0; i < M; i++){
for(int j=0; j<N; j++) {
cout << (*A)[i][j] << " ";
}
cout << endl;
}
}
calling with:
printPtr(&A);
BTW your pointer should be:
int (*ptrA)[4][3] = &A;

Why this Selection sort code in Cpp, not giving required Output

#include<iostream>
using namespace std;
int min_arr(int arr[],int size);
void swap(int *,int *);
int main()
{
int arr[10]={31,2,55,3,77,12,89,98,43,34},loc;
int* arr1;
arr1 = &arr[0];
for(int i=0;i<10;i++)
{
for( int j=i;j<9;j++)
{
loc = min_arr(arr1,(10-i));
swap(&arr[loc],&arr[i]);
arr1++;
}
}
for(int i =0; i<10;i++)
cout<<arr[i]<<endl;
return 0;
}
int min_arr(int arr[],int size)
{
int k=0;
int temp=arr[0];
for(int i=1;i<size;i++)
{
if(arr[i]<temp)
{
temp=arr[i];
k=i;
}
}
return k;
}
void swap(int *a, int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
Why this Selection sort code in Cpp, not giving required Output? Kindly find the flaw! I have taken two functions to find min of the sub arrays as we procede. And as i find the min, i return its index and swap the first position of the sub array and minimum valued element!
After rearranging the code and adding some debug lines, it's pretty easy to find out what's wrong:
Firstly, the second loop (j loop) is completely pointless
Secondly loc variable is not 0-based but i-based (as you searched over arr1, which is incremented by the loop), so arr[loc] should be arr[loc+i]
Corrected, smartly indented (that's important to make tour code easily readable) code:
#include<iostream>
#define ARRAY_SIZE 10
using namespace std;
int min_arr(int arr[],int size);
void swap(int *,int *);
int main()
{
int arr[ARRAY_SIZE]={31,2,55,3,77,12,89,98,43,34},loc;
int* arr1;
arr1 = &arr[0];
for( int i = 0; i < ARRAY_SIZE; i++ )
{
//for( int j = i; j<ARRAY_SIZE-1; j++ )
{
loc = min_arr(arr1,(ARRAY_SIZE-i));
// for debug:
//std::cout << "min found at " << loc << std::endl;
swap(&arr[loc+i],&arr[i]);
// for debug:
//for( int i =0; i<ARRAY_SIZE; i++ )
// cout << arr[i] << " ";
//cout << std::endl;
arr1++;
}
}
for( int i =0; i<ARRAY_SIZE; i++ )
cout<<arr[i]<<endl;
return 0;
}
int min_arr( int arr[], int size )
{
int k=0;
int temp=arr[0];
for( int i=1; i<size; i++ )
{
if( arr[i] < temp )
{
temp=arr[i];
k=i;
}
}
return k;
}
void swap(int *a, int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
It will output:
2
3
12
31
34
43
55
77
89
98
In your version you just go with pointers beyond the area mapped for the array.
First of all, call of the function min_arr. It requires array, not pointer:
loc=min_arr(arr,(10-i));
Second, the function itself. You always start from the beginning of the array, that's why already sorted elements go resorted.
int min_arr(int arr[],int size)
{
int k=10-size;
int temp=arr[k];
for(int i=k+1;i<10;i++)
{
if(arr[i]<temp)
{
temp=arr[i];
k=i;
}
}
return k;
}
for(int i=0;i<10;i++)
{
for( int j=i;j<9;j++) //shouldn't this be j < 10 ?
......