Parenthesis in C - how does it affect flow? - c

I was doing my assignment and was kind of playing around with the braces around iteration loops in c. From my understanding, you can write loops without having braces around the statements in each branch.
When I used the sample question code below, it managed to exit the loop to print the value outside of the loop.
But when I include brackets for each if / if else loop (which I am more comfortable with). It seems to be stuck inside the loop without printing anything on my console.
Am I overlooking something? Or is there special meaning on the way we bracket loops in c?
Sample Code from Assignment:
while (i<=20) {
if(i%2 == 0 && i <= 10) value += i*i;
else if ( i % 2 == 0 && i > 10) value += i;
else value -= i;
i++;
}
I added braces for each if / else if loops
int i = 0 , value = 0;
while (i<=20) {
if(i%2 == 0 && i <= 10) {value += i*i;}
else if ( i % 2 == 0 && i > 10) {value += i;}
else {value -= i;
i++;}
}
printf("%d", value);
so like I said, the first one does make it to the print statement. while the second example does not? Is that supposed to happen? Am I overlooking something?

In the first example (without parentheses) the i++ is performed in every cycle, so you reach 20 and you exit.
In the second example you increment i (i++) only if you enter the 'else' statement, so you get stuck (i remains zero).
If you want to understand well what happens I would suggest you to use printfs in each statement (with and without parenthesis) so you can see what happens at every iteration.
In C without using parenthesis only the first line is inside the else statement (first example: value -= i;)
Correct indentation:
while (i<=20) {
if(i%2 == 0 && i <= 10)
value += i*i;
else if (i % 2 == 0 && i > 10)
value += i;
else
value -= i;
/* not inside the else statement */
i++;
}
Correct indentation, second example:
int i = 0 , value = 0;
while (i<=20) {
if(i%2 == 0 && i <= 10) {
value += i*i;
}
else if ( i % 2 == 0 && i > 10) {
value += i;
}
else {
value -= i;
/* inside the else statement */
i++;
}
}
printf("%d", value);

I think this is how you were supposed to include the braces, only fixed i++ (in the comment)
#include<stdio.h>
void main(){
int i=0,value=0;
while (i<=20){
if (i%2==0 && i<=10){ value+=i*i;}
else if (i%2==0 && i>10){ value+=i;}
else { value-=i;}
i++; // its outside the if statement.
}
printf("%d",value);
}

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!

Whats happening in this for loop

whats happening in the first statement of the for loop? I can not seem to wrap my head around why 1 == 2 would be acceptable because its a comparison and not a value assignment.
char ch = 120;
unsigned char x = 1;
unsigned int y = 1;
for(1 == 2; ch > 0; ch++) {
printf("%d\n", ch);
x <<= 1;
y *= 2;
}
It is just a useless statement that the compiler will optimize away. The first statement in the for does not need to be an assignment, it is just build to be succinct/readable way to loop over a set of values. You can expand the for loop into a while and it may make it clearer:
1 == 2; // does nothing, likely emits compiler warning.
while( ch > 0 )
{
printf("%d\n", ch);
x <<= 1;
y *= 2
ch++;
}
If you want to use a for loop for the post iteration expression but have already initialized your variables, you can use the null statement as the first expression:
for( ; ch > 0; ch++ ){ /* ... */ }

multithreaded game of life in c

I 've been trying to implement a multithreaded game of life in c. The program reads a 2d array(A[100][100]) sized 100x100 from a file, copies that into a second array(B[100][100]) and creates 100 threads which are assigned a 10x10 part of the array and the threads are supposed to check each cell's neighbours(from array A) and change it's status according to the rules, in array B, when they 're finished the main function copies B into A and starts aggain from the beggining until the user stops the program. My problem is that the threads only change values for the last part of the array(positions [90-99][90-99]). does anyone have any idea as to might be going wrong?(if I use the same code but assign the whole array to all of the threads the output is correct, the same happens if I only use one thread)
Here:
int c[5];
for(i=0;i<100;i=i+10){
for(j=0;j<100;j=j+10){
c[0]=i;
c[1]=i+9;
c[2]=j;
c[3]=j+9;
c[4]=k;
err = pthread_create(&(tid[k++]),NULL, &populate, (void *)c);
}
}
You're passing the same array to each thread. So all threads will have the same parameters - whatever the final values of c are at the end of the loops.
Instead, give each thread it's own c:
int *c;
for(i=0;i<100;i=i+10){
for(j=0;j<100;j=j+10){
c = malloc(5 * sizeof(*c));
c[0]=i;
c[1]=i+9;
c[2]=j;
c[3]=j+9;
c[4]=k;
err = pthread_create(&(tid[k++]),NULL, &populate, (void *)c);
}
}
your "has_neighbors" as a whole lot of redundant code, which could be removed with either combining the rangechecks with the content check,
...
if( i> 0 && j> 0 && A[i-1][j-1]==1) count++;
if( i> 0 && A[i-1][j ]==1) count++;
if( i> 0 && j<99 && A[i-1][j+1]==1) count++;
if( j> 0 && A[i ][j-1]==1) count++;
if( j<99 && A[i ][j+1]==1) count++;
if( i<99 && j> 0 && A[i+1][j-1]==1) count++;
if( i<99 && A[i+1][j ]==1) count++;
if( i<99 && j<99 && A[i+1][j+1]==1) count++;
return count;
}
or by using a range checked subfunction to return the content:
int neighbour_value(int i, int j){
if (i<0 || i>99) return 0; /* out of range, never set */
if (j<0 || j>99) return 0; /* out of range, never set */
return A[i,j];
}
and then just check via
{
int count = 0;
if(neighbour_value(i-1,j-1)==1) count++;
if(neighbour_value(i-1,j )==1) count++;
if(neighbour_value(i-1,j+1)==1) count++;
if(neighbour_value(i ,j-1)==1) count++;
if(neighbour_value(i ,j+1)==1) count++;
if(neighbour_value(i+1,j-1)==1) count++;
if(neighbour_value(i+1,j )==1) count++;
if(neighbour_value(i+1,j-1)==1) count++;
return count;
}

