For-Loop and Arrays Java - arrays

Can anyone explain to me in words what the code after 'for' exactly means? I'm confused with the mixing of int and booleans within 'for' (still a beginner). It's about checking whether two arrays have the same values in the same sequence. Thanks in advance:
public static boolean equal(int[] a1, int[] a2) {
if (a1.length != a2.length) {
return false;
} boolean equal = true;
for (int i = 0; i < a1.length && equal; i++) {
equal &= a1[i] == a2[i];
}
return equal;
}

The for loop consists of 4 parts:
for(initialisation; condition; increment/decrement) {
body
}
Where initialisation is the part where you initialise variables which are in scope throughout the loop.
Condition is the boolean expression which if evaluated to true results in the execution of the body.
Increment/decrement is where you may change the value of any variable in the loop scope.
All 3 parts after the for keyword are optional, so you could create an infinite loop as shown:
for(;;) {
System.out.println("body");
}

The line equal &= a1[i] == a2[i]; is using the &= (logical-and assignment) operator, which is the same as equal = equal & (a1[i] == a2[i]);. It combines the logical-and with the assignment operator. This line can be parsed like this:
bool = (itself) AND (int == int)
bool = (itself) AND (another bool)
bool = (some bool value)
Be very careful with the & operator, since it has two different meanings. It means logical-AND for boolean types, but bitwise-AND for numeric types. To make it clearer to read, use equal = equal && a1[i] == a2[i]; which also has the upside of short-circuit operation (which can save a few unnecessary comparisons).
On another note, there are a few redundancies in this loop.
boolean equal = true;
for (int i = 0; i < a1.length && equal; i++) {
equal &= a1[i] == a2[i];
}
The looping condition checks that the array still has elements AND that the previous element(s) have all matched. Since the looping condition is also checking the boolean equal, there is no need to use the compound and-assignment operator. A simple equal = a1[i] == a2[i]; would work and even save the unnecessary (true) & (something) operation every loop iteration. This works because the looping condition guarantees that equal == true, since the loop will stop execution otherwise.

Related

Code review in C regarding bools and if/else if

