Using bool function for matching sums in C++ - c++

I've written this program that's supposed to solve a wheel with numbers from 1 to 11 and I'm having trouble with figuring out what's causing this Linker error. I believe I have everything else working fine in the code body except for this Boolean function that uses an integer array, but the error that comes up says the following. I'm not sure what I've done wrong with the function. I've declared it using a prototype in the beginning of the code, I call the function using its proper name and calling the array correctly. Could someone please help me figure out what's wrong with the code?
undefined reference to 'matchingSums(int)' … relocation truncated to fit: R_X86_64_PC32 against undefined symbol
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <time.h>
using namespace std;
const int MAX_CIRCLES = 11;
const int CENTER_CIRCLE_INDEX = 10;
bool matchingSums(int);
void fillTheWheel(int []);
void displayWheelContents(int []);
void randomizeTheContents(int, int []);
int nbrOfItems, firstSum, nextSum;
int main(void)
{
srand(time(NULL));
int wheel[MAX_CIRCLES];
int numInt = 0;
fillTheWheel(wheel);
while (!matchingSums(*wheel))
{
numInt++;
randomizeTheContents(MAX_CIRCLES, wheel);
}
cout << "After " << numInt << " unsuccessful attempts, the following solution was found:" << endl;
displayWheelContents(wheel);
}
void fillTheWheel(int wheel[])
{
for (int fillTheWheelIndex = 0; fillTheWheelIndex < MAX_CIRCLES; fillTheWheelIndex++)
{
wheel[fillTheWheelIndex] = (fillTheWheelIndex + 1);
}
}
void displayWheelContents(int wheel[])
{
cout << "* Outside circles (clockwise from the top):" << endl << " " << endl;
for (int wheelIndex = 0; wheelIndex < MAX_CIRCLES; wheelIndex++)
{
// Print each value in a column width of 4 as shown in the example-program-execution.txt file
cout << setw(4) << wheel[wheelIndex] << " ";
}
cout << " " << endl << " " << endl << "*Center circle: " << wheel[CENTER_CIRCLE_INDEX] << endl;
}
void randomizeTheContents(int nbrOfItems, int table[])
{
for (int indexA = 0; indexA < nbrOfItems; indexA++)
{
int indexB = rand() % nbrOfItems;
int temp = table[indexA];
table[indexA] = table[indexB];
table[indexB] = temp;
}
}
bool matchingSums(int wheel[])
{
const int MAX_OUTER_CIRCLES = MAX_CIRCLES - 1;
const int OPPOSITE_SIDE_FACTOR = 5;
const int STARTING_INDEX = 0;
int firstSum;
int nextSum;
// Calculate the sum of the first pair of numbers
firstSum = wheel[STARTING_INDEX] + wheel[CENTER_CIRCLE_INDEX]
+ wheel[STARTING_INDEX + OPPOSITE_SIDE_FACTOR];
// Compare the first sum to each of the sums of the other pairs
for (int i = 1; i < MAX_OUTER_CIRCLES/2; i++)
{
nextSum = wheel[i] + wheel[CENTER_CIRCLE_INDEX] + wheel[i + OPPOSITE_SIDE_FACTOR];
if (firstSum != nextSum)
return false;
} // End for
return true;
} // End matchingSums

Initially the function is declared with a parameter of the type int like
bool matchingSums(int);
And called with an argument of the type int in main
while (!matchingSums(*wheel))
But in its definition it is declared with a parameter of the type int [] that is implicitly adjusted by the compiler to the type int * like
bool matchingSums(int wheel[])
So the compiler issues an error because it did not find the definition of the function declared like
bool matchingSums(int);

The argument of matchingsums is of int type but the definition of the matchingSums function accepts int wheel[], an integer type of unsized array.
You must have overlooked this, since the function fillTheWheel accepts the same type of argument but was declared and defined just fine.
Replace the prototype
bool matchingSums(int) to bool matchingSums(int []).

Related

Pass by references?

