How to simplify compound negated logic - c

Lets say I have array of boolean values B[], or I am figuring out true/false using function. How can I simplify this code, it there are many values (maybe tens of them)? Here is pseudocode:
if(!B[0]){
doTask1;
}
if(!B[0] && !B[1]){
doTask1;
doTask2;
}
if(!B[0] && !B[1] && !B[2]){
doTask1;
doTask2;
doTask3;
}
...
Edit 1: I forgot to mention, that I want doTask1 etc. happen only once (if any of there ifs is true), not doing it multiple times(if for example 1.st if is true, second one is true too, i still need to happen it only once)

You can use array of function pointers.
typedef void *(* funcPtr)(void);
funcPtr arrayFunPtr[N];
Then store the functions into the array.
arrayFunPtr[0]= task1;
arrayFunPtr[1]= task2;
....
arrayFunPtr[N-1]= taskN;
Then loop the bool array and call respective index function.
for(int i=0;i<N;i++)
{
if(!B[i]) arrayFunPtr[i]();
}
#Edit.
If you want to stop calling tasks function once you hit B[i]=true use the below code.
for(int i=0;i<N && !B[i] ;i++)
{
arrayFunPtr[i]();
}

(Assuming you don't want to make the same task more than once, even though your original code will)
Make a function doTask() which will take the number of the task to do (or just make an array of function pointers). And then:
for(i=0; i < numberOfTasks; i++)
{
if (!B[i])
doTask(i);
else
break;
}
Or more concisely:
for(i=0; i < numberOfTasks && !B[i]; i++)
{
doTask(i);
}

Function pointers is the way to go here.
If you do not like function pointer you might use the switch construct as shown below:
switch(i) {
case 3:
if(!B[0] && !B[1] && !B[2]) doTask3();
case 2:
if(!B[0] && !B[1]) doTask2();
case 1:
if(!B[0]) doTask1();
}
Or you can do :
You can write a method :
simplify(int[] B, int l) {
for (int i =0 ; i < l, i++) {
// write the code using &&
}
}
Then can call this method as :
if(simplify(B, 1){
doTask1;
}
if(simplify(B, 2){
doTask1;
doTask2;
}
etc.

Related

while loop replicating a for loop

Hi im trying to do a disk scheduling algorithm (C-SCAN).I have a for loop with an if statement that works, however im trying to change it to a while loop or another option to remove the break statement.
for(i=0;i<n;i++)
{
if(initial<RQ[i])
{
index=i;
break;
}
}
while ( initial>RQ[i] )
{
index =i;
i++;
}
The above for loop is what im trying to replicate as seen in my while loop. however it is not working the same way.
any help will be much appreciated
A for loop of the form
for (initialization; condition; repetition) {
// body code
}
is equivalent to:
initialization;
while (condition) {
// body code
repetition;
}
So your loop would be rewritten as:
i = 0;
while (i < n) {
if (initial < RQ[i]) {
index = i;
break;
}
i++;
}
One possibility of removing the break statement would be to introduce an additional flag variable which gets set when the loop should be terminated.
#include <stdbool.h>
[...]
bool terminate = false;
for( i=0; i<n && !terminate ; i++ )
{
if(initial<RQ[i])
{
index=i;
terminate = true;
}
}
However, I personally consider it better to use a break statement.

Compare entire array lines for a set of variables

What i am trying to do is simple: i want to compare an entire line of an array in search of a set of variables in order like this:
var[2][]=={1,2,3,4,5} //all at the same time
instead of
var[2][0]==1 && var[2][1]==2 && var[2][2]==3 && var[2][3]==4 && var[2][4]==5 //one by one
or maybe
vartwo[4][3...7]==var[2][] ou vartwo[4][]==var[2][]
void main() {
int i,var[5];
puts("enter values:");
for(;i<5;i++) {
scanf("%d",&var[i]);
};
if(var[]=={1,1,1,0,0,0}) {
//do stuff
} else if (var[]=={1,2,3,5,2}) {
//do something else
}
.
.
.
} else {
//not found
}
}
is there any way i can do that?
Sorry to break but there is no way you can compare two arrays like the way you showed in C.
Simple old looping with element wise comparison is the way out.
for(size_t i = 0; i < len ; i++)
if( arr[i] == anotherarr[i] )
// same
memcmp is an option but unless you can ensure there will be no padding you can't use it reliably.

Shortest code to check if all int array elements are equal to a specific number?

What's the shortest way I can do an if..else statement to check if all int array elements are equal to certain numbers? For example in pseudocode:
if (allElementsOfIntArray == -1)
//do something
else if (allElementsOfIntArray == 1)
//do something else
I have another variable that is const int arraySize
My Arduino code is getting really messy at this point so I'm just trying to find the shortest way to implement this so it doesn't look like a mess to others that have to read it.
bool all_are(int* i_begin, std::size_t sz, int x)
{
const int* i_end = i_begin + sz;
for(; i_begin != i_end; ++i_begin)
if(*i_begin != x) return false;
return true;
}
if (all_are(my_array, arraySize, -1))
//do something
else if (all_are(my_array, arraySize, 1))
//do something else
Check first if all entries are the same and then switch():
for (int i=1; i<arraysize; i++)
if (theArray[0] != theArray[i]) return "no way";
/*** All array elements are the same, so we can evaluate any element ***/
switch (theArray[0])
{
case 0:
return "All are zero";
case 1:
return "All are one";
default:
return "All elements are the same";
}
The quickest way that pops into mind (assuming the array is unsorted) is to just iterate through it and checking each element. You can do this a few ways. Use a normal for loop or try a for each.
Each element in array is independent to others. So you must use for to check all of it to make sure.

Reading correctly from a 2D char array in a function

I canĀ“t read from the char array
This is how I pass the string into my array for each test case and that works fine but passing the array is a problem. I looked it up here: Passing arrays and matrices to functions as pointers and pointers to pointers in C
I still get the warning that I compare between a pointer and an integer.
char klammern[MAX][STRING];
int i, test;
int ergebnis;
printf(" Test cases?:");
scanf("%d",&test);
getchar(); //catch Enter
for(i=0;i<test;i++)
{
fgets(klammern[i],30,stdin);
}
Here is how I pass the argument:
for(i=0;i<test;i++)
{
ergebnis = matching_brackets( klammern );
printf("%d ",ergebnis);
}
My function should count the numbers of brackets and return 1 if not all brackets are closed and 0 if everything is correct.
int matching_brackets(char (*klammern)[STRING])
{
int ergebnis, i;
int runde_klammern = 0;
for(i=0; *klammern[i] != '\n';i++)
{
if( *klammern[i] == '(')
{
runde_klammern++;
}
else if( *klammern[i] == ')')
{
runde_klammern--;
}
ergebnis = runde_klammern;
if ( ergebnis != 0)
{
return 1;
}
else
{
return 0 ;
}
While testing I saw that my for loop in the function read my array like this:
array [1][0]
array [2][0]
...
I want to loop the array like:
array[0][0]
array[0][1]
...
Edit: I do not get the compiler warning anymore after I fixed a typo in my function.
You have two problems, one is that your loop is wrong and the other is an operator precedence problem.
You should loop like e.g.
for (size_t i = 0; i < test; ++i)
{
for (size_t j = 0; klamern[i][j] != '\n'; ++j)
{
// Here `klamern[i][j]` is the current character
}
}
Note that you need to pass the test variable to the function as well.
The above loops also removes the second problem. (that *klamern[i] is seen by the compiler as *(klamern[i]) and not (*klamern)[i]).

Changing the if statement into a while statement

I'm trying to change an if statement into a while statement.
For example
int A=1; if(A==1){};
is similar to int A=1 while(A!=1).
My If statement has no codes, I just need it to do nothing in order to avoid the else-if statements.
My If statement is inside 1 While statement and 1 If statement.
So I want the program to do the same thing in the while statement rather than going in 1 While statement and 1 If statement with an If statement with no code.
Original codes something like this
while(C1)
{
if(C2)
{
if( h->data[temp] < h->data[temp*2] && h->data[temp] < h->data[temp*2+1] )
{
break;
}
else if(C4)
{
DO();
}
}
}
I've changed it to
while( C1 && h->data[temp] > h->data[temp*2] && h->data[temp] > h->data[temp*2+1] )
{
if(C2)
{
if(C4)
{
DO();
}
}
}
and the result is different. The original code gives the correct result but the changed code gives an incorrect result. I've only changed the location to if to while and also changed the direction of the < operator to the > operator.
The total code seems like I've spent less effort in it, making down votes. So I'm posting the code somewhat like a pseudo code.
For example int A=1; if(A==1){}; is similar to int A=1 while(A!=1).
As already mentioned, your loop is breaking. The above statement is also incorrect.
int a = 1;
if(a == 1) {} //this is true, and will happen once
BUT
int a = 1;
while(a != 1) {} //false on entry, skip loop ( never entered )
You could also consider a switch / case if you can isolate the condition.
This might achieve your goal of removing the ifs, and make the code more readable.
e.g
int a = 1;
while(a)
{
switch(a)
{
case 1: ++a; continue;
case 2: do();
default: break; //end loop
}
}
In the original code, if (for example) h->data[temp]>h->data[temp*2] were false, DO() wouldn't be executed, but the loop would continue. In the new version, the loop would stop.
As others said, there is no reason to obfuscate the code with an extra while statement; the original is perfectly clear. There is also no need for the else in your original:
while(C1)
{
if(C2)
{
if( h->data[temp] < h->data[temp*2] && h->data[temp] < h->data[temp*2+1] )
{
break;
}
if(C4)
{
DO();
}
}
}

Resources