I have a problem passing a pointer to a function. Here is the code.
#include <iostream>
using namespace std;
int age = 14;
int weight = 66;
int SetAge(int &rAge);
int SetWeight(int *pWeight);
int main()
{
int &rAge = age;
int *pWeight = &weight;
cout << "I am " << rAge << " years old." << endl;
cout << "And I am " << *pWeight << " kg." << endl;
cout << "Next year I will be " << SetAge(rAge) << " years old." << endl;
cout << "And after a big meal I will be " << SetWeight(*pWeight);
cout << " kg." << endl;
return 0;
}
int SetAge(int &rAge)
{
rAge++;
return rAge;
}
int SetWeight(int *pWeight)
{
*pWeight++;
return *pWeight;
}
My compiler outputs this:
|| C:\Users\Ivan\Desktop\Exercise01.cpp: In function 'int main()':
Exercise01.cpp|20 col 65 error| invalid conversion from 'int' to 'int*' [-fpermissive]
|| cout << "And after a big meal I will be " << SetWeight(*pWeight);
|| ^
Exercise01.cpp|9 col 5 error| initializing argument 1 of 'int SetWeight(int*)' [-fpermissive]
|| int SetWeight(int *pWeight);
|| ^
PS: In real life I wouldnt use this but I got into it and I wanna get it working this way.
You shouldn't dereference the pointer. It should be:
cout << "And after a big meal I will be " << SetWeight(pWeight);
Also, in SetWeight(), you are incrementing the pointer instead of incrementing the value, it should be:
int SetWeight(int *pWeight)
{
(*pWeight)++;
return *pWeight;
}
int *pWeight = &weight;
This declares pWeight as a pointer to an int. SetWeight actually takes a pointer to an int, so you can just pass pWeight straight in without any other qualifiers:
cout << "And after a big meal I will be " << SetWeight(pWeight);
First I took your feedback and changed:
cout << "And after a big meal I will be " << SetWeight(*pWeight);
// to
cout << "And after a big meal I will be " << SetWeight(pWeight);
// But after that I changed also:
*pWeight++;
// to
*pWeight += 1;
The * symbol can have two different meanings in C++. When used in a function header, they indicate that the variable being passed is a pointer. When used elsewhere in front of a pointer it indicates that to which the pointer is pointing. It seems you may have confused these.
Related
I recently started C++, moving from JavaScript, so I'm a little bit confused.
I'm trying to make a number guessing game, and my actual error is something like:
main.cpp:14:67: error: invalid operands of types ‘const char*’ and ‘const char [2]’ to binary ‘operator+’
cout << "Perfect, now your playing with numbers up to " + range + "."
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
$ g++ main.cpp
main.cpp: In function ‘int main()’:
main.cpp:14:67: error: invalid operands of types ‘const char*’ and ‘const char [2]’ to binary ‘operator+’
cout << "Perfect, now your playing with numbers up to " + range + "."
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
I have no idea if it helps, but I'm going to attach my code below:
#include <iostream>
using namespace std;
void startGame(int random);
int generateNo(int range);
int main() {
int range;
cout << "WELCOME TO NUMBER GUESSING GAME!" << endl;
cout << "The calculator is going to generate a random number and you'll have to guess it!" << endl;
cout << "Please enter the range of numbers you want to play (ex: 10)" << endl;
cin >> range;
int solution = generateNo(range);
cout << "Perfect, now your playing with numbers up to " + range + "."
cout << "GOOD LUCK :)" << endl;
startGame(solution);
return 0;
}
int generateNo(int range) {
return rand() % range + 1;
}
void startGame(int random) {
int inputNo;
cin >> inputNo;
for( int a = 0; ; a++) {
if(inputNo == random) {
cout << "Congrats! You've guessed the number!" << endl;
break;
} else if(inputNo > random) {
cout << "Hooolly! WHAT'S with this giant number" << endl;
startGame(random);
break;
} else {
cout << "Good number, but had your little brain considered to make it bigger!?" << endl;
startGame(random);
break;
}
}
}
You can chain calls to <<:
cout << "Perfect, now your playing with numbers up to " << range << ".";
If you want to first build a string (no reason to do that here), you first need to build a string:
std::string text = std::string{"Perfect, now ..."} + std::to_string(range) + ".";
std::cout << text;
In your code you are trying to add a string literal (type is char[N]) with an integer. There is no operator+ to concatenate an integer to a string literal.
C++ doesn't overload the + operator between all the arbitrary types, and doesn't implicitly convert everything to strings when you try to print it out. Luckily, for all the built-in types, you could just write them to the output stream using the << operator (and override it for your own types):
cout << "Perfect, now your playing with numbers up to "
<< range // Note the use of "<<" and not of "+"
<< "."
<< "GOOD LUCK :)"
<< endl;
This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 4 years ago.
I know how to pass 1D array pointer to a function by the following code
void fiddleWithArray(int*);
int main(){
int list[10] = {1, 3, 5, 7, 9, 11, 13, 17};
cout << "List at 0 before being passed is... " << list[0][0] << endl;
cout << "List at 1 before being passed is... " << list[1][0] << endl;
fiddleWithArray(list);
cout << "List at 0 after being passed is... " << list[0][0] << endl;
cout << "List at 1 after being passed is... " << list[1][0] << endl;
}
void fiddleWithArray(int* input){
input[0] = 45;
input[1] = 18;
}
However, when I try to do something similar for a 2D array(as shown below) I get an error.
void fiddleWithArray (int** input);
int main ()
{
int list [10][2]={{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int ** pointer;
pointer=&list;
cout<< "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(pointer);
cout<< "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout<< "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
void fiddleWithArray(int** input)
{
cout << input [6][1]<< endl;
}
The compiler gives an error saying "error: cannot convert ‘int (*)[10][2]’ to ‘int**’ in assignment
pointer=&list;"
I am also open to alternate methods of passing a 2D array pointer to a function.
Keeping your data structure, if you want to pass list to fiddleWithArray you can declare it as
void fiddleWithArray (int input[][2]);
and then, in the main program, call it as
fiddleWithArray(list);
There is also another problem in your program: cout << list[0] does not work. If you want to print the contents of the array when the first index is fixed to 0 you would write something like
cout << list[0][0] << " " << list[0][1]
If you instead intended to write the array where the second index is fixed to 0 or 1, then, to keep things easily, you need a short loop like
for (unsigned int i = 0; i < 10; i++)
cout << list[i][0] << " ";
cout << endl;
Finally, instead of using int[][] you may want to use std::arrayintroduced in C++11.
void fiddleWithArray(int input[10][2])
{
cout << input[6][1] << endl;
}
int main()
{
int list[10][2] = {{1,3},{5,7},{9,11},{13,17},{7,4},{5,90},{9,1},{3,25}};
int (*pointer)[10][2];
pointer=&list;
cout << "List at 0 before being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 before being passed is ... "<< list[1][0]<< endl;
fiddleWithArray(*pointer);
cout << "List at 0 after being passed is ... "<< list[0][0]<< endl;
cout << "List at 1 after being passed is ... "<< list[1][0]<< endl;
}
Will be better using std::array
I'm just learning about function pointers in C++. The following examples do all compile and return the expected result, but I was taught that example 3 was the way to go. Why do the other examples still work?
There is another thing that seemed strange are the examples f,g,h,i which in contrast to the the examples above do not all work. Why don't they work, comparing to the examples 1-8?
int executeOperator1(int a, int b, int f(int,int)){
return f(a,b);
}
int executeOperator2(int a, int b, int f(int,int)){
return (*f)(a,b);
}
int executeOperator3(int a, int b, int (*f)(int,int)){
return f(a,b);
}
int executeOperator4(int a, int b, int (*f)(int,int)){
return (*f)(a,b);
}
int op(int x, int y){
return x+y;
}
int main(int argc, char *argv[])
{
int a = 2, b=3;
//the following 8 examples compile nicely:
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,op) <<endl; //1
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,op) <<endl; //2
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,op) <<endl; //3
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,op) <<endl; //4
cout << "a=" << a << " b=" << b << " res=" << executeOperator1(a,b,&op) <<endl; //5
cout << "a=" << a << " b=" << b << " res=" << executeOperator2(a,b,&op) <<endl; //6
cout << "a=" << a << " b=" << b << " res=" << executeOperator3(a,b,&op) <<endl; //7
cout << "a=" << a << " b=" << b << " res=" << executeOperator4(a,b,&op) <<endl; //8
//int f(int,int) = op; //does not compile
int (*g)(int,int) = op; //does compile
//int h(int,int) = &op; //does not compile
int (*i)(int,int) = &op;//does compile
return 0;
}
All your examples work because of wonderful so-called pointer decay rule. A function name decays to a pointer to function in almost all contexts. (Decay here means that original type information is lost, and all what is left is the pointer. Arrays do decay to pointers too in certain contexts).
So all your examples are semantically the same thing, and I would not call any of them preferred.
And just for the fun of it, this would compile too:
int executeOperator_insane(int a, int b, int f(int,int)){
return (***************f)(a,b);
}
Function, like arrays when passed as an argument to a function, decays into a pointer. For eg: A function taking two int parameters and returning an int would have a type of int (*) (int, int). But you can pass the function as reference as well, in which case you would have a type of int (&) (int, int).
To declare a value of type of above function pointer you would simply write :
typedef int (*FuncType) (int, int);
FuncType myFunc = op;
// OR
FuncType myFunc = &op;
The second way is usually preffered as it is more clear, but most of the compilers let the user do away with the first style.
Would recommend to go through below link:
http://en.cppreference.com/w/cpp/language/pointer#Pointers_to_functions
When you use:
int f(int,int);
in main (or any place that is not an argument to a function), it declares f to be a function, not a pointer to a function. Hence, you cannot use
int f(int,int) = op;
On the other hand,
int (*g)(int,int) = op;
declares g to be a pointer to a function. Hence, it works.
When int f(int,int) is used as an argument to a function, it is equivalent to sing int (*f)(int, int).
I am getting an error saying the operand "<<" (right before times3(x) in the main function ) does not match the operand types being outputted in that line. What am I doing wrong? I searched for errors similar to it and found that its an inclusion error but i thought having would fix it. Also, countdown(seconds) in the main function is not being recognized and giving me an error. Why is that? The problems keep occurring when working with void.
'
#include <iostream>
#include <string>
#include <cstdlib>
#include <limits>
using namespace std;
bool die(const string & msg);
double triple(double x);
double times9(double x);
void triple(double & result, double x);
void times3(double & x);
void countdown(unsigned seconds);
bool restore();
int main(){
double x;
cout << "x: " << endl;
cin >> x;
cout << "The triple of " << x << " is " << triple(x) << endl;
cout << "9 times of " << x << " is " << times9(x) << endl;
cout << "3 times of " << x << " is " << times3(x) << endl;
unsigned seconds;
cout << "seconds: " << endl;
cin >> seconds;
cout << countdown(seconds) << endl;
}
bool die(const string & msg){
cout << "Fatal error: " << msg << endl;
exit(EXIT_FAILURE);
}
double triple(double x){
return 3 * x;
}
double times9(double x){
return 3 * triple(x);
}
void triple(double & result, double x){
x = 3 * x;
}
void times3(double & x){
x = triple(x);
}
void countdown(unsigned & seconds){
unsigned count = seconds;
cin >> seconds || die("input failure");
for (unsigned i = seconds; i <= size; i--){
cout << i << endl;
}
cout << "Blast off! " << endl;
}
bool resotre(){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
return cin.good();
}'
As mentioned in earlier answer, you need to change the return type of your function from void to the data type of variable your trying to print.
Another issue in your code is with function void countdown(unsigned & seconds)
Declaration and definition of the functions are different.
You have declared it as void countdown(unsigned seconds); but at the time of defining it you are using void countdown(unsigned & seconds). In declaration you are declaring it to take arguments by value but in definition you are making it to take arguments by reference.
Also in the for loop of the function countdown you have written
for (unsigned i = seconds; i <= 0; i--), this won't print any output, since your condition is i<=0, i think you tried to type i >= 0. :)
times3 returns void. Try:
times3(x);
cout << "3 times of " << x << " is " << x << endl;
Or have times3() return double instead of passing by reference.
double times3(double x);
problem with const in C++...
MyVektor[i].getName().getFirstName() generates error: (see code below)
Error 1 error C2662: 'Name::getFirstName' : cannot convert 'this' pointer from 'const Name' to 'Name &' c:\users\betula\documents\visual studio 2012\projects\c++laboration_2\c++laboration_2\person_test.cpp 215 1 C++Laboration_2
and
3 IntelliSense: the object has type qualifiers that are not compatible with the member function
object type is: const Name c:\Users\Betula\Documents\Visual Studio 2012\Projects\C++Laboration_2\C++Laboration_2\Person_Test.cpp 215 17 C++Laboration_2
Vector and Method call from main in PersonTest...
vector<Person> MyPersons;
ShowPerson(MyVektor);
Method:
void ShowPerson(vector<Person> &MyVektor)
{
cout << endl << " List of people: " << endl << endl;
for( size_t i = 0; i < MyVektor.size(); i++)
{
cout << " " + MyVektor[i].getName().getFirstName() + " " + MyVektor[i].getName().getLastName() << endl;
//cout << " " + MyVektor[i].getAddress() + " " + MyVektor[i].getAddress()+ " " + MyVektor[i].getAddress() << endl;
cout <<" Social security number: " + MyVektor[i].getPersNr() << endl;
cout <<" Shoe size: " + to_string(MyVektor[i].getSkoNr()) << endl << endl;
}
}
all Getmethods are declare const i there class Person & Name
const Name Person::getName()
{
return my_name;
}
const string Name::getFirstName()
{
return firstName;
}
if i remove const declare in Class Person & Name everything works...
Any suggestions for a beginner...
/ Nimos
Replace const Name Person::getName() with Name Person::getName() const etc. to make the functions constant as opposed to the return variable.