In the code below, I do not understand the difference between the two versions. In both cases, I make a passage by reference, it seems to me (I think).
Moreover, I do not understand why version 2 works, because for what I understand for the moment, the sign & allows me to give the address of a variable, so when I put function_name(int &yourInt) I technically ask the user to enter the address of an int? So I should call it like function_name(&myInt)? But here we call the function like function_name(myInt) instead.
Version 1 :
int value(int tab[], int *valeur)
{
for (int i = 0; i < 5; i++)
{
*valeur += tab[i];
}
return *valeur;
}
int main()
{
int test = 0;
int tab[10] = { 1,2,3,4,5};
std::cout << value(tab, &test) << std::endl;
std::cout << test;
}
Version 2 :
int value(int tab[], int &valeur)
{
for (int i = 0; i < 5; i++)
{
valeur += tab[i];
}
return valeur;
}
int main()
{
int test = 0;
int tab[10] = { 1,2,3,4,5};
std::cout << value(tab, test) << std::endl;
std::cout << test;
}
When the & character is part of a type declaration, it means that variable is a reference to another. So in the second function, int &valeur declares a variable named valeur that is a reference to an int. This example should help you understand:
#include <iostream>
int main() {
int a = 5;
int& b = a; // b is a reference to a
std::cout << a << '\n'; // outputs 5
std::cout << b << '\n'; // outputs 5
a = 7;
std::cout << a << '\n'; // outputs 7
std::cout << b << '\n'; // outputs 7
}
As a result, you can simply call your second function with value(tab, test) which passes the test variable by reference.
In the first example, value takes a pointer to int as second parameter. A pointer is used to save a memory address, so the function has to be called using the address operator (&), passing the address of test.
In the second example, value takes a non-const reference to int as second parameter, so you do not need to pass the memory address of test this time. What happens is almost equivalent to something like this:
int test = 0;
int& valeur = test;
So remember, the address operator:
int test;
std::cout << &test; // outputs address of "test" in memory
is not the same as a reference, which is part of the type of a variable:
int test;
int& valeur = test; // here, the type of "valeur" is "int&"

Cannot convert - C++ - std::string__cxxll:string

#include <iostream>
#include <limits>
#include <string>
using namespace std;
void wczytajOsobe(string imie[], string nazwisko[], int wiek[])
{
int i=2;
for(int indeks=0;i>indeks;indeks++)
{
cout << "Podaj Imie: " << endl;
getline(cin, imie[indeks]);
cout << "Podaj Naziwsko: " << endl;
getline(cin, nazwisko[indeks]);
}
}
void wypiszOsobe(string imie[], string nazwisko[], int wiek[])
{
int i=2;
for(int indeks=0;i>indeks;indeks++)
{
cout << imie[indeks];
cout << nazwisko[indeks];
cout << wiek[indeks];
}
}
int main()
{
string imie[2];
string nazwisko[2];
int wiek[2];
for( int i = 0; i < 2; i++ )
wczytajOsobe(imie[i], nazwisko[i], wiek[i]);
for( int i = 0; i < 2; i++ )
wypiszOsobe(imie[ i ], nazwisko[ i ], wiek[ i ] );
system("PAUSE");
return 0;
}
This is my code and i have problem with|36|error: cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string}' to 'std::__cxx11::string* {aka std::__cxx11::basic_string}' for argument '1' to 'void wczytajOsobe(std::__cxx11::string, std::__cxx11::string*, int*)'|
can somebody help me with that issue ?
You have two functions defined as:
void wczytajOsobe(string imie[], string nazwisko[], int wiek[]);
void wypiszOsobe(string imie[], string nazwisko[], int wiek[]);
Because arrays decay to pointers when passed to functions, the parameter types are actually:
void wczytajOsobe(string *imie, string *nazwisko, int *wiek);
void wypiszOsobe(string *imie, string *nazwisko, int *wiek);
When you call the functions like:
for( int i = 0; i < 2; i++ )
wczytajOsobe(imie[i], nazwisko[i], wiek[i]);
You're not passing arrays but individual array elements. That's why the error message says it can't convert std::string to std::string*.
You don't need those loops in main(). You can just call the functions as:
int main()
{
string imie[2];
string nazwisko[2];
int wiek[2];
wczytajOsobe(imie, nazwisko, wiek);
wypiszOsobe(imie, nazwisko, wiek);
system("PAUSE");
return 0;
}
Note that I'm just passing the arrays to the functions.

This pointer and suqare bracket overload

