Help with type conversion error - c++

When I try to compile my program, I get the following error:
main.cpp: In function ‘int main()’:
main.cpp:67: error: cannot convert ‘int (*)[(((long unsigned int)(((long int)mapSizeY) - 1)) + 1u)]’ to ‘int (*)[10]’ for argument ‘3’ to ‘void initializeMap(int, int, int (*)[10])’
main.cpp:68: error: cannot convert ‘int (*)[(((long unsigned int)(((long int)mapSizeY) - 1)) + 1u)]’ to ‘int (*)[10]’ for argument ‘3’ to ‘void paintMap(int, int, int (*)[10])’
My code looks like this:
#include <iostream>
using namespace std;
void initializeMap(int mapSizeX, int mapSizeY, int map[][10])
{
// Map details:
// 0 = # (wall)
// 1 = space (free space)
// 2 = x (player)
for(int x = 0; x < mapSizeX; x++)
{
map[x][0] = 0;
}
for(int y = 0; y < (mapSizeY - 2); y++)
{
map[0][y] = 0;
for(int x = 0; x < (mapSizeX - 2); x++)
{
map[x][y] = 1;
}
map[mapSizeX][y] = 0;
}
for(int x = 0; x < mapSizeX; x++)
{
map[x][mapSizeY - 1] = 0;
}
}
void paintMap(int mapSizeX, int mapSizeY, int map[][10])
{
for(int y = 0; y < mapSizeY; y++)
{
for(int x = 0; x < mapSizeX; x++)
{
switch(map[x][y])
{
case 0:
cout << "#";
break;
case 1:
cout << " ";
break;
case 2:
cout << "x";
break;
}
cout << map[x][y];
}
cout << endl;
}
}
int main()
{
int mapSizeX = 10;
int mapSizeY = 10;
int map[mapSizeX][mapSizeY];
initializeMap(mapSizeX, mapSizeY, map);
paintMap(mapSizeX, mapSizeY, map);
cout << endl << endl;
return 0;
}
I've spent an hour trying to solve the issue and about twenty minutes searching for a solution. Can any of you help me out?

C++ does not support variable-length arrays, which is what map is in your code. However, some compilers may support it as a non-standard extension. However, it certainly won't be compatible with a function expecting a "standard" array.
If you make mapSizeX and mapSizeY constants, this should work.

Declare mapSizeX and mapSizeY const. Your current code, as is, is basically not wellformed according the C++ language specification which allows only constants as array size specifiers.
The error message is utterly misleading, that's due to the fact that some compiler support this as an extension and the latest C language standard includes it as well.
I tested it here.

Your function calls expect the second dimension to be exactly 10, always. Your code has that dimension in a variable (mapSizeY), which is not guaranteed to be 10, even though you set it a line earlier.
Change mapSizeY to const int so the compiler can optimize it away.

If you make mapSize[X|Y] const in the main method, this should work. Alternatively, as you're passing the dimensions to each of your methods, why not pass the matrix as an int**?

The problem is the variable-length automatic array. One way to fix this is to make the item look the same in main() as it does in initializeMap() and paintMap().
int main()
{
int mapSizeX = 10;
// int mapSizeY = 10;
int map[mapSizeX][10];
initializeMap(mapSizeX, 10, map);
paintMap(mapSizeX, 10, map);
cout << endl << endl;
return 0;
}
One thing I don't suggest is simply declaring MapSize? to be const. Then it looks like the array is variable-length when it really isn't.
You should also be aware that variable-length automatic arrays are a GNU extension to C89 and C++.

Change the definition map[][10] to map[][] or *map in the initializeMap an paintMap functions.

Related

My program displays the result only in case of 1 numera, task: sort out all simple numeras from array