I came up with this solution with some help regarding the CS50 Week 2 Problem set password. The prompt is to use 2 function to come up with a simple password checker, verifying an input string has 1 uppercase letter, 1 lowercase letter, 1 number, and 1 symbol. The suggestion was to use bools. However, I have 3 questions on how and why this works:
Bools... I still am struggling with them. Why don't I have to put the =true part? Are bools just assumed to have to be true?
Doing some research, I understand now that the last statement in an if clause doesn't have to be else, because that can't be specified. But why does one if and three else if work? I originally anticipated that it would be a sort of nested if statements instead.
Does the bool valid(string password) function take false and true as input because it's defined as using bool?
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
bool valid(string password);
int main(void)
{
string password = get_string("Enter your password: ");
if (valid(password))
{
printf("Your password is valid!\n");
}
else
{
printf("Your password needs at least one uppercase letter, lowercase letter, number and symbol\n");
}
}
bool valid(string password)
{
bool haslower = false;
bool hasupper = false;
bool hasdigit = false;
bool haspunct = false;
int i;
for (i = 0; password[i] != '\0'; i++)
{
if (isupper(password[i]))
{
hasupper = true;
}
else if (islower(password[i]))
{
haslower = true;
}
else if (isdigit(password[i]))
{
hasdigit = true;
}
else if (ispunct(password[i]))
{
haspunct = true;
}
}
if (hasupper && haslower && hasdigit && haspunct)
{
return true;
}
return false;
}
Bools... I still am struggling with them. Why don't I have to put the =true part? Are bools just assumed to have to be true?
I assume you are actually asking why you don't have to do == true as in if(hasupper && haslower). This isn't really related to the bool type as such, but to the if and similar selection statements in C. Any plain variable or pointer type passed to these gets evaluated as "if non-zero then true, otherwise false". Similarly the logic operators like == return either 1 or 0. This goes way back to a time before C even had a bool type.
However, it is considered good style to only use variables of type bool in that manner. if(mybool) is ok some coding standards frown at code such as if(mypointer) and instead encourage to be explicit if(mypointer != NULL).
Also note that the bool type in C has the built-in ability to convert any non-zero integer value into true/false. So bool b=123; results in true (which in turn equals 1).
Doing some research, I understand now that the last statement in an if clause doesn't have to be else, because that can't be specified. But why does one if and three else if work? I originally anticipated that it would be a sort of nested if statements instead.
else is always optional at the end of an if. Now as it happens, there is actually nothing in C called else if, it's just a very common coding style convention. Each else always belongs to the previous if, so your code is actually using else, and it can be rewritten 100% equivalent (but harder to read) like this:
// harder to read
if (isupper(password[i]))
{
hasupper = true;
}
else
if (islower(password[i]))
{
haslower = true;
}
else
if (isdigit(password[i]))
{
hasdigit = true;
}
else
if (ispunct(password[i]))
{
haspunct = true;
}
This works because every if or else can accept one statement on the next line without braces. You could type out the braces explicitly too, but that's even less readable:
// even harder to read
if (isupper(password[i]))
{
hasupper = true;
}
else
{
if (islower(password[i]))
{
haslower = true;
}
else
{
if (isdigit(password[i]))
{
hasdigit = true;
}
else
{
if (ispunct(password[i]))
{
haspunct = true;
}
}
}
}
The else if coding style convention reduces the amount of indention and braces, so it is very widely used as a "de facto" standard coding style. (In fact it is one of the very few style-related matters that all C programmers agree on.)
Does the bool valid(string password) function take false and true as input because it's defined as using bool?
The type in front of the function name declares the return type (output) from the function. The input to the function is specified by the parameters, in this case string password. Which is CS50's dysfunctional way of writing char* password. An even better way would be to use const correctness - since this function shouldn't modify the string, it should be declared as bool valid (const char* password);.
You can also eliminate the if/else use entirely by assigning the result of the comparison directly to the variable, because the result of a comparison operation is a value that can be assigned, just like x + 5 can be assigned:
bool valid(const char *password)
{
bool haslower = false;
bool hasupper = false;
bool hasdigit = false;
bool haspunct = false;
for (int i = 0; password[i] != '\0'; i++)
{
hasupper = hasupper || isupper(password[i]);
haslower = haslower || islower(password[i]);
hasdigit = hasdigit || isdigit(password[i]);
haspunct = haspunct || ispunct(password[i]);
}
return(hasupper && haslower && hasdigit && haspunct);
}
The code does have to be more complex than just has* = is*(password[i]); because once any of the has* variables are true it has to remain true. Each new value of the has* variables from each char of password has to be or'd with the previous value of that has* variable.
And because the || operator short-circuits, once any of the has* variables is true, the corresponding is*() function doesn't need to be and won't be called any more.
C does not have any ||= compound operator, so you can't write
hasupper ||= isupper(password[i]);
You could use the bitwise-or compound operator |=, though
hasupper |= isupper(password[i]);
although that doesn't short-circuit and the use of bitwise operators on bool values probably isn't good style. One reason it's bad style is there's a critical difference in the symmetry between the || and |= operators and the && and &= operators.
Both the || and |= operators will "carry through" a true value as used above because any setting of a non-zero value or bit will always carry through to a true end result: both 0 || 1 and 0 | 2 are true. But if you want to check if all characters are upper case, for example, &= is not equivalent to &&: 1 && 2 is true, but 1 & 2 is false.
Bool or boolean is a primitive data type. There are only two possible values, true or false, which can be denoted as 1 or 0. Booleans are used to denote whether something is true or not, yer or no, and in this case, either it is a valid password or its not. Google more about this.
end? or else? if statements have the option to be chained together using elseif where the predicate is checked through several conditional statements. For example, lets say the predicate is age. If you "age < 21 no alcholo, else yes alcohol" In this case you only need 2. What if you want to check whether a student qualifies for an award and you must check several conditions to see if each are met. If statements aren't required to be chained but they can very well be if needed. They can be nested within other ifs, loops as well and much more. Google what you don't understand and gravitate towards official documentation after a while.
No, Bool is the return type. The function either returns true or false. The parameter takes in a string. So it takes in a set of characters and in this case a password.
You can call the function, or invoke the function in main or any other user defined function by calling the function valid and passing in a string argument. The argument MUST be a string not a bool. The function determines whether the password is indeed a valid password based on the conditional requirements you specified in your if statements. I'm surprised you wrote this but don't understand it but don't give up. Feel free to ask more questions. Be more specific about the lines you refer to next time as well!
Are you watching the shorts from cs50 provided by Doug? They are very useful in helping explain the material further.
Again, lots of jargon here, but google words and concepts you don't understand.
Best of luck!

Which condition is true in While?

