Prototyping in C++ - c++

If I prototype a function above the main function in my code, do I have to include all parameters which have to be given? Is there a way how I can just prototype only the function, to save time, space and memory?
Here is the code where I came up with this question:
#include <iostream>
using namespace std;
int allesinsekunden(int, int, int);
int main(){
int stunden, minuten, sekunden;
cout << "Stunden? \n";
cin >> stunden;
cout << "Minuten? \n";
cin >> minuten;
cout << "Sekunden= \n";
cin >> sekunden;
cout << "Alles in Sekunden= " << allesinsekunden(stunden, minuten, sekunden) << endl;
}
int allesinsekunden (int h, int m, int s) {
int sec;
sec=h*3600 + m*60 + s;
return sec;
}

"If I prototype a function above the main function in my code, do I have to include all parameters which have to be given?"
Yes, otherwise the compiler doesn't know how your function is allowed to be called.
Functions can be overloaded in c++, which means functions with the same name may have different number and type of parameters. Such the name alone isn't distinct enough.
"Is there a way how I can just prototype only the function, to save time, space and memory?"
No. Why do you think it would save any memory?

No, because it would add ambiguity. In C++ it's perfectly possible to have two completely different functions which differ only in the number and/or type of input arguments. (Of course, in a well-written program what these functions do should be related.) So you could have
int allesinsekunden(int, int, int)
{
//...
}
and
int allesinsekunden(int, int)
{
//...
}
If you tried to 'prototype' (declare) one of these with
int allesinsekunden;
how would the compiler know which function was being declared? Specifically how would it be able to find the right definition for use in main?

You have to declare the full signature of your function, i.e. the name, the return value, all parameters with types, their constness, etc.

Related

Why isn't a function parameter used here?

I'm going through this tutorial:
https://www.learncpp.com/cpp-tutorial/how-to-design-your-first-programs/
I noticed the author didn't use a parameter in this function:
int getUserInput()
{
std::cout << "Enter an integer ";
int input{};
std::cin >> input;
return input;
}
Would it be okay to do something like this?
int getUserInput(int input)
{
std::cout << "Enter an integer ";
std::cin >> input;
return input;
}
It would work, but it wouldn't make much sense.
The first version of your function is used something like this:
int some_number = getUserInput();
That makes sense; the caller isn't providing any input to the function, so it takes no parameters.
The second version takes a parameter though, so the caller has to provide it. The function doesn't actually do anything with that value though. All of the following behave exactly the same:
int some_number1 = getUserInput(0);
int some_number2 = getUserInput(123456);
int some_number3 = getUserInput(some_number2);
It makes no sense for the caller to provide a parameter to the function since the function doesn't use it at all.

Xcode linker command failed with exit code 1 c++

I've written a simple series of functions. When I try to call the last function I get the "linker command" error. The syntax is correct but my program won't compile. Am I missing something or is this an IDE issue?
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <time.h>
using namespace std;
// Function Prototypes
int numGen ();
int questSol ();
int questAns ();
int main() {
// Store values of functions in variables
int ans = questAns();
int sol = questSol();
if (ans == sol){
cout << "Very good! Press Y to continue" << endl;
questAns();
} else {
cout << "Incorrect. Please try again" << endl;
cin >> ans;
if(ans == sol){
questAns();
}
}
return 0;
};
//Generates two random numbers between zero and ten and returns those numbers
int numGen () {
srand(time(0));
int one = rand() % 10;
int two = rand() % 10;
return one;
return two;
};
//Takes in the random numbers, multiplies them, and returns that result
int questSol (int one, int two) {
int solution = one * two;
return solution;
}
//Takes in random numbers, displays them in cout statement as question, receives and returns user answer to
//question
int questAns (int one, int two) {
int answer;
cout << "How much is " << one << " times " << two << "? \n";
cin >> answer;
return answer;
}
You forward declare a function:
int questAns ();
And then later define a function with a signature:
int questAns (int one, int two);
In C++, functions can have the same name but have different parameters (overloaded functions), so you've never actually defined the questAns that you forward declare and then try to call.
Note: You have the same problem with questSol.
It looks like you don't quite understand the scope of local variables.
Inside numGen you define two ints, one and two. Variables defined within a block (curly braces: {}) exist only within that block. They are local to it. The identifier is only valid within the inner-most block it's defined in, and once you exit it that memory is freed. Returning two ints like you're trying is also impossible.
It looks like you're expecting those ints to be available to your other two functions.
The smallest change you could make is to make int one and two global variables. This means you define them outside of any block (usually at the very top of your code). Then remove the parameter lists from your function definitions, because all the functions can see the global variables. That's generally considered bad programming practice because in more complex programs globals wreak havoc on your code, but in this simple program it'd work and give you a chance to practice understanding variable scope.
Another solution, more in line with what you were trying, is to define an ARRAY of two ints, and return that. Then pass that array to the other two functions. That'd be a better way to do it, and give you a chance to learn about arrays.
You have several problems:
numGen - You cannot return two separate values this way
// Function Prototypes
int numGen ();
int questSol ();
int questAns ();
Says that you have 3 functions all of which return an int and are called with no parameters - which is how you call them.
So the linker is looking for functions with a fingerprint of int_questSol_void and int_questAns_void - you then declare two functions that return an int and take as inputs 3 ints - these have fingerprints of int_questAns_int_int and int_questSol_int_int.
As a result the linker is moaning that you are calling to functions that it can't find.