I need to complete the task, meeting the following requirements:
Algorithms for input and output of array elements, as well as for performing a given operation on an array, should be formatted as functions.
When accessing array elements, use a pointer.
In principle, my program should work, but it works only for 1 number, for 2 it already shows some kind of weird, and for 3 or more - nothing at all.
#include <iostream>
#include <stdlib.h>
using namespace std;
void input(int x[], int n);
int spisok(int x[], int n);
int main() {
int n, x[n];
cout << "Vvedite kolichestvo chisel v massive" << endl;
cin >> n;
input(x, n);
spisok(x, n);
for (int i = 0; i < n; i++) {
if (x[i] != 0) {
cout << "Prostiye chisla " << x[i] << ' ';
}
}
return 0;
}
void input(int x[], int n) {
int * p = x;
for (int i = 1; i <= n; i++) {
cout << "Vvedite " << i << "-oe chislo" << endl;
cin >> * p;
p++;
}
}
int spisok(int x[], int n) {
int i = 0;
for (int j = 2; j <= x[i]; j++) {
if (i > n) {
break;
}
if (x[i] % j == 0 && x[i] != j) {
x[i] = 0;
break;
}
i++;
}
return *x;
}
As you actually did not ask a question I take the liberty to interpret it as: How to find the mistake?
Further I am assuming that you use gcc. The answer for different compilers is similar (check their manual).
It might be a bit of a surprise, but as a matter of fact, gcc does not compile standard C++ with its default settings.
Unless you know what you are doing you should at least use the flags:
-pedantic to make it compile the code as standard C++
-Wall to make it report most common warnings
-Werror to report warnings as errors
With that flags your code produces following error message:
<source>: In function 'int main()':
<source>:10:12: error: ISO C++ forbids variable length array 'x' [-Werror=vla]
10 | int n, x[n];
| ^
<source>:10:15: error: 'n' is used uninitialized in this function [-Werror=uninitialized]
10 | int n, x[n];
| ^
cc1plus: all warnings being treated as errors
The first is because array sizes must be compile time constants. See Why aren't variable-length arrays part of the C++ standard? for details and use a std::vector for dynamically sized arrays instead.
The second is because you use n before it is initialized. You read n from user input, but that is after you declare the array in this line int n, x[n];. Code is executed from top to bottom. The value of n doesn't magically travel back in time after read from user input to use the right size for the array.

Vector as an argument in function

I have a code like this:
Forgive me Polish names for stuff, I hope it isn't a problem. I can change them if you wanna.
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
//a few unimportant functions
void zamianaNaDziesietny(int podstawa, int liczba, int reszta[])
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--)
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
void zamianaNaDziesietny(int podstawa, int liczba, int reszta[])
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--) //request for member 'size' in 'reszta', which is of non-class type 'int*'
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
//another unimportant part of code
int main()
{
//unimportant stuff
zamianaZDziesietnego(podstawa, liczba);
zamianaNaDziesietny(podstawa, liczba, reszta);
return 0;
}
I dunno how to use vector 'reszta' as an argument in function "zamiananaDziesietny".
What should I type to let this program compile?
I'm getting 2 errors:
One of them is:
'reszta' was not declared in this scope
It's an array... Oh well, vector is a kind of array... I think... I'm noob so I can always be wrong.
I can work on this vector in main, adding "cout << reszta[0];" (just to write on the screen an element of this vector) in main, just between inductions of those two functions worked well. But I think this problem could be solved by setting this vector in main and then it will be as an argument in zamianaZDziesietnego() function too, but...
I dunno how to use a vector as an argument in function.
The second error I'm getting is:
request for member 'size' in 'reszta', which is of non-class type 'int*'
It's in the 32nd line.
So this is my problem.
I have tried typing this argument in a few different ways.
When I tried with:
void zamianaNaDziesietny(int podstawa, int liczba, vector reszta[])
The second error changed to:
request for member 'size' in 'reszta', which is of pointer type 'std::vector*' (maybe you meant to use '->' ?)|
And also got a new error a few lines below:
no match for 'operator*' in '*(reszta + ((((sizetype)a) + -1u) * 12u)) * pow((double)podstawa, (double)(a + -1))'|
Well, I am very a big noob and I dunno how to solve this. Could anyone help?
Btw, if anyone was interested - I'm making a program that converts binear counts to decimal and vice versa.
Just declare the argument like this:
void zamianaNaDziesietny(int podstawa, int liczba, std::vector<int> reszta)
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--)
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
Or better still, pass the vector by reference to avoid it being copied:
void zamianaNaDziesietny(int podstawa, int liczba, std::vector<int>& reszta)
{
vector < int > cyfra;
cout <<"\n";
for(int a = reszta.size(); a > 0; a--)
{
cyfra.push_back(reszta[a - 1] * pow(podstawa, a - 1));
}
for(int a = 1; a < cyfra.size(); a++)
{
cyfra[0] += cyfra[a];
}
cout << cyfra[0];
}
What you have done is use an int array (int reszta[]) as the argument rather than a vector - they are different types.
Vectors are different than arrays, as vectors are classes and can have methods called upon them (ex. .size(). Arrays are from c which are really just pointers in memory. Passing in the reference as stated would be the best way to pass in the vector, but make sure to be careful about modification.

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
}
}
}