bitwise operation, printing of bits depends of which putchar is put first...?

I'm simply trying to print an unsigned int as bits, but it appears my code:
void checksWithOne(unsigned int userInput)
{
int i = 0, a = 0;
for (i = sizeof(int)*8-1; i >= 0; i--)
{
a = (userInput&(1<<i));
if (a==1)
{
putchar('1');
}
else
{
putchar('0');
}
}
printf("\n");
}
Only works if the if statement is changed as such (replacing 1s and 0s):
if (a==0)
{
putchar('0');
}
else
{
putchar('1');
}
It's beyond me as to why that is... any thoughts?
Thanks
Second code works because you prints '0' when a is == 0 else '1'. Accordingly in first code piece, if(a==1) should be if(a) that means print 1 if a is not 0 (Rremember every non-zero value is true in C).
The thing is a = (userInput & (1<<i)); is not always 1 but a can be a number that is either zero or a number in which only one bit is one (e.g. ...00010000)
The result of a = (userInput&(1<<i)) will be either 1<<i or 0, (not 1 or 0). So change:
if (a==1)
to:
if (a != 0)
and your code should work.

Base conversion using recursion

I'm working on an assignment and have it partially solved.
Currently I'm getting the correct output, only in reverse.
Here's the helper function I've implemented:
char int2char (int radix, int value) {
char c = '?';
if ((value >= 0 && value < radix) && (radix <= 36 && radix >= 2)){
if (value < 10){
c = value + 48;
}
else if (value >= 10 && value < 36) {
c = value + 55;
}
}
return c;
}
And the actual function I'm having difficulty with looks like this thus far:
void int2str (int radix, int value) {
int result = value % radix;
int division = value / radix;
char c;
c = int2char(radix, result);
putchar(c);
while (division > 0) {
return int2str(radix, division);
}
}
The first function is used to represent the digits 10-35 in hex. So if the modulus produces an 11, for example, I'm supposed to output a 'B'.
This is working great, except backwards! And I can't figure out how to reverse it. The biggest hitch is you can only use putchar() as an output. No strings, no arrays.
To further clarify, if I enter:
int2str 16 60
The output should be '3C', instead I'm getting 'C3'.
First off, your use of while is confusing, since there's a return in it. Replace that with if. The return is unnecessary, since the function will return on its own at the end.
Once you've done that, you can reverse the output by moving the putchar after the recursive call:
if (division > 0) {
int2str(radix, division);
}
putchar(c);
As a side note, return int2str(radix, division); doesn't make sense in this function anyway, since it's a void function, so there's nothing to return. If you did want to do this (you don't in this case), you would say:
somefunction();
return;
Also, this may be more clear if you used '0' and 'A' instead of 48 and 55:
if (value < 10){
c = value + '0';
}
else if (value >= 10 && value < 36) {
c = value - 10 + 'A';
}
result is the last digit, but you're printing it first. Drop the return from the recursive call and move the putchar to the end. Also, the while loop should be an if.
void int2str(int radix, int value) {
int lastdigit = value % radix;
int firstdigits = value / radix;
if (firstdigits) {
int2str(radix, firstdigits);
}
putchar(int2char(radix, lastdigit));
}
Try this
c = int2char(radix, result);
if (division > 0)
int2str(radix, division);
putchar(c);
Last call to int2str will print first digit while first call will print last digit.

Resources