C++ function about usage of return - c++

Hello i am totally new to c++ programming, I had a question when we use a int function why do we have to use return command like we can use cout << sum << endl; and call the function in main(). but for return we have to do like cout << printSum();
Case 1:
#include <iostream>
using namespace std;
int addNumbers(int x, int y){
int sum = x + y;
cout << sum << endl;
}
int main() {
addNumbers(4, 5);
return 0;
}// without using return
Case 2:
#include <iostream>
using namespace std;
int addNumbers(int x, int y){
int sum = x + y;
return sum;
}
int main() {
cout << addNumbers(4, 5) << endl;
return 0;
}// return method

return statement is seemingly very basic, but in fact, one of the most puzzling aspects of procedural programming for freshman students in our local university.
What are the functions anyway?
Functions are the building blocks of procedural and functional programming languages. You might think of a function as of reusable, maintainable block of code responsible for some action. If you perform some operations often together, you might want to "pack" them inside a function. A "good" function is a little machine that takes some input data and gives back processed data.
In C++ you can "share" the results of the processing with "outside code" by returning a value, modifying a parameter (worse) or modifying the global state (worst).
In simple case, "returning" functions are direct analogs of math functions like y = f(x) (even the call syntax is very similar). As a programmer you just define what is x, what is y and how exactly f maps x to y.
Printing vs returning
Now, the printing into console (terminal) and returning are not the same. In simple words, printing is just showing the user some characters on the screen ("speaking with user"). Returning from function allows to receive the result from function ("speaking with outside code"), but it's invisible for the user unless you print it afterwards .
Different function layouts you may encounter while learning
(does not pretend to be an exhaustive list)
So, in your class or tutorial sometimes they teach you how to
(1) print an object directly within main()
int main() {
int i = 42 + 13;
std::cout << i << std::endl;
}
(2) print an object inside a function
void printSum(int a, int b) {
int i = a + b;
std::cout << i << std::endl;
}
int main() {
printSum(42, 13);
}
(3) return an object from the function and printing afterward
void sum(int a, int b) {
return a + b;
}
int main() {
int s = sum(42, 13);
std::cout << s << std::endl;
}
Obviously, (1) is not reusable at all: to change parameters you must intervene into the program logic. Also, if logic is something more than just a sum, main() function will grow quickly in size and become unmaintainable. Responsibilities will be scattered across the code, violating Single responsibility principle
(2) is better in all aspects: function encapsulates logic in a separate place in code, has distinctive name, can be changed separately from main function. Function can be called with different values, and changing arguments doesn't change the function.
But it still has 2 responsibilities: perform the calculation and output to the screen. What if you want not to print the result, but write it to a file? or send it via network? or just discard it? You will need to write another function. The logic inside this new function will be the same, thus introducing duplication and violating DRY principle. Also, (2) is not a pure function because it is modifying std::cout which is basically the global state (we say that this function has "side effects").
Also, you can think about (2) as if it was (1), but with whole program logic moved from main() into a separate function (that's why sometimes functions are called "subprograms").
(3) solves the multiple responsibility problem, by getting rid of printing (moving it into the "user code"). The function contains only pure logic. Now it's a number crunching machine. In main function you can decide what to do with the result of the calculations without touching the calculating function. It becomes a "black box". No need to worry how it is implemented, and no need to change anything, it just works.
In your post there is a shorter version of (3):
int main() {
std::cout << sum(42, 13) << std::endl;
}
The difference is that no temporary object int s being created, but return value is being written directly to std::cout (in fact, passed as a parameter to a function called operator<<)
In real life
In real-life programming, most of the time you will be writing functions like (3), that don't print anything. Printing to terminal is just a quick and simple way to visualize data. That's why you've been taught how to output to standard streams rather than writing to the files, network sockets or showing GUI widgets. Console printing is also very handy during debugging.
See also:
Call Stack - Wikipedia to better understand how function calls happen under the hood
The Definitive C++ Book Guide and List might be of help too.
P.S. There is a big deal of simplification in this post, thus the usage of lots of quoted terms.

The int function must return an int. If you don't want to return values, you can use a void function:
#include <iostream>
using namespace std;
void addNumbers(int x, int y){
int sum = x + y;
cout << sum << endl;
}
int main() {
addNumbers(4, 5);
return 0;
}
The main() must return int (standard), which means that the program ran successfully (0). You can even leave the return statement out of main(), but it will return zero (implicit).
#include <iostream>
using namespace std;
void addNumbers(int x, int y){
int sum = x + y;
cout << sum << endl;
}
int main() {
addNumbers(4, 5);
}

You have two slightly different scenario in both of your snippets.
Case 1: You are printing the value from the called function, before the function finishes execution. So, you don't (need to) return any value. So you don't need a return statement.
Case 2: You are expecting the function to return the value which will get printd. So, you need to have a the return in your called function.

This is because of the return types of the function. Some times you want a function to give you a result instead of just doing things with the information you put into it.
Just like a variable has a type such as int and string, a function wants a type for the item it will be returning.
Here is a website which might help you get into the basics of functions including information about return types.

Related

How to implement the mapping from type to method call

I want to complete a mapping form type to method execution.
This sample code like this(The actual code is more complex):
int DoTask1(int num)
{
cout << "DoTask1" << endl;
}
int DOTask2(int num)
{
cout << "DoTask2" << endl;
}
static unordered_map<int, function<int(int)>> httpSrvFunc = {
{1, DoTask1},
{2, DOTask2}
};
int main() {
httpSrvFunc[1](1);
httpSrvFunc[2](1);
return 0;
}
The core idea is to use different key value to execute different method(these method have the same type)
There are two question here:
Because the construct of map/unordered_map is not nonexcept and we can't catch the exception of static global variable initialization. This makes code execution dangerous.
I don't want to use if/else to judge perform different method, it look not smart. I also don't want to use simple array to store function, because the key may be Enum or some other type which is inconvenient as a subscript.
I wonder if there's a more elegant way to do it.
Have you considered switch statement?
It is elegant, as it usually compiles to an elegant jump table.

Specifying class variables vs. method variables C++

Here's an extremely basic example of my question.
#include <iostream>
#include <string>
using namespace std;
int x;
void test(int x) {
x += 3;
cout << x << endl;
}
int main() {
test(x);
cout << x << endl;
return 0;
}
the output is:
"3" (new line) "0"
How can I specify inside of the "test()" function that I want the class's 'x' variable to have the 3 added to it instead of the temp variable inside of the function?
In java you specify that you're dealing with the function/method's variable by using '"this". Is there a similar way to do this in C++?
In your case you can use :: to specify to use global variable,
instead of local one:
void test(int x) {
::x += 3;
cout << ::x << endl;
}
And it is not class member or so on just global and local.
In the C++ language, create a class or struct and you can use this->x the same as this.x in the Java language.
First of all, thank you for stating that you come from Java. This will help us a lot in terms of helping you!
Now, let's analyze your code
#include <iostream>
#include <string>
using namespace std;
Including some headers, using the std namespace (not recommended, BTW), everything's okay here.
int x;
You declare a variable named x of type int at global scope, with an initial value of zero (this only applies to objects at global scope!).
void test(int x) {
x += 3;
cout << x << endl;
}
You declare a function test that takes a parameter x of type int and returns void (a.k.a: nothing). The function increments the value of its intenral x variable by 3, then prints that to standard output by means of std::cout. Just to be clear, once you declare the int x parameter, it "hides" the int x at global scope, thus if you want to access the later, you have to use another way (see below).
int main() {
test(x);
cout << x << endl;
return 0;
}
You declare the special main function, taking no parameters and returning int. The function calls test with the global int x as argument, then prints the value of the global x to the standard output by means of std::cout, and finally returns zero, indicating successful execution.
Now, you have a big misconception, that you can attribute to the single-paradigm design of the Java language. In Java, there's no concept of "global functions", not to even say there are no "functions" at all. You only have "classes" with "methods".
In C++, this is not the case. The C++ language is a multi-paradigm one; it allows you to do imperative programming, structured programming, object-oriented programming, and even functional programming (you're not expected to have understood that last sentence completely)! When you declare anything without specifying an scope, it's said to lie in the global scope. The global scope can be accessed by anything, anywhere. In the example you presented there are no classes involved!
In the global scope, something like void test(int) is not a method, but a function. There's no class "owning" that function; let's say it's of "everyone" ;). A function is just a block of code that you can reuse by giving it arguments, if the function has them at all. In C++, you use classes to encapsulate data and corresponding code in a single "packed" black-box entity, not for, well, anything, like in Java.
Now, (this is somewhat like Java, but be careful!), when you pass a "plain" object, such as an int or something more funky and complex like std:: (you were not expected to understand that...) to a function, that function gets a copy of that object. The int x in test is not the same as the one main passed to it. If you assign to it inside test, you'll notice main "sees no difference". In Java, this applies too, but only to the fundamental types like int, but in C++ it does for all types.
If you want to be able to change the variable you got, just use references. You get a reference of any type T by typing T&. So, if you assign to a int& x inside the now modified test, main will "see" all changes.
Finally, there's the :: operator. It's used to access stuff in some scope from, well, other scopes. It has the form namespace-or-class::stuff. So for example, std::cout refers to identifier cout in namespace std. There's a special case: if the left operand is not given, :: accesses the global scope. This is useful whenever you "hide" something from the global scope. So, for example, in test, you could say ::x, and that would refer to the x in the global scope!
void test(int x) {
// ...
::x += 123;
}
Edit: If you're curious, you can take a glance at how classes in C++ work with this (I won't explain it, because that's off-topic)...
#include <iostream>
int x = 0;
class MyClass {
private:
int x;
public:
MyClass() : x(0) {}
void test(int x) {
this->report(x);
std::cout << "Doing some magic...\n";
this->x += x;
this->report(x);
}
void report(int x) {
std::cout << "this->x = " << this->x << '\n';
std::cout << "x = " << x << '\n';
}
};
int main() {
MyClass c;
c.report();
x += 123;
c.test(x);
x += 456;
c.test(x);
c.report();
}

Const-correctness of function parameters on API changes

Suppose I am using a library which implements the function foo, and my code could look something like this:
void foo(const int &) { }
int main() {
int x = 1;
foo(x);
std::cout << (1/x) << std::endl;
}
Everything works fine. But now suppose at one point either foo gets modified or overloaded for some reason. Now what we get could be something like this:
void foo(int & x) {
x--;
}
void foo(const int &) {}
int main() {
int x = 1;
foo(x);
std::cout << (1/x) << std::endl;
}
BAM. Suddenly the program breaks. This is because what we actually wanted to pass in that snippet was a constant reference, but with the API change suddenly the compiler selects the version we don't want and the program breaks unexpectedly.
What we wanted was actually this:
int main() {
int x = 1;
foo(static_cast<const int &>(x));
std::cout << (1/x) << std::endl;
}
With this fix, the program starts working again. However, I must say I've not seen many of these casts around in code, as everybody seems to simply trust this type of errors not to happen. In addition, this seems needlessly verbose, and if there's more than one parameter and names start to become longer, function calls get really messy.
Is this a reasonable concern and how should I go about it?
If you change a function that takes a const reference so that it no longer is a const, you are likely to break things. This means you have to inspect EVERY place where that function is called, and ensure that it is safe. Further having two functions with the same name, one with const and one without const in this sort of scenario is definitely a bad plan.
The correct thing to do is to create a new function, which does the x-- variant, with a different name from the existing one.
Any API supplier that does something like this should be severely and physically punished, possibly with slightly less violence involved if there is a BIG notice in the documentation saying "We have changed function foo, it now decrements x unless the parameter is cast to const". It's one of the worst possible binary breaks one can imagine (in terms of "it'll be terribly hard to find out what went wrong").

C++ can't establish communication between variables in separate functions

I am making a text-based RPG with C++ and I'm having the same error pop up time and again, and I'm sure I'm doing something fundamentally wrong, but I don't know what. Searches turned up the solution to the specific compiler error, but not anything I can use to fix the code I'm writing.
Question I want answered: How do I use pointers to enable communication of variables between separate functions? In other words, how can I use pointers to point to a variable's value so that I can use and manipulate that value in a function in which it was not declared?
TL;DR version: I'm trying to make my "exp" int variable communicate with outside functions using pointers. I get the error "ISO C++ forbids comparison between pointer and integer [-fpermissive]"
Long version: Here's a bit of the code where I'm having problems:
In file charlvl.cpp:
...
int lvl = 1;
int *exp = 0;//value I want communicated to main()
int str = 0;
int vit = 0;
...
in file fight.cpp (main.cpp):
...
//you've just killed a monster
cout << "\nThe monster drops to the ground." << endl;
cout << "You gained " << expValue << " experience!" << endl;
&exp += expValue;//&exp is the character's experience.
//expValue is the exp gained upon monster death
//*exp (from charlvl.cpp) is the value I want to communicate to here.
It was not declared here, but in charlvl.cpp. How do I establish communication between the declared variable in charlvl.cpp and main() without having to resort to using global variables?
If you defined exp as a global pointer, you don't need to think about the communication thing, you can just simply use it in different functions, but the way you use it is wrong.
&exp += expValue;
should be change to
*exp += expValue;
because * means get that pointer's content to me.
btw, try not defining exp as a pointer may also work.
int exp = 0;
exp += expValue;
This is all based on exp is a global var or global pointer.
if you have defined it in a function like this:
void func()
{
int *expPtr = 0;
int exp = 0
}
And you want to use it in another function
void use()
{
// trying to use expPtr or exp.
}
The ways I know is:
1, use a local var and return it in func(), but be aware that the returned var is only a copy.
int func()
{
int exp = 0;
exp++;
return exp;
}
2, use a local pointer and allocate memory for it, then return the pointer or assign the new memory to a global pointer. But be careful about the memory leak, you need to delete it as soon as you don't use it.
int * func()
{
int *expPtr = 0;
expPtr = new int(2);
return expPtr;
}
You've gotten the & and * operators confused. * turns an int* into an int, while & turns an int* into an int**.
This is what you want:
(*exp) += expValue;
You might want to consider using references.

Calling functions from main() in c++

I came across a program with 10 header and 10 source files. I read in my text book that the functions are called from main. But how can I pass data to so many functions from main()?
Functions don't necessarily need to called from main. They can be called by other functions. For example:
int foo(int x)
{
return x*x;
}
int bar(int x)
{
return foo(x) + 1;
}
int main()
{
int a = bar(42);
std::cout << a << std::endl;
return 0;
}
Note that foo() is never called directly from main().
To my mind, this phrase isn't correct, but I guess what was meant to be said could be rephrased like "Every function or class method that you implement and use would be somehow called from your main() routine"
And somehow in this context would actually mean directly or indirectly - via other functions / function wrappers.
Anyway, the idea should be clear - any significant action that is done in your application is actually done using some function call from your main() routine, which is sometimes also called application root (try to think of your application as a tree of function calls and then your main() function would be right in the top of your tree).