Tutorial c++ reference parameters issue

I have some doubts about C++ reference parameters. I am learning from this website:
http://www.doc.ic.ac.uk/~wjk/c++Intro/RobMillerL3.html
First program:
#include<iostream>
using namespace std;
int area(int length, int width);
int main()
{
int this_length, this_width;
cout << "Enter the length: ";
cin >> this_length;
cout << "Enter the width: ";
cin >> this_width;
cout << "\n";
cout << "The area of a " << this_length << "x" << this_width;
cout << " rectangle is " << area(this_length, this_width) << endl;
return 0;
}
int area(int length, int width)
{
int number;
number = length * width
return number;
}
Then the author suggests that "under some circumstances, it is legitimate to require a function to modify the value of an actual parameter that it is passed".After that he introduces new function:
void get_dimensions(int& length, int& width)
{
cout << "Enter the length: ";
cin >> length;
cout << "Enter the width: ";
cin >> width;
cout << "\n";
}
What is the main advantage when we pass values as parameters?
Advantages of passing by reference:
It allows us to have the function change the value of the argument, which is sometimes useful.
Because a copy of the argument is not made, it is fast, even when used with large structs or classes.
We can pass by const reference to avoid unintentional changes.
We can return multiple values from a function.
Disadvantages of passing by reference:
Because a non-const reference can not be made to a literal or an expression, reference arguments must be normal variables.
It can be hard to tell whether a parameter passed by reference is meant to be input, output, or both.
It’s impossible to tell from the function call that the argument may change. An argument passed by value and passed by reference looks the same. We can only tell whether an argument is passed by value or reference by looking at the function declaration. This can lead to situations where the programmer does not realize a function will change the value of the argument.
Because references are typically implemented by C++ using pointers, and dereferencing a pointer is slower than accessing it directly, accessing values passed by reference is slower than accessing values passed by value.
Sources:
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
http://www.functionx.com/cppcli/functions/Lesson10b.htm
https://en.wikibooks.org/wiki/C++_Programming/Code/Statements/Functions
There is already a good answer (imho worth accepting). However, I would like to give a more basic answer, as it seems like you encountered passing by reference for the first time:
This function:
void foo(int x){x +=1;}
can do anything with the value of the passed (by value) parameter, but it has no chance to return anything to the caller, i.e. the x+=1 has practically no effect at all.
On the other hand, this function:
void bar(int& x){x +=1;}
gets not only the value, but it is working on the actual variable that you pass as parameter (by reference). Thus the x+=1 has an effect also outside of the function.
Both functions in action:
int main(){
int a = 1;
foo(a); // foo gets a copy of a and increments its value
// a is still 1
bar(a); // bar directly increments the value of a
// a is now 2
}
This is the main difference of passing a parameters by reference (bar) vs passing by value (foo). The main advantage of passing by reference is that the value of the parameter needs not to be copied. (This is whypassing by value is usually done with a const reference. Passing a const reference is like passing the value because the value cannot be changed even if actually a reference is passed.) However, for more details I refer to Rohits answer.
int &a is a reference to any parameter passed to that function, You should always think of references as Alias to a variable (it is similar to a const pointer).
If your reference is not const you are allowed to changed and therefore change the content of the original variable.
It is useful for many reason first of all it can improve performances by avoiding doing copies when passing a parameter by reference, and it is also useful if you have a function that your expecting to return multiple results for example =:
int f (int &a,int &b,int &c,int&d);
int main
{
int first,second,third,result;
result = f(first,third,result);
}
All your int variables can be change within you function.

