In C language, comparing 2 members of a structure - c

I seem to have trouble with comparing 2 members of a structure.
I can see in watch window that the sequence in all logs are 0x000.
This one evaluates AllLogsNotZero to TRUE
for (i=0;(i<(3)&&(!AllLogsNotZero));i++)
{
UINT8 j;
j=i+1;
UINT16* comp1;
UINT16* comp2;
comp1 = (UINT16*) (&Data.log[i].Sequence);
comp2 = (UINT16*) (&Data.log[j].Sequence);
if ((Data.log[i].Sequence == Data.log[j].Sequence) == 0)
AllLogsNotZero=FALSE;
else
AllLogsNotZero=TRUE;
This one evaluates AllLogsNotZero to FALSE
for (i=0;(i<(3)&&(!AllLogsNotZero));i++)
{
UINT8 j;
j=i+1;
UINT16* comp1;
UINT16* comp2;
comp1 = (UINT16*) (&Data.log[i].Sequence);
comp2 = (UINT16*) (&Data.log[j].Sequence);
if (Data.log[i].Sequence == Data.log[j].Sequence)
AllLogsNotZero=FALSE;
else
AllLogsNotZero=TRUE;
I don't know why.

I think you're making a mountain out of a molehill. I think the way I'd write the loop using your current variable name is:
bool AllLogsNotZero = true;
for (int i = 0; i < 4; i++)
{
if (Data.log[i].Sequence == 0)
{
AllLogsNotZero = false;
break;
}
}
if (AllLogsNotZero)
…processing option for no zero logs
else
…processing option for at least one log zero
We can debate whether the loop limit should be 3 or 4 (or some other value); it isn't entirely clear from your code, but you set j to i+1 and use that, and limit i to < 3, so when the code doesn't use i+1, the limit should probably be 4. It would be better to have an enumeration or #define value for the limit — the name would indicate what you're measuring against better than just the number.
The negative in the name (AllLogsNotZero) also makes life harder; avoid that when you can. For example:
bool LogsZero = false;
for (int i = 0; i < 4; i++)
{
if (Data.log[i].Sequence == 0)
{
LogsZero = true;
break;
}
}
if (LogsZero)
…processing option for at least one log zero
else
…processing option for no zero logs

Look if statements
First check:
//You check if they are the same
if (Data.log[i].Sequence == Data.log[j].Sequence)
Second check
//You check if they are not the same
if ((Data.log[i].Sequence == Data.log[j].Sequence) == 0)
//Can be evaluated as:
if (Data.log[i].Sequence != Data.log[j].Sequence)

for (i=0;(i<(3)&&(!AllLogsNotZero));i++)
{
UINT16 Var1 = 0;
if (Data.log[i].Sequence == Var1)
AllLogsNotZero=FALSE;
else
AllLogsNotZero=TRUE;
This works!!

Related

Error C2360 Initialization of "arr2" is skipped by "case" tag

I am new to programming.
This is a C language program.
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdbool.h>
#define ture 1
#define false 0
void add(int m, int* arr,int n)
{
if (n == 32) return;
arr[n] += m;
if ( arr[n] > 1)
{
arr[n] = 0;
add(m, arr, ++n);
}
return;
}
int main(void)
{
int T,n,r,m,i,j,k;
bool check = ture;
scanf("%d", &T);
while (T--)
{
scanf("%d%d", &n, &r);
switch (r)
{
case 10:
printf("%d", n);
break;
case 2:
int arr2[32] = { 0 };
if (n > 0)
{
for (i = 0; i < 32 ; i++)
{
arr2[i] = n % 2;
n = n / 2;
}
for (j = 31; j >= 0; j--)
{
if (arr2[j] == 0 && check == ture) continue;
else
{
check = false;
printf("%d", arr2[j]);
}
}
}
else if (n == 0)printf("%d", 0);
else if (n < 0)
{
n = -n;
for (i = 0; i < 32; i++)
{
arr2[i] = n % 2;
n = n / 2;
}
for (k = 0; k < 32; k++)
{
arr2[k] = !arr2[k];
}
add(1, arr2, 0);
for (j = 31; j >= 0; j--)
{
if (arr2[j] == 0 && check == ture) continue;
else
{
check = false;
printf("%d", arr2[j]);
}
}
break;
}
case 8:
int arr8[11] = { 0 };
if (n > 0)
{
for (i = 0; i < 11; i++)
{
arr8[i] = n % 8;
n = n / 8;
}
for (j = 10; j >= 0; j--)
{
if (arr8[j] == 0 && check == ture) continue;
else
{
check = false;
printf("%d", arr8[j]);
}
}
}
}
}
return 0;
}
When I run the program in VS2022.There is a bug.
Error C2360 Initialization of "arr2" is skipped by "case" tag Project5 C:\code\C\C_Single\Project5\Project5\test.cpp 74
I don't understand why this is happening.
In my opinion,when I select the contents of case8, I don't need the contents of case2, certainly,including the declaration of arr2.But obviously the compiler doesn't think that way.
So I turn to google for help.
However,google tells me something like this.
Your search - Error C2360 Initialization of "arr2" is skipped by "case" tag - did not match any documents.
Suggestions:
Make sure that all words are spelled correctly.
Try different keywords.
Try more general keywords.
Try fewer keywords.
So I want to get help in stackoverflow.Can anyone help me?
This is one reason that goto statements are frowned upon in modern code.
A case label is not much more that a regular label, and the switch will do something like:
if(value==2) goto label2;
if(value==3) goto label3;
etc.
But when you declare an array like:
int arr[10];
or actually any variable that goes on the stack, the compiler needs to increase the stack pointer to make space for that. in this case:
sp += 10 * sizeof(int)
(Of course this depends on your system/compiler etc)
So what happens if you put this piece of code, in between to (case) labels...
label2:
//int arr[10];
sp += 10*sizeof(int);
label3:
...
// end of scope for arr
sp -= 10*sizeof(int);
// or not?
Yeah it happens only half the time. So now you end up at the end of you switch statement, and your compiler doesn't know weather to decrease the stack pointer or not.
The compiler warns you that the initialization of the array arr2 can be skipped if the control will be passed to the label case 8:. In this case the array will have indeterminate values.
To avoid the compiler message just enclose statements after labels in braces creating a compound statement like for example
case 2:
{
int arr2[32] = { 0 };
//...
}
You have several problems here, within your switch(). (I'm just going to focus on that.)
Firstly, declaring variables within case clauses is problematic: providing them with initialisers, even more so. If you enclose the entire case clause within curly braces, that's a lot better. You also constrain the scope of your case-dependent variables to within that specific case.
Secondly, you have a significant logic error in your switch() statement. Your case 2: clause only hits a break in the n < 0 instance: in all others, it will fall through to case 8:. This is very clearly incorrect.
Thirdly, your case 8: clause has no break statement. As it's the last in the switch(), that's benign - you'll "fall out the bottom", but it's bad practice.
Finally, there is no default: clause. In just about every situation you use a switch() you want to catch the default: case, as it's either going to need a default handling, or it indicates an error condition.
In summary: brace your case clause code, so you can do as you with with, and scope, the variables you declare, and be rigorous about break and default: use. You'll thank me in the future!

For loop instead of long if condition in order to reduce computing time

I have some code that looks like shown below. I have simplified it to get my point across. It contains an array. In the first part each value of the array minus a certain value shall be compared to a margin value.
If all of the conditions are met the µC should stop run a simple function.
Else the µC should run a calculation with the values of the array. This calculation has a few multiplications that are run for every value.
uint32_t value[8];
uint16_t othervalue;
if ((value[0] < othervalue && value[1] < othervalue && value[2] < othervalue && value[3] < othervalue && value[4] < othervalue && value[5] < othervalue && value[6] < othervalue && value[7] < othervalue)
{
othervalue = 100;
simplefunction();
}
else
{
calculatewithallvalues(values);
}
I have noticed that i could probably improve the code. The calculations in the "else" only need to be done if the condition for that specific value is not met. Therefore in certain cases the calculation does not have to be done for every value. I came up with a different approach using a for loop. However, this code is longer an maybe more confusing. The extra if loop at the end is needed to account for the possibility that all values meet the condition.
uint32_t value[8];
uint16_t othervalue;
uint8_t calc_needed = 0;
int i;
for (i=0; i <7; i++)
{
if (value[i] < othervalue)
{
//do nothing
}
else
{
calculatewithvalue(values[i]);
calc_needed = 1;
}
if (calc_needed == 0)
{
othervalue = 100;
simplefunction();
}
Which is the better solution or is there a third solution?
There is a third solution:
for(i=0; i < 7; i++) {
if (value[i] < othervalue ) continue;
break;
}
if (i == 7) { // loop completed; all values were below othervalue
othervalue = 100;
simplefunction();
}
else {
calculatewithallvalues(values);
}

How do I get the integer method "guess" to go into another method as an array?

else {
masterNum[3] = guess % 10; //checks integers in their respective positions
masterNum[2] = ((guess - guess%10)/10)%10;
masterNum[1] = ((guess - guess % 100)/100)%10;
masterNum[0] = (guess - guess % 1000)/1000;
masterDigit(guess, masterNum);
}
//}
//This method determines the total number of correct digits but not
//necessarily in the correct position
public static int masterDigit (int [] guess,int [] code) //int [] guess
{
int i,j,k,number;
int [] tempGuess = new int [4]; //an array to hold a copy of a code
boolean found;
number = 0;
for(k=0; k<4; k++) //copies code to tempGuess so code
//doesn't get changed (you can't just assign code to tempGuess)
tempGuess[k] = code[k];
for(i = 0; i < 4; i++)
{
j=0;
found = false;
while(j < 4 && found == false) // a while loop instead of a
// for loop so duplicates are only counted once
{
if(guess[i] == tempGuess[j])
{
found = true;
tempGuess[j] = -1; // fills up tempGuess with an impossible
// value so that index only gets
// counted once
number++;
}
j++;
}
}
return number;
}
This code is for a Mastermind game with integers. Upon running through the compiler, there is an error saying that integer "guess" cannot be converted to an array. How can I get my guess (defined as an integer scanner console) to go into this method that will check which numbers are correct?

Function Warnings in C

Hello guys i have threefunctions for which i get 4 warnings...!!
The first one is this
void evaluatearxikos(void)
{
int mem;
int i;
double x[NVARS+1];
FILE *controlpointsarxika;
controlpointsarxika = fopen("controlpointsarxika.txt","r");
remove("save.txt");
for(mem = 0; mem < POPSIZE; mem++)
{
for(i = 0; i < NVARS; i++)
{
x[i+1] = population[mem].gene[i];
}
rbsplinearxiki();
XfoilCall();
population[mem].fitness = FileRead();
remove("save.txt");
}
fclose(controlpointsarxika);
}
For this one the compiler warns me tha variable x is set but not used...!! But actually i am using the variable x...!!!
The second function is this one...
void elitist(void)
{
int i;
double best,worst;
int best_mem,worst_mem;
best = population[0].fitness;
worst = population[0].fitness;
for(i = 0; i < POPSIZE - 1; i++)
{
if(population[i].fitness > population[i+1].fitness)
{
if(population[i].fitness >= best)
{
best = population[i].fitness;
best_mem = i;
}
if(population[i+1].fitness <= worst)
{
worst = population[i+1].fitness;
worst_mem = i+1;
}
}
else
{
if(population[i].fitness <= worst)
{
worst = population[i].fitness;
worst_mem = i;
}
if(population[i+1].fitness >= best)
{
best = population[i+1].fitness;
best_mem = i+1;
}
}
}
if(best >= population[POPSIZE].fitness)
{
for(i = 0; i < NVARS; i++)
{
population[POPSIZE].gene[i] = population[best_mem].gene[i];
}
population[POPSIZE].fitness = population[best_mem].fitness;
}
else
{
for(i = 0; i < NVARS; i++)
{
population[worst_mem].gene[i] = population[POPSIZE].gene[i];
}
population[worst_mem].fitness = population[POPSIZE].fitness;
}
}
For this one i get two warnings that the variables worst_mem and best_mem may be used uninitialized in this function..!! But i initialize values to both of them..!!
And the third function is this...
void crossover(void)
{
int mem,one;
int first = 0;
double x;
for(mem =0; mem < POPSIZE; mem++)
{
x = rand()%1000/1000;
if(x < PXOVER)
{
first++;
if(first%2 == 0)
{
random_Xover(one,mem);
}
else
{
one = mem;
}
}
}
}
For which i get that the variable one may be used unitialized..!! But it is initialized..!
Can you please tell me what is wrong with these functions...??
Thank you in advance
In your first function, you set (assign) x, but you never read it, hence you are not using it... you're only wasting CPU cycles by writing to it. (Note also that because you index it as i+1 you write beyond the space you've allocated for it).
In the second function, your initializations to those variables are in conditional blocks. You can see that (perhaps? I didn't verify) in all conditions they are initialized but your compiler isn't that smart.
In your third function, it does appear that one could be refered to without having first been initialized.
First: You set x but do not use it. It's a local variable that gets set but it's dropped as soon as the function returns.
Second: There might be values that makes it so that your best_mem/worst_mem never gets set in your if/else, but you are using them later on. If they haven't been set, they contain garbage if not initialized.
Third: While it shouldn't happen that you try to use an uninitialized variable in your code, it still looks weird and compiler doesn't see that it won't happen first time.
When you get compiler warnings, treat is as you are doing something wrong or rather not recommended and that it could be done in a better way.
The x variable is only used on the left hand side (i.e. assigned a value). You are not using that value on the right hand side or pass it to a function.
It may be possible to get to the end of the loop for(i = 0; i < POPSIZE - 1; i++) without those variables given a value. Why not set them in the declaration.
The call to random_Xover(one,mem); could be called when one is not set. Change the line int mem,one; to int mem,one = <some value>;

Varying arguments for if () statement

I have a problem as stated below:
i have an array(say) a[]={10,24,56,33,22,11,21}
i have something like this
for(i=0;i<100;i++){
if(a[i]==10)
// do something
}
next when i=1
if(a[i]==10 && a[i+1]==24)
so on so at each iteration the arguments / conditions within if should be varying
now this will be a very big sequence i cant explicitly write
if(a[i]==10 && a[i+1]==24 && a[i+2]==56 ...... a[i+100]=2322)
how can i achieve this varying conditions?
You have to have a cumulative "boolean" variable that checks a[i] at the i-th iteration and update that variable:
int a[] = {...}; /* array with some values to verify */
int v[] = {...}; /* these are the actual desired values in a[] */
/* the verifying loop */
int i;
int cond = 1;
for (i = 0; i < 100; i++)
{
cond = cond && (a[i] == v[i]);
if (cond)
{
/* do something */
}
}
I think that you should introduce a boolean value.
bool valid = true;
for(i=0;i<100;i++){
if(a[i]==10 && valid)
// do something
else
{
valid = false;
break;
}
}
For every iteration, you need to change the value to which you are comparing a[i]
Have a loop within a loop:
for (i = 0; i != 100; ++i)
{
int condition = 1;
for (j = 0; i + j != 100 && condition; ++j)
{
condition = condition && (a[i + j] == /* your number */ );
}
if (condition) { /* ... */ }
}
In this case, you can use function pointers or blocks.
You can find a good example here here
Seeing your examples, I think that the variations you are talking about is only in the length of array 'a' whose presence you want to check in some array x. If indeed it is so, memcmp can be of use to you.
Let me modify your example a bit to clarify what I am saying.
int a[7]={10,24,56,33,22,11,21} is the required values you want to check in some array 'x', with different lengths of 'a' each time, with 'x' declared as
int x[1000];
In that case, you could use memcmp as follow :-
for ( len = 1 ; len <= 7 ; ++len )
{ for ( i = 0 ; i <= 1000-len ; ++i )
{ if ( ! memcmp( a, x+i, len * sizeof(int) ) )
{ // do something
}
}
}

Resources