#include <iostream>
#include <string>
usingnamespace std;
string input();
int countVowels(string);
// Main Function
int main(){
string word = input() ;
int vCount = countVowels(word);
cout << "There are " << vCount << " vowels in " << word << " which has " << word.length() << " letters.\n" ;
return 0;
}
// Input Function
string input(){
string word;
cout << "Please type word: " << endl;
cin >> word;
cout << endl;
return word;
}
// Count Vowel Function
int countVowels(string word){
int vCount = 0;
int i = 0;
while (i < word.length()){
char Let = word [i];
bool isVowel (Let == 'a' || Let == 'e' || Let == 'i' || Let == 'o' || Let == 'u' ||
Let == 'A' || Let == 'E' || Let == 'I' || Let == 'O' || Let == 'U');
if ( isVowel )
++vCount;
++i;
}
return vCount;
}
Line 07 is called a "prototype". This tells the compiler that you have a function called countVowels which returns an int and takes one argument (as a string). This allow the compiler to check whether you are passing the wrong number or wrong type of arguments.
On line 13, you are "calling" countVowels with "word" as a parameter. This basically means you are copying the value of "word" into the first argument of countVowels. If it helps change the name of the argument on line 32 to "arg1" or something.
Note that since this is a *copy*, so if you tried to modify the argument inside the function, it would not modify the original argument you were passing.
Well, there was nothing 'wrong' in my passing of values in my first code, from what I saw.
What would be classified as a 'wrong number' or 'wrong type of argument'?
Why do I need to copy the value of 'word' into countVowels?
The line string word = input(); in my first code grabs the word just fine.
Well, there was nothing 'wrong' in my passing of values in my first code, from what I saw.
Well, no - since you didn't pass any arguments, all your argument passing was fine ;)
What would be classified as a 'wrong number' or 'wrong type of argument'?
If you tried to pass the wrong type of variable - ie an int to a function that takes a string.
Why do I need to copy the value of 'word' into countVowels?
You don't. Have your function take a reference instead (using the '&' reference indicator for function parameters): int countVowels(string&);
Or even better, have it take a const reference: int countVowels(const string&);
This indicates to the compiler that you will not be changing the variable in the function, helping detect mistakes in your code.
The line string word = input(); in my first code grabs the word just fine.
Yes it did, but it still made a copy: The string was copied on return. So it was inefficient, but that doesn't matter in such trivial code.
The thing is that you are that you are (IMO) violating the principle of least surprise.
When I see a function called "countWords" I would expect it to count the words in a string I give it, not ask for the string too. Do you understand?
It's sort of like making a function like this:
1 2
int add(int a, int b) {
return a - b; //trololol subtraction instead
To me, this code would make sense. It takes the value of int A and int B, and returns the value of A minus B. It's simple and to the point. I'm not sure I understand why this would be bad.
Also @ exiledAussie, we haven't touched on the & symbol or const yet, so I'm going to hold off on asking about those for now. You say that my code works fine because I don't pass any arguments; I think my main problem is that I'm not completely sure what an 'argument' really is in C++ context, so the passing of arguments looks alien to me. Back to learncpp.com I suppose.
To me, this code would make sense. It takes the value of int A and int B, and returns the value of A minus B. It's simple and to the point. I'm not sure I understand why this would be bad.
An argument (or a parameter) is what is passed to a function. So take the function:
int Add(int a, int b){return a + b;}
Add will return the value '5' for the arguments '3' and '2'.
So take your original countVowels function. A programmer would expect this to be a function on whatever word you gave as an argument. This would accord with the principle of least surprise! But you did not give it any argument. Rather you got the function to itself ask the user to input a word for it to analyze. So (basic interpretation) it turned no argument into a count of vowels, which is odd!
By separating input from analysis you can make a more robust and more understandable program.
Ok, let me try to explain what I'm misunderstanding.
In the following code, let's look at line 7.
int countVowels(); would return the value determined by the countVowels function. I get that.
From what you all are saying, adding "string" to the parenthesis defines a parameter.
so let's use the one provided in the code:
int countVowels(string);
So the parameters are now defined by a string. This is what confuses me. The value I want to return from countVowels is vCount (a number), not a string. This 'parameter' doesn't make sense to me.
When you are passing the string as an parameter, you are basically saying something like "perform this function on this argument." So when you do something like
countVowels(myString);
You are saying "count the vowels in myString and give me the result."
When you are passing the string as an parameter, you are basically saying something like "perform this function on this argument." So when you do something like
countVowels(myString);
You are saying "count the vowels in myString and give me the result."
Does that help any?
YES, that makes much more sense now. Sorry that I'm taking so long to grasp this stuff. Saying it like that clears up a lot.
So...
int countVowels(string);
would perform the countVowels function on whatever string is defined...
int countVowels(string word);
Would perform the countVowels function on the specific stringword that I provided.
but countVowels(word) is always used in the code... wouldn't that need to be countVowels(string word)?
This is used in the definition because otherwise you would have no way to refer to the string, so you give it a name. The name is pretty arbitrary; like stated earlier you could call it arg1, word, or even zyxxy.
When you are calling the function, you do NOT put the type. That is because the type is already known (you wrote string word before). Just put the variable there.
For example:
1 2 3
int x = 1, y = 2;
int z1 = x + y; //this looks much better than
int z2 = int x + int y; //this, and this doesn't make much sense anyway
1 2 3
int x = 1, y = 2;
int z1 = add(x, y); //same here
int z2 = add(int x, int y);
So let me see if I get the basics of this.
If I used a function like:
1 2 3 4 5 6 7 8 9 10 11
void foo(int y)
{
cout << "y = " << y << endl;
}
int main()
{
foo(5)
return 0;
}
Then Y would grab the value of 5 and use it as Y, then at the end of the function, 5 disappears, and Y remains open for anything else I want to assign to it, correct?
Then Y would grab the value of 5 and use it as Y, then at the end of the function, 5 disappears, and Y remains open for anything else I want to assign to it, correct?
Yes, exactly. The y inside the function is a new one every time you call it, and separate from any other y's inside main or other functions.