c++ error: invalid types 'int[int]' for array subscript

Trying to learn C++ and working through a simple exercise on arrays.
Basically, I've created a multidimensional array and I want to create a function that prints out the values.
The commented for-loop within Main() works fine, but when I try to turn that for-loop into a function, it doesn't work and for the life of me, I cannot see why.
#include <iostream>
using namespace std;
void printArray(int theArray[], int numberOfRows, int numberOfColumns);
int main()
{
int sally[2][3] = {{2,3,4},{8,9,10}};
printArray(sally,2,3);
// for(int rows = 0; rows < 2; rows++){
// for(int columns = 0; columns < 3; columns++){
// cout << sally[rows][columns] << " ";
// }
// cout << endl;
// }
}
void printArray(int theArray[], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
C++ inherits its syntax from C, and tries hard to maintain backward compatibility where the syntax matches. So passing arrays works just like C: the length information is lost.
However, C++ does provide a way to automatically pass the length information, using a reference (no backward compatibility concerns, C has no references):
template<int numberOfRows, int numberOfColumns>
void printArray(int (&theArray)[numberOfRows][numberOfColumns])
{
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}
Demonstration: http://ideone.com/MrYKz
Here's a variation that avoids the complicated array reference syntax: http://ideone.com/GVkxk
If the size is dynamic, you can't use either template version. You just need to know that C and C++ store array content in row-major order.
Code which works with variable size: http://ideone.com/kjHiR
Since theArray is multidimensional, you should specify the bounds of all its dimensions in the function prototype (except the first one):
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns);
I'm aware of the date of this post, but just for completeness and perhaps for future reference, the following is another solution. Although C++ offers many standard-library facilities (see std::vector or std::array) that makes programmer life easier in cases like this compared to the built-in array intrinsic low-level concepts, if you need anyway to call your printArray like so:
printArray(sally, 2, 3);
you may redefine the function this way:
void printArray(int* theArray, int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x * numberOfColumns + y] << " ";
}
cout << endl;
}
}
In particular, note the first argument and the subscript operation:
the function takes a pointer, so you pass the name of the multidimensional array which also is the address to its first element.
within the subscript operation (theArray[x * numberOfColumns + y]) we access the sequential element thinking about the multidimensional array as an unique row array.
If you pass array as argument you must specify the size of dimensions except for the first dim. Compiler needs those to calculate the offset of each element in the array. Say you may let printArray like
void printArray(int theArray[][3], int numberOfRows, int numberOfColumns){
for(int x = 0; x < numberOfRows; x++){
for(int y = 0; y < numberOfColumns; y++){
cout << theArray[x][y] << " ";
}
cout << endl;
}
}