I need your help to get started with a good implementation thinking.
I need to create a simple program with the following:
1. A function with two parameters, first parameter is a name (char*), and the second parameter is the number of times you would like to print this name to the screen(int).
If the second parameter wasn't supplied in the function call, it should print the name 10 times.
If the first parameter wasn't supplied in the function call, it should print the author name / the writer of the program (i.e my name).
I was thinking to create the following function with default parameteres:
void printTextToScreenNTimes(char * text = "guy", int n = 10);
This function implementation is the following :
void printTextToScreenNTimes(char * text, int n) {
int i;
for (i = 0; i < n; i++)
cout << text << " ";
}
My problem arises as I try to print my default name 2 times. For example if I want only using the following function call:
void printTextToScreenNTimes(3);
I would like the function to print the default name (in this case "guy") 3 times but It's impossible because I must fill the first parameter.
Do I have no choice but using a global parameter holding my name?
Overloading:
void printTextToScreenNTimes(int x)
{
printTextToScreeNTimes("guy", x);
}
I think you are reading too much into your requirements. I think the second part about not supplying the name only applies when the first part (not supplying the count) also applies.
But in any case you can solve it using overloading as Luchian has just explained.
Related
Please let me preface this question by stating that I am an absolute C++ novice and I'm only well-versed in R. Also, I'm working within Xcode.
Let's say I create an int object called 'answers'. Initially, it is set as int. After I assign values to answers[0], answers[1], etc., is it still int or has it become something else because I added multiple values?
int answers[4];
answers[0] = 8;
answers[1] = 6;
answers[2] = 7;
answers[3] = 5;
Let's say I want to pass 'answers' to a user-defined function (see code below). My problem is that in the line, cout<<"The first value you entered...", I get an error saying that 'Subscripted value is not an array, pointer, or vector". Then, in the line, showAnswers(answers);, I get the error 'No matching function for call to 'showAnswers''. What am I doing wrong here? My first guess is that 'answers' is no longer an int, but I don't know what it would be.
void playGame(int input){
cout << "The first value you entered was: " << input[0];
}
int main() {
int answers[4];
answers[0] = 8;
answers[1] = 6;
answers[2] = 7;
answers[3] = 5;
showAnswers(answers);
}
Two things to consider:
First, as said in a comment by Igor, answers is not an int but rather an array of 4 int values.
Second, the parameter for playGame is an int not an array of int values, so adding the subscript ([0]) is not valid.
Either you must make a separate call to playGame for each value in your array, or modify the function to accept an array reference, or a pointer to your array.
In the grand scheme of things, neither of those solutions is optimal for larger programs, as they can be prone to problems as described here in the Cpp Core Guidelines: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#a-nameri-arrayai13-do-not-pass-an-array-as-a-single-pointer
Lets say I have a function
void doStuff(vector<int> &a, int b, vector<int> &c> {
c = vector<int>(a.size());
for (int i = 0; i < a.size(); i++) {
c[i] = a[i] + b;
}
}
obviously, upon seeing the function, we know that "c" is the output.
For anybody who hasn't seen the function definition though, it remains a mystery unless i name c something like "output_c". Maybe I'm just being vein but I don't like naming things "ouput_xxx", is there any syntax candy for letting the user of the function know that its supposed to be the output?
Syntax, by itself, can be a guide to indicate which one is an input argument and which one is an output argument. However, an output argument can also serve as an input argument too. You cannot tell that by just looking at the signature.
Examples:
int foo(int arg); // The argument is copy by value. It can only be an input argument.
void foo(std::vector<int> const& arg); // The argument is by const&.
// It can only be an input argument.
void foo(std::vector<int>& arg); // The argument is by &. It can be:
// 1) an output argument.
// 2) an input and output argument.
// 3) an input argument (bad practice)
You could add a preprocessor directive:
#define OUT
and put it in the parameter list like so:
void doStuff(vector<int> &a, int b, OUT vector<int> &c) ...
I think I've seen some APIs do something like this. That way it is explicitly stated in the function signature but you don't have to modify the variable names. The code is also unchanged at compile time since OUT is not defined to be anything, it is just a defined symbol.
I think, though, I would rely on your own documentation when writing the function and/or return-by-value instead of doing something like this. You could also make use of the const keyword to flag a parameter that is guaranteed not to change - that's what the syntax is designed for.
I am reading this tutorial about function pointers which said that function pointers can replace a switch statement
http://www.newty.de/fpt/intro.html .
Can anyone clarify?
We have a switch statement like this:
// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer
float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }
// Solution with a switch-statement - <opCode> specifies which operation to execute
void Switch(float a, float b, char opCode)
{
float result;
// execute operation
switch(opCode)
{
case '+' : result = Plus (a, b); break;
case '-' : result = Minus (a, b); break;
case '*' : result = Multiply (a, b); break;
case '/' : result = Divide (a, b); break;
}
cout << "Switch: 2+5=" << result << endl; // display result
}
// Solution with a function pointer - <pt2Func> is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer
cout << "Switch replaced by function pointer: 2-5="; // display result
cout << result << endl;
}
// Execute example code
void Replace_A_Switch()
{
cout << endl << "Executing function 'Replace_A_Switch'" << endl;
Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}
As you can see, the Replace_A_Switch() function as an example is very unclear. Supposed we need to point the function pointer to one of 4 arithmetic functions(Plus,Mins,Multiply,Divide). how can we know which one we need to point to? We have to use the switch statement again to point the function pointer to the arithmetic functions , right?
It will be like this one**(please the comment in the code)**:
void Replace_A_Switch()
{
.....................
..........
//How can we know this will point to the &Minus function if we don't use the switch statement outside?
Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}
So in summary, what is the advantages of function pointer, it always said that the function pointer a late-binding mechanism , but in this tutorial i dont see any advantage of the function pointer for late binding.
Any help are very appreciated. Thanks.
What you're saying is pretty well true, you still need to decide somewhere what function pointer to use.
What you're looking at though is a pretty simple, contrived example for explanation purpose. It shows how you can leverage a function pointer. In this case it might be pointlessly complicated but a real case would probably be too complicated to use to instruct in this basic concept.
The difference becomes much clearer when you've got a lot of functions that have the same switch, or a switch with subsets of the same set. The difference is all the same though (this is also important). In that case, why rewrite it a bunch of times?
It also opens your code for a change in how the decision is made. Maybe you want to invert '+' and '-' for whatever reason. Change the point where you make the pointer and all the client code catches up.
Finally, what if you don't even need to make the decision? Instead of replacing the switch for example, what if you just wanted to do the addition version? Obviously addition is too simple a task for this level of design, but again it's just an example.
All this is true whether you're using function pointers or a class hierarchy. Someone has to decide what the input will be. What these constructs do is provide you a method to compose different bits into a running program. It also separates the part that is responsible for deciding which version of things to use from the using of those things. There are a lot of different ways to approach that creation (see creational design patterns for some).
As the tutorial states there are no advantages and the basic calculator is simply an example. The main use of function pointers is to allow the API-dev to define a function, which does something that is not known at the time the API is created.
A better example is probably qsort, which takes a comparison function. Thanks to this function-pointer argument it is possible to implement the sort in a generic way. Since you could not possibly know what kind of data needs to be sorted you can't know how the <,=,> operators have to be implemented. Thus you expect the caller to provide a function that implements the comparison thereby avoiding this dilemma.
In general, function pointers are often useful if you want to program something in a generic way. Its use is that of function-arguments in other languages. If someone asked you to implement a simple reduce function for example, you could come up with something like this:
void reduce(void *data, size_t nmemb, size_t size,
void (*op)(void *, void *), void *res){
int i;
for (i = 0; i < nmemb; ++i){
op(data, res);
data = (void *)((unsigned char*)data + size);
}
}
Clearly it is very advantageous over rewriting this for operations like multiply, add, and more complex ones all over again with the respective function replacing op.
I can see how you can convert your '+', '-' etc into an enum, and store the 4 func pointers into an array ordered by the enum order. After that arr[op] is the function you want, just execute that.
Alternatively a std::map<String, FuncType> map from + -> &Plus.
as from what i see..
the pt2Func is a name defined for pointer which references a function
you can see how it works in the main where it is being called
(removed the comment to make it more readable)
Switch_With_Function_Pointer(2, 5, &Minus);
&Minus here is a pointer that references to your function Minus
this is stupid as you are calling a function to reference another function by using a pointer.
There is no benefit and it does nothing special.. its just another more complicated way to call the Minus function
the Switch function however is just a normal switch encapsulated in a function for reusability
after making a fresh start on a new program i made for learning how arrays work in combinatio0n with void ive ran into the following problem.
cpp(15): error C2182: 'input' : illegal use of type 'void'
Does anyone know what causes this? I am new to the concept of void and array.
#include "stdafx.h"
#include <iostream>
using namespace std;
void input (int x );
int main()
{
int x = 0;
int a[ 5 ];
input ( a[ 5 ]);
{
void input(x);
for(int i = 1; i < 5; i++) {
cin >> a [ i ];
}
cin.get();
cout << a [ 3 ];
cin.get();
}
}
Your code has many problems with it. It's just not valid C++ as it is. Remember that C++, like any other programming language, is unforgiving when it comes to syntax. If it's not exactly the right syntax, it's not going to compile. You can't just write what you think makes sense. You need to learn the correct syntax and apply it.
It looks like you want everything from the for loop to the last cin.get() to be part of a function called input. To do that, you need to use the appropriate syntax for defining a function and you need to do it outside any other functions:
void input(int x) {
for(int i = 1; i < 5; i++) {
cin >> a [ i ];
}
cin.get();
cout << a [ 3 ];
cin.get();
}
This still has a problem though. The parameter type is int, yet it looks like you want to pass the entire array:
void input(int x[])
Note that this is not actually an array type parameter, but is really a pointer. When you pass an array to this function, x will be a pointer to its first element. The [] is just a convenient syntax.
Then, instead of passing a[5] to the function (which is an element that does not exist, since only a[0] to a[4] exist), you should be passing just a:
input(a);
You also loop from 1 to 4 - I'm not sure if this is intentional. If you want to input a value for each element of the array, you should be looping from 0 to 4.
You're going to have more errors after resolving the current one. Here's some quick pointers that may help. I don't want to just give you a solution because you are still learning and that won't help:
void as a keyword refers to the "nothing type" and is used in functions to denote having no return value
curly braces {} denote scope and can be used to define the body of a function, loop, or control statement
Functions themselves need to be declared and defined. The definition, or body of the function, can be later on in your code but the declaration needs to be present before you call it
Here's an example program to illustrate basic function parts:
#include <iostream>
// declaration
void Welcome();
int main()
{
// function call
Welcome(); // displays "Hello World"
return 0;
}
// definition
void Welcome()
{
std::cout << "Hello World" << std::endl;
}
More on functions
As far as arrays they are basically a contiguous block of memory large enough to hold a given amount of the same type. Here's a few things to remember about arrays:
They work with integral types as well as objects but are usually used for plain old data. e.g. int intArray[5]; is an array of 5 int types.
The index starts at 0 meaning intArray[0] from previous example is the first integer.
Using the array operator you can get and set values e.g. int last = intArray[4]; or intArray[0] = -1;
More on arrays
Check out the other answers for more on how to pass arrays as parameters but I also recommend picking a Good C++ Book ;-)
EDIT: thanks for all the speedy responses, I have a much better understanding of this concept now. Also, I'll try to make my error messages more clear next time.
EDIT: updated with my newest code. the error happens on line 18. Also, I'm beginning to wonder if my latest issue has to do with the original class itself?
I'm trying to teach myself classes and objects in C++. I did it once by just declaring a void function, outputting something on the screen, calling the object in main and everything worked fine.
Now, I wanted to expand upon this and make a simple addition thing. However, I get a couple errors on Code Blocks:
error: invalid use of non-static member function 'int Addition::add(int, int)'
error: no matching function for call to 'Addition::add()'
Here's my code:
#include <iostream>
using namespace std;
class Addition {
public:
int add (int x, int y) {
int sum;
sum=x+y;
return sum;
}
};
int main()
{
int num1;
int num2;
int ans=addobj.add(num1,num2);
Addition addobj;
addobj.add(num1,num2);
cout<<"Enter the first number you want to add"<<endl;
cin>>num1;
cout<<"Enter the second number you want to add"<<endl;
cin>>num2;
cout<<"The sum is "<<ans<<endl;
}
One of the most important things, a developer should learn to do is to read compiler's messages. It's clear enough:
error: no matching function for call to 'Addition::add()'
Your function in your class is
int add (int x, int y)
it takes 2 arguments and you pass none:
addobj.add();
You have 2 options:
create and initialize x and y inside your main and pass them as arguments
make add without parameters, create x and y inside add's body, as their values are taken from user input.
In this case, as the function's name is add, I'd chose the first option:
declare int x, y; inside your main
read the user input inside the main (the part, where you use cin and cout)
pass the x and y as arguments to add like this: addobj.add( x, y );
store the result (if needed), like this: int result = addobj.add( x, y );
You declared a method add(int, int) that takes two integers as arguments; you have to supply those arguments when you call it. It would be nice to print the returned value, as well:
Addition addobj;
std::cout << addobj.add(1, 2) << std::endl;
Your add function takes two arguments, yet you call it with none, so no matching function could be found. You must call the function as it was declared, i.e.,
addobj.add(1, 2);
Your function takes two arguments and yet you call it without providing them. You need to provide the two integer arguments that your function requires. To be useful you should store the result too. Something like this
int a = 1;
int b = 2;
int result = addjobs.add(a,b);