Sorry if this is too simple. I want to know which of the conditionals is happening exactly. Is there a way more able to capture this without repeating them inside the block with if structures? I am using C language.
while ( l < 0 || l > 2 || c < 0 || c > 2 )
You could use comma expressions, i.e. something like (expr1,expr2), which are always evaluated left to right with a sequence point at each ,; So you may rely on that expr1 is evaluated before expr2, whereas the latter serves as the comma expression's result then.
With that, the following should work, and x will bee in the range of 0..3, depending on which condition got true:
int x;
while ( (x=0,l < 0) || (++x,l > 2) || (++x,c < 0) || (++x,c > 2) )
You can assign them "on the fly" to previously declared variables:
bool ll0, lg2, cl0, cg2;
while((ll0 = l<0) || (lg2 = l>2) || (cl0 = c<0) || (cg2 = c>2)) {
if(ll0) {
// l is less than 0
} else if(lg2) {
// l is greater than 2
} else if(cl0) {
// c is less than 0
} else if(cg2) {
// c is greater than 2
}
// ...
}
Notice the if-else chain, as, since the || operator short-circuits (i.e. the second operand isn't even evaluated if the first is already true), if e.g. ll0 is true the other values aren't going to be correctly assigned.
That being said, to be honest I wouldn't bother - just repeat the conditional, if these are just integer variables these comparisons aren't going to cost you anything (actually, the compiler may even keep around the comparison value in some cases and recycle it).
You could use a loop without conditions, compute conditions in loop, and break if any of the conditions is true.
while (1) // or for(;;)
{
bool one = l < 0;
bool two = l > 2;
bool three = c < 0;
bool four = c > 2;
if (one || two || three || four) break;
// bool variables are available there
}
If you want to get access to all conditions, you cannot use short-circuiting evaluation for them. So make sure you really want to store them beforehand.

What is the purpose of ";" at the end of for loop?

I found the following code:
int func_prim (int zahl) {
int count;
if (zahl < 0)
return -1;
for (count = 2; zahl % count != 0 && zahl >= count; count++);
if (count == zahl)
return 1;
return 0;
}
The point of function is to check whether a number is a prime number or not.
I don't understand why the for-loop has ; at the end:
v
for (count = 2; zahl % count != 0 && zahl >= count; count++);
Without that, the code doesn't work properly.
What is the explanation?
It means exactly the same as:
for(count = 2; zahl % count != 0 && zahl >= count; count++)
{
}
A for loop has the for keyword, followed by parentheses containing three optional expressions separated by semicolons, followed by a body which executes in each iteration of the loop.
The goal of the for loop in your example is to set the value of count, which will be compared to zahl in the if statement that follows. This is achieved in the semicolon-delimited expressions, so the loop body doesn't need to do anything.
Since the loop doesn't need to do anything, it uses the empty statement as its body.
If the ; at the end were omitted and no other changes were made, then the if statement after the for loop would itself become the body of the for loop. (That is not intended and would break the program, as you have observed.)
However, making one's loop body consist of a single ; on the same line is not the only way to write an empty loop body, nor is it probably the most sensible way to do so. It works perfectly well, but the problem is that other readers - and perhaps the same programmer, returning to the project later - may wonder if it was actually an error. After all, one types semicolons at the ends of lines quite often when coding in a C-style language, so it's easy to type an extra one where it doesn't belong.
The other problem is that, in code where a one-line loop with ; as its body is the chosen style, it is difficult to recognize when someone actually has made the mistake of putting a ; when one doesn't belong.
Therefore, these alternatives may be preferable:
putting the ;, indented, on the next line -- as sh1 suggests
writing the loop body as an empty block, { }, rather than an empty statement
making the loop body a continue; statement, which simply causes the loop to move on to its next iteration (which is the same as what happens when the loop body is empty) -- also as sh1 suggests
The semicolon at the end of the for-loop means it has no body. Without this semicolon, C thinks the if statement is the body of the for loop.
Syntax of for loop (iteration statement) is
for ( clause-1 ; expression-2 ; expression-3 ) statement
statement can be a null statement (;). C11 6.8.3 says
A null statement (consisting of just a semicolon) performs no operations.
In para 5 it gives an example
In the program fragment
char *s;
/* ... */
while (*s++ != '\0')
;
a null statement is used to supply an empty loop body to the iteration statement.
Same thing is happening in
for (count = 2; zahl % count != 0 && zahl >= count; count++);
; is used to supply an empty loop body to the for statement. Without ; the statement next to the for loop will be considered as its body and will be executed.
In addition to what the other excellent answers already say, I would like to point out that
for(count=2; zahl % count != 0 && zahl >= count; count++);
(that is, a for loop with an empty statement used to increment a "counter") is equivalent to
count=2;
while(zahl % count != 0 && zahl >= count)
{
count++;
}
that would make the objective of the code even clearer than some of the listed alternatives: if not comments are present, as in the presented case, a loop with an empty statement might confuse another programmer that has to mantain or use the code (as was the case with the OP here).
The context might help discerning the true scope of the statement, but between a for loop with an empty statement and a while loop with a statement, the latter requires less work to understand its scope.
The ; after the for loop simply means that the for loop won't do anything more than increase the counter count.
for Statement:
The for statement is a loop statement whose structure allows easy
variable initialization, expression testing, and variable
modification. It is very convenient for making counter-controlled
loops. Here is the general form of the for statement:
for (initialize; test; step)
statement
[...]
Null Statement:
The null statement is merely a semicolon alone.
;
A null statement does not do anything. It does not store a value anywhere.
It does not cause time to pass during the execution of
your program.
Most often, a null statement is used as the body of a loop statement,
or as one or more of the expressions in a for statement. Here is an
example of a for statement that uses the null statement as the body of
the loop (and also calculates the integer square root of n, just for
fun):
for (i = 1; i*i < n; i++)
;
Here is another example that uses the null statement as the body of
a for loop and also produces output:
for (x = 1; x <= 5; printf ("x is now %d\n", x), x++)
;
A null statement is also sometimes used to follow a label that would
otherwise be the last thing in a block.
In your case, the ; is the Null Statement of the for Statement:
int func_prim (int zahl) {
int count;
if (zahl < 0)
return -1;
for (count = 2; zahl % count != 0 && zahl >= count; count++)
;
if (count == zahl)
return 1;
return 0;
}
Without it, the if becomes the for statement:
int func_prim (int zahl) {
int count;
if (zahl < 0)
return -1;
for (count = 2; zahl % count != 0 && zahl >= count; count++)
if (count == zahl)
return 1;
return 0;
}
Therefore, behaving differently.
The for loop is there just to increase the value of count.
a for loop will (normally) have a body,
where the body is enclosed in braces { }
However, for a single statement body, the braces are optional.
; is an empty statement.
Combining the above it becomes obvious that the for loop executes until the condition becomes false.
The for loop is basically looping through all the numbers that are less than or equal to zahl but greater than 2 and storing it in the variable count. As it loops through all these numbers it is checking to see if zahl is divisible by count. If zahl is divisible by count, the loop is stopped. Otherwise, the loop is stopped when count equals zahl.
The if statement after the for loop checks to see if count is equal to zahl. If it is, then that must mean that the loop went through all the numbers less than zahl and greater than 2. This means that zahl is divisible by all the numbers less than itself and greater 2, which makes zahl prime.
It indicates the statement the for loop is used for. It can't be empty. At least it should include a single statement. ; is the empty statement which the iteration is done for.

if-else condition in C

In C language, what is the result of x=0 if I put it in if-else condition? if it is represent false or if this assignment is finished, then represent true?
my colleague write code as:
if(condition = 0)
{
//do process A
}
else
{
// do process B
}
obviously, this code is wrong, I know it should be condition == 0 or ((condition=foo()) == 0) but my assumption is program should always do process A because i think if(condition = 0) should always return true since this is set value 0 to variable condition and this set process should be true. However, program always do process B, that means if use the variable condition value and my assumption is wrong.
Then I did a another test code:
if(condition = 2) //or other none-zero value
{
//do process A
}
else
{
// do process B
}
this time, program always do process A.
My question is why if-else condition does not use the operation value of condition but use the left variable after setting?
when you assign 0 to variable condition it becomes false as 0 represents false and any non-zero value represents true.so, when you assign 0 else condition is executed and when you assign 2 condition represents a true statement so, it executes...
if(condition = 0)
after assigning value 0 to condition it becomes
if(condition)
and as it is false, it doesn't execute.but, when condition = 2, it works in the same way and become true .so, the if condition is executed then.
You use wrong operator.
a = 10;
The "equals" operator means "assign value to".
Now to compare two operands, a and b, to see if a = b, you use another operand.
That operand is double equals (==).
if(variable == 0)
{
//do process A
}
else
{
// do process B
}
Now look.
If the variable with name "variable" has value = 8 that is not equal to 0,
thus the whole "variable == 0" expression if FALSE.
So proccess B will run.
If otherwise variable is equal to 0 indeed, proccess A will be executed because "variable == 0" is true.
It's like:
if(EXPRESSION)
{
// EXPRESSION IS TRUE
}
else
{
//EXPRESSION IS FALSE
}
Got it? :)
In C, assignment is an expression that returns the set value; i.e. x = 2 will result in 2.
This allows you to do something like this:
unsigned char ch;
while((ch = readFromFile(f)) != EOF) {
// do something with ch
}
It also allows you to shoot yourself in the foot if you accidentally mistype == as =, which is why this 'feature' doesn't appear in a lot of other languages.
In your first loop, the expression condition = 0 will always result in 0, causing the else branch to be taken. Similarly, condition = 2 results in 2, which causes the true branch to be taken.