I have a problem when accessing the overflowed square bracket in a public method of my class. Here is the code:
#include <iostream>
#include <cassert>
#include <cmath>
using namespace std;
template<unsigned int DIM> class Vector
{
private:
double mData[DIM];
public:
Vector(double tableau[DIM])
{
for(int i=0; i<DIM; i++)
{
mData[i] = tableau[i];
}
}
double operator[](int index)
{
assert(index < DIM);
assert(index > -1);
assert(-pow(10,-6)<=mData[index]<=1+pow(10,-6));
if(mData[index]>=0 && mData[index]<=1)
{
return mData[index];
}
else if(mData[index]<0 && mData[index]>=pow(10,-6))
{
return 0.0;
}
else if(mData[index]>1 && mData[index]<= 1+ pow(10,-6))
{
return 1.0;
}
}
double getDim() const
{
return DIM;
}
void print() const
{
for(int i=0;i<getDim();i++)
{
cout << this[i] << " "; //PROBLEM!!
}
}
};
int main()
{
double err=pow(10,-6);
double tableau[5];
tableau[0] = 0.5;
tableau[1] = 0.79;
tableau[2] = err;
tableau[3] = 1+err;
tableau[4] = 0;
Vector<5> proba(tableau);
proba.print();
}
I have tried with *this, this->, but anything appeared to work.
I hope you could help me.
Florent
Member operator overloads require a value or reference of the class type, and this is a pointer. So you either need to dereference the this pointer prior to using the operator, like this:
(*this)[i]
Or you can call the operator directly, which has the advantage of being totally explicit in its intent, but has the disadvantage of being a bit wordy and a bit more obscure (and therefore more likely to trip up anyone who reads it):
this->operator[](i)
If you have already tried *this[i] and found that it doesn't fix the problem, that's because it actually means *(this[i])!
Apart from wrong implementation of operator[], there is wrong use of it:-
cout << this[i] << " ";
This should be
cout << (*this)[i] << " "; //is you want to implement that way...
this is just a pointer, so to access operator[] you can either dereference it first:
cout << (*this)[i] << " ";
Or call the function directly (not preferred):
cout << this->operator[](i) << " ";

C++ Array passig parameters

