Consider:
for(int i = 10; b >= i; i++){
if(i%2 == 0)
cout << "even" << endl;
else
cout << "odd" << endl;
}
for(int i = 10; b >= i; i++){
if(i%2 == 0){
cout << "even" << endl;
}else{
cout << "odd" << endl;
}
}
Both of these code work with the only difference being the curly brackets for the if else statement. When should I use curly brackets and when not?
They're called braces or curly brackets, not to be confused with the "curly arrow" in some languages, ~>.
In C, and by inheritance C++, these are optional on single-line if statements, but as many, many bugs have been created by omitting them you'd be advised to use them as a matter of principle even when they're redundant.
That is a mistake like this is easy to overlook:
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
Where it seems like that goto is conditional, yet it's not, it just drops through. This is the huge OpenSSL bug that caught everyone by surprise, and if veteran developers can mess it up, so can you.
The second form is the most reliable, least ambiguous, especially when formatted according to typical conventions:
for (int i = 10 ; b >= i;i++) {
if (i%2 == 0) {
cout << "even" << endl;
}
else {
cout << "odd" << endl;
}
}
for is a statement, not a function, so the syntax is for (...) with a space. Functions have no space, like f(...). Omitting the space implies for is a function, which it absolutely is not. The same goes for if, while and so on.
It's worth noting that the original code can actually be reduced to:
for (int i = 10 ; b >= i;i++)
if (i%2 == 0)
cout << "even" << endl;
else
cout << "odd" << endl;
Since that if is a single statement, even with the else clause attached.
Again, this is not advised because the rules of what is and isn't a single statement can be confusing.
Google has a detailed C++ style guide that may help you. In particular, it says that
In general, curly braces are not required for single-line statements, but they are allowed if you like them; conditional or loop statements with complex conditions or statements may be more readable with curly braces. Some projects require that an if must always have an accompanying brace.
If the 'if', 'else' or 'for' structures have only one statement inside them, you can decide not to use the curly brackets. However, I would recommend to use them in order to improve the code readability.
Related
I have been learning c++ recently. When I tried to run the following lines...
#include <iostream>
short a = 0;
short b = 1;
short c, i;
void Fibonacci(){
std::cout << a;
std::cout << b;
while (a <= 100){
c = a + b;
a = b;
b = c;
std::cout << c;
}
}
int prime_number(short a){
if (a == 1){
std::cout << "It's a prime number\n";
} else{
for (i = 2; i < a; i++){
if ((a%i) == 0){
std::cout << "It's a prime number\n";
std::cout << "The given number is divisible by " << i << "\n";
return 0;
}
}
std::cout << "It's not an prime number";
}
}
int main(){
short user_input;
std::cout << "Press 1 for Fibonacci and 2 for prime number";
std::cin >> user_input;
if (user_input == 1){
Fibonacci();
}
if (user_input == 2){
std::cout << "Type the number to check whether it's prime";
std::cin >> a ;
prime_number(a);
}
}
...I get an error saying:
In function ‘int prime_number(short int)’:
Function.cpp:37:1: warning: control reaches end of non-void function [-Wreturn-type]
37 | }
I searched various platforms for the answers, but I couldn't understand what really happens here. It's an error because the compiler cannot find whether the function has an end or not. Can someone help me understand the error and solve it?
Warnings aren't errors. When you compile a program and only get warnings (ie. no errors) then this means your program has successfully compiled (an executable has been made). When you get errors, this means that compilation was aborted (so no executable output - if you already had one, it won't have been updated).
It's warning you that when the integer input is 1 that you aren't specifying a return — which is invalid. Also, if it's not 1, then the the else statement still doesn't guarantee a returned value:
for (i = 2; i < a; i++){
if ((a%i) == 0){
std::cout << "it's a prime number\n";
std::cout << "The given number is divisible by " << i << "\n";
return 0;
}
}
The compiler can't know that return 0 will always be executed here - and even if it could, the compiler isn't designed to always understand the logic of your code. Even knowing your logic, return 0 will only be executed if a is greater than 2 and non-prime.
You could fix this by putting return statements in both of your if statements, or even at the end of your function. But notice that you never use the return value? This implies that your prime_number() function should be void prime_number(), then you won't need return values at all, and can just use break; in your loop - or return; if you prefer (here's an example of how to resolve this particular issue - there's still other bugs though, discussed below).
This is probably confusing to a beginner: Why doesn't it warn you when the function int main() contains no return value? This is because main is special: If no return value is given, it implies return 0.
Another thing that may confuse you here is if you ever compile with the flag -Werror. If you do, then the original code will give you an error, because the Werror flag turns all warnings into errors (to force programmers to pay attention to the warnings).
The logic of your code isn't right - it's actually the opposite: 1 is defined as not a prime number (this is because of the value we get from unique prime decomposition, so mathematicians chose to exclude 1 as prime). Also, ((a%i) == 0) means that when a is divided by i that it has 0 remainder, ie. i divides a, so a is not prime.
Finally, avoid using global variables. Keep all your variables local so that the logic of your code is simpler (easier to read / less bug-prone).
Here's an example of how you could rewrite your code that resolves all the above issues.
As Elliott in the comments has said the warning you are getting is not going to affect your program at all. It's recommend that you return something since you function has a return type of integer.
Below is a easy fix to get rid of the warning. :)
Old Code:
if (a == 1)
{
std::cout << "Its a prime number\n";
}
New Code without the Warning:
if (a == 1)
{
std::cout << "Its a prime number\n";
return 0;
}
I'm working on a midterm project for my coding class, and while I've gotten the majority of kinks worked out I'm struggling with comparing two string values and determining if they are equal or not. The strings in question are ANSWERKEYand studentAnswers. The former is a constant that the latter is compared to.
The code in question is as follows.
if (studentAnswers == ANSWERKEY)
{
percentScore = 100.0;
cout << "Score: " << percentScore << " % " << 'A' << endl;
}
else if (studentAnswers != ANSWERKEY)
{
int count = 0;
double answerCount = 0.0;
while (count < ANSWERKEY.length())
{
if (studentAnswers.substr(count, count+1) == ANSWERKEY.substr(count, count+1)
{
answerCount++;
count++;
}
else
{
cout << "Incorrect answer." << endl;
count++;
}
}
percentScore = ((answerCount) / (double)ANSWERKEY.length()) * 100.0;
cout << "Percent score is " << percentScore << "%" << endl;
}
The exact issue I'm facing is that I can't work out a better way to compare the strings. With the current method, the output is the following:
The intro to the code runs fine. Only when I get to checking the answers against the key, in this case "abcdefabcdefabcdefab", do I run into issues. Regardless of what characters are changed, the program marks roughly half of all characters as mismatching and drops the score down because of it.
I've thought of using a pair of arrays, but then I can't find a solution to setting up the array when some values of it are empty. If the student's answers are too short, e.g. only 15 characters long, I don't know how to compare the blank space, or even store it in the array.
Thank you for any help you can give.
First:
if (studentAnswers == ANSWERKEY)
{...}
else if (studentAnswers != ANSWERKEY)
{ ...}
looks like an overkill when comparing strings. And where is the else part ?
Second, this is risky. Read the IEE754 and articles about cancellation, or even SO:
double answerCount = 0.0;
...
answerCount++
Third:
You are checking character by character using substr. To me it feels like using a hammer to kill a bacteria.
studentAnswers.substr(count, count+1) == ANSWERKEY.substr(count, count+1)
Fourth:
What if studentAnswers is shorter than ANSWERKEY ?
Conclusion:
You need to clarify inputs/expected outputs and use the debugger to better understand what is happening during execution. Carefully check all your variables at each step fo your program.
Is there any difference between the following 2 codes
for (int i = 0; i < 3; i++)
cout << i << endl,
countSteps ++;
and
for (int i = 0; i < 3; i++){
cout << i << endl;
countSteps ++;
}
The comma character has different meaning under different syntactic elements.
In your case, it is a comma operator.
For the sake clarity, the following does not constitute a statement.
cout << i << endl,
The following does.
cout << i << endl,
countSteps ++;
As does the following
cout << i << endl;
A semi-colon ends a statement. A comma does not.
For your posted code, the two blocks of code won't make any difference to the outcome of your program. However, it is good to know the difference between the syntactic constructs.
In general, they can have different behavior based on the value the expressions of the comma operator evaluate to. See https://en.cppreference.com/w/cpp/language/operator_other#Built-in_comma_operator for additional details.
No, there is no difference in this case. (Except for the second snippet not looking ugly.)
In general case, operator, could be overloaded. Then the first option might can cause weird effects.
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main(){
string Whitelist[4] = {"Stian", "Mathias", "Modaser"};
for (int x = 0; x < 3; x++){
cout << x + 1<< ". " << Whitelist[x] << endl;
if (Whitelist[x] == "Stian" && "Mathias" && "Modaser"){
cout << "" << Whitelist[x] << " is here" << endl;
}
else{ cout << "no one is here" << endl; }
}
cin.get();
return 0;
}
//so yeah basically im just trying to loop through my array and see if any of these names are there. so i guess u can pretty much read what the code does since most of u are pros :P. but when i asked my friend, whos been coding for 1-2 years, he said that i couldnt loop through arrays like this and told me to use a vector. what does he mean by that? and my code works?
This set of code is wrong
if (Whitelist[x] == "Stian" && "Mathias" && "Modaser"){
cout << "" << Whitelist[x] << " is here" << endl;
}
Why? because suppose the first condition of the if statement evaluates to true like this:
if (true && "Mathias" && "Modaser")
{
//...
}
Then the code wouldn't make sense. In an if statement, you have to check for every condition separately, like this:
if (Whitelist[x] == "Stian" && Whitelist[x] =="Mathias" && Whitelist[x] =="Modaser"){
cout << "" << Whitelist[x] << " is here" << endl;
}
But since any 1 string cannot be three names at the same time, this condition will fail, (you used &&). Fix your code using the || operator, like this, for your final code (Also, remove << "", that is just redundant, and unnecessary):
if (Whitelist[x] == "Stian" || Whitelist[x] =="Mathias" || Whitelist[x] =="Modaser"){
cout << Whitelist[x] << " is here" << endl;
}
BTW: As a recommendation, use a std::vector<std::string>, not a raw array, so you get easier and more capabilities than an array.
Lastly, you also have 4 elements in your array, of which one is unused. It might be a typo, so make your array size 3.
There is nothing fundamentally wrong with looping over an array like this.
We can only guess what your friend meant, but I can perform my own review of your code.
However, you have four array elements and only loop over three of them, which may be a mistake; if it is, it's evidence that you'd be better off using iterators, rather than hard-coding numbers that you can get wrong.
Furthermore, your if conditional is wrong: did you mean || ("or"), instead of && ("and")? And you have to write out the adjoined conditions in full, so:
if (Whitelist[x] == "Stian" || Whitelist[x] =="Mathias" || Whitelist[x] =="Modaser")
I'm not sure why you're comparing against all these values, when they're the only ones in the array. Well, except for that empty fourth element; perhaps you're trying to catch that. We don't know, because you didn't tell us. Did you mean to search Whitelist while iterating over some other array? We have no way of knowing. Maybe that's what your friend really meant? Again, I couldn't say.
Streaming "" to std::cout just waits resources and does literally nothing else. Remove it.
Finally, and somewhat tangentially, it would be better not to block waiting for input as a means to keep your console window open. That is not your program's job.
I've read a book by Mark Lee, C++ absolute beginner, and one of the code snippet is :
while(true)
{
cout << description.c_str() << "\n\n";
int response = 0;
do
{
cout << "What would you like to do?\n";
if(enemy)
cout << "1) Attack the evil "
<< enemyName.c_str() << "\n";
else if(!enemy)
cout << " 1) Move to the next room.";
if(treasure)
cout << " 2) Pick up the "
<< treasureName.c_str() << "\n";
cin >> response;
}while(response < 1 || response > 2);
switch(response)
{
case 1 : if(enemy)
{
enemy = !enemy;
cout << "You slay the deadly "
<< enemyName.c_str() << "\n";
}
else if(!enemy)
return;
break;
case 2: treasure = !treasure;
cout << "You pick up the "
<< treasureName.c_str() << "\n";
break;
}
}
I think you can ignore about what this program intention is, but the question is, why the part of "while(true)" is exist ? I think, there are no ways out of the loop, right ? Because, I think the "true" value is always return 1, and the "while(true)" part is same with "while(true == 1)", so this loop is like infinity loop, am I wrong or ? Any help is appreciated.
Yes:
this loop is like infinity loop
You're correct in that while(true) is an instruction to loop forever.
However, there are a few other ways to exit loops:
A return statement will exit the function (and consequently also terminate the loop)
A break statement will exit the closest for, while or switch statement.
A goto statement might cause the code to jump to a label outside the loop
An exit() call will cause the whole program to terminate.
A throw statement will throw an exception that will break out to the nearest appropriate catch statement (which might be outside the loop).
In this case, the return; near the bottom of the loop causes the function to exit.
The break; statements do not cause the loop to stop, because they belong to the switch.
A caveat on the use of goto - many programmers consider it poor style, as it can lead to code that is difficult to follow. There is quite a bit of further discussion on this question. In C++, typically throw is more appropriate for situations where goto might be used.
However, there are situations in pure C where goto can be very useful. This answer provides an excellent overview of why goto is historically considered poor style, and even provides some examples of where it might be appropriate to use goto.
Of course, a good rule for beginners might be "pretend goto doesn't exist". Especially in C++.
If you look closely, there is a
return;
statement in the code. This will exit the loop and the function the loop is in.
(This is worth answering since it has fooled at least one 5,000 reputation user and therefore demonstrates the importance of writing code that is clear).
The return statement is the loop terminator. This will exit the function.
It's buried deep within the function. I'd criticise the code therefore for that style: it's hard to follow and difficult to debug.
The only exit from the while(true){...} is the return statement, which terminates the surrounding function.
I don't know the book, but I've never seen another suggestion of writing if statements this redundant way:
if(enemy)
{ ...
}
else if(!enemy)
{...
}
Redundancy is usually to be avoided since it makes maintenance more difficult.
And I very much dislike:
case 2: treasure = !treasure;
cout << "You pick up the "
<< treasureName.c_str() << "\n";
This will let you pick up the treasure, but you stay in the loop and can select '2' once more, telling you "You pick up the x" once more, but negating variable treasure once more. Hmm, let's hope this isn't a full quote from the book!