Need help understanding struct, and a few errors with program

I don't get how to use structs properly to achieve my goal of calculating Fractions (it is required). Quite frankly I don't have much of an idea of what I'm doing, this is only my 3rd class in C++ and I feel lost...this was the task assigned to us
Your enter() function accepts a fraction from the user. Your
simplify() function simplifies the fraction that it receives, if
possible. Your display() function displays the fraction that it
receives.
Your global functions use a Fraction type. A Fraction type holds the
numerator and denominator of a fraction as separate data members.
This is my program, only the main EXCEPT the "cin" and "cout" and the GCF function was provided by the professor, all other functions and struct outside of the main i tried to do myself...
#include <iostream>
using namespace std;
void entry (int a, int b);
void simplify (double c);
void display(int x, int y)
int main()
{
struct Fraction fraction;
cout << "Enter a numerator: " << endl;
cin >> fraction.num;
cout << "Enter a denominator: " << endl;
cin >> fraction.den;
cout << "Fraction Simplifier" << endl;
cout << "===================" << endl;
enter(&fraction);
simplify(&fraction);
display(fraction);
}
struct Fraction {
int num;
int den;
}
struct Fraction fraction{
fraction.num;
fraction.den;
}
void display(int num, int den) {
cout << fraction.num << endl;
cout << fraction.den << endl;
}
// Great Common Factor (Euclid's Algorithm), provided by Professor
int gcf( int num1, int num2 )
{
int remainder = num2 % num1;
if ( remainder != 0 )
{
return gcf( remainder,num1 );
}
return num1;
}
these are my errors:
w2.cpp: In function 'int main()':
w2.cpp: 14: error: aggregate 'Fraction fraction' has incomplete type and cannot be defined
w2.cpp: 23: error: 'enter' was not declared in this scope
w2.cpp: At global scope: w2.cpp:35: error: function definition does not declare parameters
w2.cpp: In function 'void display(int, int)':
w2.cpp: 41: error: 'fraction' was not declared in this scope
I'm sorry for the really long post, but any and all help is greatly appreciated.
AND if someone could point me to a helpful C++ book that I could read while at home and or in lectures (because of a language barrier i cannot understand my prof well enough) would also be appreciated
Let's walk through these:
error: aggregate 'Fraction fraction' has incomplete type and cannot be defined
Now, in main(), you said struct Fraction fraction;. At this point, you're forward-declaring your struct. It is not complete, so you can't use it as if it were.
You should have your whole Fraction struct defined before main(). Also note that the struct in struct Fraction fraction; is unnecessary, and left over from C.
error: 'enter' was not declared in this scope
Simple. You've declared entry() up top, but you're trying to use enter(). Not much more to be said.
At global scope: w2.cpp:35: error: function definition does not declare parameters
Now this is a bit more confusing. This is the offending line:
struct Fraction fraction{
How the compiler sees this is that it is a function returning a Fraction, but it's missing its parameter list. I'm not exactly sure what you're trying to do with this block of code.
error: 'fraction' was not declared in this scope
Looks like you're trying to use an object declared somewhere else. If you want the one from main(), you'll have to pass it in as an argument. If you want a global variable fraction, all you need in the global space is:
Fraction fraction;
This should occur after the Fraction struct. Also note that because this has the same object name as the one in main(), the one in main() shadows this one, and if you want to access the global one from main() you need to use ::fraction.
I hope that helps clear up some of the understanding.
Some other errors I see are:
enter(&fraction);
You're passing a Fraction * to a function that takes two ints. I think you'd want this one to take a Fraction &. Then you can just call it like enter (fraction); to have it modify the object passed in.
simplify(&fraction);
Similar, but this one takes a double. I think you'd want it to take a Fraction & as well.
Your entry and simplify functions never get defined, but you still try to use them.
display should take a Fraction in order to print the parts of it.
A list of recommended books on C++. Searching this site helps too.
In C++, structures (or classes) and unions form the two basic types of user defined data structure. A user defined data structure is a model/blue-print of something (it could be a real-world quantity or an abstract concept) you want your program to work with. So, if you wanted a structure to store your friends' names, you'd probably do something like this:
struct FriendName {
std::string first, last;
}; // the semi-colon is required here
first and last are the members of your struct. std::string is the type of these members which tells the compiler what sort of data you want to store -- the data here being strings we use the appropriate type defined by the library.
Once you've defined something called a FriendName you can use it to store data and also work with this data. However, if you try to define FriendName again, the compiler will complain. Which is what is happening with your code.
Now, in order to use this data structure, you will need to create an object (which is a region of memory that represents a particular FriendName instance). You can create an object as follows:
FriendName fred; // note that I don't need to use struct FriendName
and you can go ahead and use it as:
fred.first = "Fred"; // write 'fred' object's first name
fred.last = "Flintstone";
The object name works as a marker which when combined with with the . operator and a member name allows you to read/write that particular member.
Assume you wanted to read in the names from the console: In that case you'd do:
FriendName wilma;
std::cin >> wilma.first >> wilma.last; // read in 'wilma' objects members one by one
Now, there's enough up there to get you started!

C++ compiler warning(?) when passing uninitialized local variable to function

I'm very new to C++ so I'm hoping someone would shed some light. I came across several similar topics but I just need clarification.
So it seems it's valid to pass a local string that has been declared but not initialized to a function. But why does compiler complain when you try it with int or float??
Whether it's string, float, or int, memory address gets referenced when it is declared even tho it may be "garbage"
#include <iostream>
using namespace std;
void load(int);
int main()
{
int salary;
load(salary);
return 0;
}
void load(int sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
If I declare int or float as global variable, it works as expected without any warnings.
So then is it a better practice to declare variable in global space (I hope not)?
So putting it in global, it works :
#include <iostream>
using namespace std;
int salary;
void load(int);
int main()
{
load(salary);
return 0;
}
void load(int sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
ok, another example to show that uninitialized global variable works when passing to function as value : (going off of David's comment)
int foo;
int returnit(int j)
{
cout << "your salary";
cin >> j;
return j;
}
int main()
{
int k = returnit(foo);
cout << k;
return 0;
}
anyways, lesson here is to initialize primitive data types before passing to functions.
So it seems it's valid to pass a local string that has been declared but not initialized to a function. But why does compiler complain when you try it with int or float??
If by "string" you mean a std::string object, it's because objects are never uninitialized. When you do:
std::string s;
then the default constructor of std::string is invoked, and the object is initialized.
Variables of primitive data types (such as int and float), unless declared to have static storage duration, will have garbage if not explicitly initialized, however. Making attempts to read and use that garbage rightly trigger warnings. (Variables of primitive data types that do have static storage duration (i.e., global variables or variables declared as static) are implicitly initialized to 0.)
So then is it a better practice to declare variable in global space (I hope not)?
No, a better practice would be to initialize your variables.
The best way to explain why you should never use an uninitialized variable in a function call is because this is logically invalid and sometimes both logically invalid and the syntax is invalid.
To see if your program is logically valid use the box method and trace your program. Global box has global variables in it, int main has its own box which holds its local variables, and when functions are called create a new box for that function and fill it with its parameters and local variables. Go line by line and change variable values as they change in the program. Remember to use only constants as global variables. When writhing a function be careful when you pass by reference that you understand that the function is given that variables address in memory and can change that value. When using pass by value use this kind of syntax in your functions declaration:
int Multiplication(const int Var1, const int Var2);
This protects the values you pass to multiplication.The syntax of c++ is made for speed, and it does not keep you from being logically incorrect.
int salary;
load(salary);
What value do you think you are passing to load here? You're passing a nonsense value.
To be clear, you are not passing an "uninitialized variable", you are passing the value of an uninitialized variable. If you do:
int j=3;
load(j);
You are passing the value of j, that is, 3, to load. If you don't specify otherwise, C++ passes by value.
You'd have the same problem with a global variable:
int foo;
int returnit(int j)
{
return j;
}
int main(void)
{
int j=returnit(foo);
What value do you think j should have here?! You still have to initialize a variable to some particular value before you can pass its value to a function.
To add on David's answer, what you probably wanted to do (I'm guessing) is to modify the original salary variable. To do this you need to pass a reference to the variable, like this:
void load(int& sal)
{
cout << "your salary: " << endl;
cin >> sal;
cout << sal << endl;
}
Note the '&' after int in the function signature.
Also note that you use 'salary' in load() where it's not defined. You should use 'sal' instead.
That way the compiler knows that load() receives a reference to a variable, so if you modify it inside the function, the variable you sent to the function (salary) also changes.
The call itself to the function remains the same.