I'm new in C++
I try to pass array as parameters I can't find a solution.
Here's my code :
My Header code
autobus.h
#ifndef autobus_H
#define autobus_H
#include <iostream>
using namespace std;
class autobus{
public :
int placeautobus[2] [40];
autobus();
void affichageTicket();
int calculdesplaces(int, int);
};
#endif
Bus.cpp
#include <iostream>
#include "autobus.h"
autobus::autobus(){
int i,j;
for (i=0;i<2;i++) {
for (j=0;j<40;j++)
placeautobus[i][j] = 0;
}
};
void autobus::affichageTicket()
{
}
int autobus::calculdesplaces(int typeautobus, int *placeautobus[2][40]){
int placenumero;
for (int place = 0; place < 40; place++){
if ( placeautobus[typeautobus][place] ==0) {
placenumero = place+1;
cout <<"Places : "<< placenumero <<endl;
}
}
return placenumero;
}
finally my main.cpp
#include <cstdlib>
#include <iostream>
#include "autobus.h"
using namespace std;
int main()
{
int TypeAutobus;
autobus *choixautobus = new autobus();
cout << "1 for smoking bus" << endl;
cout << "2 for non-smoking bus" << endl;
cin >> TypeAutobus;
choixautobus->calculdesplaces(TypeAutobus, choixautobus->placeautobus[2][40]);
system("PAUSE");
return EXIT_SUCCESS;
}
Everything works, but when I add this line in my main.cpp :
choixautobus->calculdesplaces(TypeAutobus, choixautobus->placeautobus[2][40]);
I have an error, I try many things.
I just want to call my function calculdesplaces with the variable : choixautobus having array placeautobus.
Can someone know how to do this.
thanks
Like others have said already, the code you have now shouldn't compile right now because of the declaration and definition mismatch for calculdesplaces.
You shouldn't need to pass the placeautobus array at all since it is a member of the autobus class. Just delete your 2nd argument from calculdesplaces and you should be able to do what you want.
int autobus::calculdesplaces(int typeautobus){
int placenumero;
for (int place = 0; place < 40; place++){
if ( placeautobus[typeautobus][place] ==0) {
placenumero = place+1;
cout <<"Places : "<< placenumero <<endl;
}
}
return placenumero;
}
In your class declaration, you need to specify the correct array pointer type for the second parameter of calculdesplaces():
class autobus{
public :
autobus();
void affichageTicket();
int calculdesplaces(int typeautobus, int (*placeautobus)[40]);
int placeautobus[2][40];
};
This declares, that you are passing a pointer to an array of 40 int elements. This is precisely the type to which the 2D array int placeautobus[2][40]; decays when you use its name: When you mention the name of an array, the array name decays into a pointer to its first element. In the case of an array of type int ()[2][40], that is a pointer to the first line array (type is int (*)[40]).
Note that the parentheses in int (*placeautobus)[40] are very important: the array subscript operator [] has a higher precedence than the dereferencing operator *, so int (*placeautobus)[40] means something very different from int* placeautobus[40].
I have also taken the liberty of including the variable names in the method declaration, this provides essential information to the reader, even though the compiler ignores it.
In the implementation of calculdesplaces(), you can access the argument array precisely the same way as you can access any 2D array:
int autobus::calculdesplaces(int typeautobus, int (*placeautobus)[40]) {
int placenumero;
for (int place = 0; place < 40; place++) {
if ( placeautobus[typeautobus][place] ==0) {
placenumero = place+1;
cout <<"Places : "<< placenumero <<endl;
}
}
return placenumero;
}
Now you can easily call your function by just passing the array:
int main() {
int TypeAutobus;
autobus *choixautobus = new autobus();
cout << "1 for smoking bus" << endl;
cout << "2 for non-smoking bus" << endl;
cin >> TypeAutobus;
choixautobus->calculdesplaces(TypeAutobus, choixautobus->placeautobus);
system("PAUSE");
return EXIT_SUCCESS;
}
Note:
The above only fixes the symptoms, not the disease. The actual problem is, that the design of the class itself is flawed. Data members should generally not be public, and methods should work on the data of the object on which they are called, instead of relying on getting parts of the object passed in via additional arguments. So, the class definition should look like this:
class autobus{
public :
autobus();
void affichageTicket();
int calculdesplaces(int typeautobus);
private:
int placeautobus[2][40];
};
The definition of calculdesplaces() doesn't change that much, it just does not shadow the already available array member with a function argument:
int autobus::calculdesplaces(int typeautobus) {
int placenumero;
for (int place = 0; place < 40; place++) {
if ( placeautobus[typeautobus][place] ==0) {
placenumero = place+1;
cout <<"Places : "<< placenumero <<endl;
}
}
return placenumero;
}
And you don't need to "grab into the object" in main(), the array is implicitly passed via the this pointer:
int main() {
int TypeAutobus;
autobus *choixautobus = new autobus();
cout << "1 for smoking bus" << endl;
cout << "2 for non-smoking bus" << endl;
cin >> TypeAutobus;
choixautobus->calculdesplaces(TypeAutobus);
system("PAUSE");
return EXIT_SUCCESS;
}
You haven't mentioned what the error it. But I think this it the issue:
What is the data type of second argument in calculdesplaces function declaration:
int calculdesplaces(int, int);
It is: int
What is the data type of placeautobus[2][40] in calculdesplaces function definition:
int autobus::calculdesplaces(int typeautobus, int *placeautobus[2][40]){ ... }
It is: int*
What is the data type of placeautobus[2][40] in calculdesplaces function call:
choixautobus->calculdesplaces(TypeAutobus, choixautobus->placeautobus[2][40]);
Looking at class autobus { ... }, it is: int
So there is mismatch between the datatype used in function declaration, definition and call. Try solving this.
The code should not be compiled.
The member function declaration of calculdesplaces
int calculdesplaces(int, int);
does not coinside with its definition
int autobus::calculdesplaces(int typeautobus, int *placeautobus[2][40]){
The type of the second parameter differs.
As for the error message then the function should be called as
choixautobus->calculdesplaces( TypeAutobus, choixautobus->placeautobus );
Take into account that the function has a bug. You pass to the function as the first argument either 1 or 2 and use these values as indices of the array while the valid indices are 0 and 1.
Also the function does not need to have the second parameter because it deals with the data member
int placeautobus[2] [40];
So I would define the class and member functions the following way
class autobus{
public :
int placeautobus[2] [40];
autobus();
void affichageTicket();
int calculdesplaces(int);
};
#include <iostream>
#include "autobus.h"
autobus::autobus() : placeautobus {}
{
}
void autobus::affichageTicket()
{
}
int autobus::calculdesplaces( int typeautobus )
{
int placenumero = 0;
for (int place = 0; place < 40; place++)
{
if ( placeautobus[typeautobus - 1][place] == 0 )
{
placenumero = place+1;
cout <<"Places : "<< placenumero <<endl;
break;
}
}
return placenumero;
}
Though I do not understand what you return from the function.:)
Also you could specify the initialization of the array inside the class definition
class autobus{
public :
int placeautobus[2] [40] = {};
//...
In this case the main can look as
int main()
{
int TypeAutobus;
autobus *choixautobus = new autobus();
cout << "1 for smoking bus" << endl;
cout << "2 for non-smoking bus" << endl;
cin >> TypeAutobus;
choixautobus->calculdesplaces( TypeAutobus );
system("PAUSE");
return EXIT_SUCCESS;
}

cyclic negative number generation in C++

I have requirement as follows.
I have to generate increment negative numbers from -1 to -100 which is used a unique id for a request. Like it should be like this: -1, -2, -3, ...-100, -1, -2, and so on. How can I do this effectively? I am not supposed to use Boost. C++ STL is fine. I prefer to write simple function like int GetNextID() and it should generate ID. Request sample program on how to do this effectively?
Thanks for your time and help
int ID = -1;
auto getnext = [=] mutable {
if (ID == -100) ID = -1;
return ID--;
};
Fairly basic stuff here, really. If you have to ask somebody on the Interwebs to write this program for you, you should really consider finding some educational material in C++.
I love the functor solution:
template <int limit> class NegativeNumber
{
public:
NegativeNumber() : current(0) {};
int operator()()
{
return -(1 + (current++ % limit));
};
private:
int current;
};
Then, you can define any generator with any limit and use it:
NegativeNumber<5> five;
NegativeNumber<2> two;
for (int x = 0; x < 20; ++x)
std::cout << "limit five: " << five() << "\tlimit two: " << two() << '\n';
You can also pass the generator as parameter to another function, with each funtor with its own state:
void f5(NegativeNumber<5> &n)
{
std::cout << "limit five: " << n() << '\n';
}
void f2(NegativeNumber<2> &n)
{
std::cout << "limit two: " << n() << '\n';
}
f5(five);
f2(two);
If you don't like the template solution to declare the limit, there's also the no-template version:
class NegativeNumberNoTemplate
{
public:
NegativeNumberNoTemplate(int limit) : m_limit(limit), current(0) {};
int operator()()
{
return -(1 + (current++ % m_limit));
};
private:
const int m_limit;
int current;
};
Using as argument to a function works in the same way, and it's internal state is transfered as well:
void f(NegativeNumberNoTemplate &n)
{
std::cout << "no template: " << n() << '\n';
}
NegativeNumberNoTemplate notemplate(3);
f(notemplate);
I hope you don't want to use it with threading, they're not thread safe ;)
Here you have all the examples; hope it helps.
Something like.... (haven't compiled)
class myClass
{
int number = 0;
int GetValue ()
{
return - (number = ((number+1) % 101))
}
}
Even a simple problem like this could lead you to several approximations, both in the algorithmic solution and in the concrete usage of the programming language.
This was my first solution using C++03. I preferred to switch the sign after computing the value.
#include <iostream>
int GetNextID() {
// This variable is private to this function. Be careful of not calling it
// from multiple threads!
static int current_value = 0;
const int MAX_CYCLE_VALUE = 100;
return - (current_value++ % MAX_CYCLE_VALUE) - 1;
}
int main()
{
const int TOTAL_GETS = 500;
for (int i = 0; i < TOTAL_GETS; ++i)
std::cout << GetNextID() << std::endl;
}
A different solution taking into account that the integer modulo in C++ takes the sign of the dividend (!) as commented in the Wikipedia
#include <iostream>
int GetNextID() {
// This variable is private to this function. Be careful of not calling it
// from multiple threads!
static int current_value = 0;
const int MAX_CYCLE_VALUE = 10;
return (current_value-- % MAX_CYCLE_VALUE) - 1;
}
int main()
{
const int TOTAL_GETS = 50;
for (int i = 0; i < TOTAL_GETS; ++i)
std::cout << GetNextID() << std::endl;
}