Assigning value in while loop condition

I found this piece of code on Wikipedia.
#include <stdio.h>
int main(void)
{
int c;
while (c = getchar(), c != EOF && c != 'x')
{
switch (c)
{
case '\n':
case '\r':
printf ("Newline\n");
break;
default:
printf ("%c",c);
}
}
return 0;
}
I'm curious about expression used as condition for while loop:
while (c = getchar(), c != EOF && c != 'x')
It's quite obvious what it does, but I've never seen this construction before. Is this specific to while loop? If not, how does parser/compiler determine which side of comma-separated expression returns boolean value for while loop?
The comma operator is a binary operator that evaluates its first operand and discards the result, it then evaluates the second operand and returns this value.
It is also a "sequence point", which means that all side effects will be calculated before the next part of the code is executed.
The comma operator is a weird beastie until you get to understand it, and it's not specific to while.
The expression:
exp1, exp2
evaluates exp1 then evaluates exp2 and returns exp2.
You see it frequently, though you may not realize it:
for (i = j = 0; i < 100; i++, j += 2)
You're not actually using the return value from "i++, j += 2" but it's there nonetheless. The comma operator evaluates both bits to modify both i and j.
You can pretty well use it anywhere a normal expression can be used (that comma inside your function calls is not a comma operator, for example) and it's very useful in writing compact source code, if that's what you like. In that way, it's part of the family that allows things like:
while ((c= getchar()) != EOF) {...}
i = j = k = 0;
and so on.
For your specific example:
while (c = getchar(), c != EOF && c != 'x')
the following occurs:
c = getchar() is executed fully (the comma operator is a sequence point).
c != EOF && c != 'x' is executed.
the comma operator throws away the first value (c) and "returns" the second.
the while uses that return value to control the loop.
In many languages the comma is an operator that always results in the value of the second operand. The operands are evaluated sequentially from left to right.
Pseudo-code:
a = 10
print a = 7 + 8, a * 2
Note: print is considered a statement that does not take arguments, so what comes after is considered the single expression a = 7 + 8, a * 2.
Executed like this:
First line
put 10 in a
Second line
evaluate 7 + 8 (15)
put evaluated value (15) in a
evaluate a * 2 (30)
evaluate , operator with operands 15 and 30:
always value of second operand (30)
print evaluated value (30)
To expand a bit on the other answers, in this code:
EXPRESSION_1 , EXPRESSION_2
EXPRESSION_1 is first evaluated, then there is a sequence point, then EXPRESSION_2 is evaluated, and the value of the whole thing is the value of EXPRESSION_2.
The order of operation guarantee and the sequence point are both important to the code you quoted. Together, they mean that we can be certain that the getchar() function gets called and the value of variable c is fully updated before the value of c is tested.
The comma is an operator. It returns the value of the right hand expression by default. The order of evaluation is guaranteed to be left first and then right.
UPDATE (reply to Pax's comment):
Just like most operators, it can be overloaded for user defined types:
#include <iostream>
#include <string>
using namespace std;
enum EntryType { Home, Cell, Address };
class AddressBookEntryReference {
public:
AddressBookEntryReference(const string& name, const EntryType &entry)
: Name(name), Entry(entry) { }
string Name;
EntryType Entry;
};
AddressBookEntryReference operator,(const string& name, const EntryType &type) {
return AddressBookEntryReference(name, type);
}
class AddressBook {
string test;
public:
string& operator[](const AddressBookEntryReference item) {
// return something based on item.Name and item.Entry.
// just to test:
test = item.Name;
return test;
}
};
int main() {
// demo:
AddressBook book;
cout << book["Name", Cell] // cool syntax!
<< endl;
}

Resources