adding { - } in a for loop : c programming - c

the program runs fine and clear, but i just wanted to ask why didnt we add { - } in the beggining and end of the for loop ? the program runs fine without adding them but when i tried to add { - } in the for loop the prgram didnt run fine, arent we suppose to add { - } in ever begging and end of every loop ? and why did the program run fine without them and didnt run fine with them ?
int c, first, last, middle, n, search, array[100];
printf("Enter number of elements\n");
scanf("%d",&n);
printf("Enter %d integers\n", n);
for ( c = 0 ; c < n ; c++ )
scanf("%d",&array[c]);
printf("Enter value to find\n");
scanf("%d",&search);
first = 0;
last = n - 1;
middle = (first+last)/2;
while( first <= last )
{
if ( array[middle] < search )
first = middle + 1;
else if ( array[middle] == search )
{
printf("%d found at location %d.\n", search, middle+1);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if ( first > last )
printf("Not found! %d is not present in the list.\n", search);

Without braces it takes ONE statement as its scope
like
for ( c = 0 ; c < n ; c++ )
scanf("%d",&array[c]);
Equivalent of
for ( c = 0 ; c < n ; c++ )
{
scanf("%d",&array[c]);
}

A loop executes the statement immediately after it in a loop. What is a statement? It can be:
A piece of code ended with ;.
A block of code started with { and ended with }.
Your for-loop
for ( c = 0 ; c < n ; c++ )
scanf("%d",&array[c]);
uses the first definition of statement, but you could also write it as
for ( c = 0 ; c < n ; c++ )
{
scanf("%d",&array[c]);
}
and it should work fine.

Informally: The for-loop has a one-statement body. To use multiple statements, you nest them in a block-statement.

If there is only one statement in the block the braces are optional

Related

What does the part a[a[i-1] of this for loop mean?

I'm new in programming and my test is going to be soon, but I have no idea what happens in this for loop. Could someone explain it to my.
I'd be very thankful :)
enter image description here
It's nothing fancy. It's just a simple for loop with some compound statements. let me explain every bit of it.
The syntax ( writing sequence ) of for loop is below.
for(initial value for loop ; condition to check on every loop ; increment in initial value)
{
body of loop
}
First Line :
int[] a = new int[6];
This line is only declaring an INTEGER ARRAY of length 6
Second Line :
for(int i=0; i<=10 ; i=i+2) a[i/2] = i < 5 ? 5 - i : 0 ;
This is a compound statement, First simplify this.
The above CODE can be written as
for (int i=0 ; i<=10 ;i=i+2)
{
if(i < 5)
{
a[i/2] = 5 - i;
}
else
{
a[i/2] = 0;
}
}
Third Line :
for(int i=a.length ; i > 0 ; i--) a[i-1] = a[a[i-1]] + i ;
The above code can be written as followed
for(int i = a.length ; i > 0 ; i-- )
{
//decomposing a[a[i-1]]
//lets assume that **i = 2** and **a[1] = 99**;
a[ value of a[i-1] which is a[2-1] => a[1] which is 99 ];
// so after putting value of a[1] the above equ will be
a[99]
//this is also be equal to some value, let say a[99] == 40;
//then
a[i-1] = 40 + i;
}

Parenthesis in C - how does it affect flow?

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);
}

How to properly make a counting algorithm to count from file?

This is a program to find the largest even number and its times of occurring from an input file and output it to an output file. I'm having a problem with the output, there seems to be an extra iteration that messes things up.
int main(int argc, char const *argv[])
{
int n, num, i, even, count;
FILE * fptr;
FILE * fptro;
fptr =fopen("maximpar.in", "r");
fptro=fopen("maximpar.out", "w");
/*scanning the first line from the file to get n for for()*/
fscanf(fptr, "%d", &n);
count = 0;
even = INT_MIN;
for(i = 0; i < n; i++)
{
fscanf(fptr, "%d", &num);
if( (num % 2 == 0 && num > even) || (even == num) )
/*checking for largest even number,
not sure about the ..||(even == num) part of the condition*/
{
even = num;
count++;
}
}
fprintf(fptro, "%d %d", even, count);
fclose(fptr);
fclose(fptro);
return 0;
}
Input file
6
9 6 9 8 9 8
Output file
8 3
Why isn't the output file like this? I don't understand
8 2
You need to reset your count whenever you get a new larger number.
I didn't test this, but it should work:
cate = 0;
par = INT_MIN;
for (i = 0; i < n; i++) {
fscanf(fptr, "%d", &b);
// skip odd numbers
if ((b % 2) != 0)
continue;
// get new larger number
if (b > par) {
par = b;
cate = 1;
continue;
}
// increment count on existing largest number
if (b == par)
++cate;
}
UPDATE:
I dont understand why skip iterations explicitly instead of only picking out the iterations that matter? Is there some sort of advantage?
Yes, it's better style. It allows simple single level indented if statements that can have their own comments.
It avoids a messy compound if or a triple level if/else ladder.
IMO, it's a common misconception [particularly among beginning C programmers] that a complex if will execute faster [or is somehow "better"] than several simple ones.
The first if could be thought of a "skip this iteration" test. Here, there's only one. But, for more complex code, there might be several.
The multiple condtion escapes could be handled in a single if with if (c1 || c2 || c2 || ... || c10) continue; but that gets messy fast.
Herein, for properly indented if/else ladder logic, we'd need:
if (cond1)
do_stuff1;
else
if (cond2)
do_stuff2;
else
if (cond3)
do_stuff3;
If we're not in a loop, here's a "trick" to avoid if/else ladder logic, by using do { ... } while (0);:
do {
if (cond1) {
do_stuff1;
break;
}
if (cond2) {
do_stuff2;
break;
}
if (cond3) {
do_stuff3;
break;
}
} while (0);
enclose the condition
if( ( ...&&...) ||(....) )
The answer is because count was incremented from 0 to 1 when b = 6. 2 iterations later, b = 8 and now count = 2, and 2 iterations after that, b = 8 and count = 3.
I also recommend you nest your if statement in parentheses for readability. Commenting would help too :) I'm a stats guy, and I have no idea what you are doing based on your variables' names.
You need to reset your counter inside the if block if b > par.
Like:
if( num % 2 == 0 && num >= even) {
if (num > even){
even = num;
count = 1;
} else {
count++;
}
}
Thanks.
JK

C Segmentation Fault in strcmp for-loop

Novice programmer learning C, I'm encountering this 'segmentation fault (core dumped)' error while trying to run a for-loop with strcmp. I have seen questions on similar issues with strcmp, but they don't seem to address my problem. Here's the program I've written.
#include<stdio.h>
#include<string.h>
int main() {
char ftpstring[15];
printf("\nEnter valid ftp command > ");
fgets(ftpstring,15,stdin);
const char* ftp[] = { "ascii", "recv", "send", "rmdir", "mkdir" , "pwd", "ls", "cd", "status", "quit" };
for ( int i = 0; i <= 10; i++ ) {
int comparison;
comparison = strcmp(ftpstring, ftp[i]);
if (comparison == 0 ) {
printf("%s is a valid ftp command.", ftpstring);
break;
}
if(i == 10) {
printf("%s is NOT a valid ftp command.", ftpstring);
}
}
}
As you can see, this program tries to read user input to determine if it matches one of the predefined valid ftp commands, then return whether or not it does.
for ( int i = 0; i <= 10; i++ ) should be for ( int i = 0; i < 10; i++ )
The ftp array contains 10 strings, so the loop should be from 0 to 9 including.
More general solution could be
for ( int i = 0; i < sizeof(ftp)/sizeof(ftp[0]); i++ )
But it is better to define a macro
#define FTP_NUM_OF_COMMANDS 10
and define the ftp array as following:
const char* ftp[FTP_NUM_OF_COMMANDS] = { "ascii", "recv", "send", "rmdir", "mkdir" , "pwd", "ls", "cd", "status", "quit" };
In this case the compiler will also verify that you don't initialize it (by mistake) with more than 10 values. The for loop will look like this:
for ( int i = 0; i < FTP_NUM_OF_COMMANDS; i++ )
Also note that the following code should be moved outside the for loop
if(i == FTP_NUM_OF_COMMANDS) {
printf("%s is NOT a valid ftp command.", ftpstring);
}
i==FTP_NUM_OF_COMMANDS will never occur inside the loop itself, if that condition is true, the for loop should break. Make sure that you define i outside the for loop scope so it would be available after the for loop breaks.
You are making a comparison past the end of the array: the for loop should stop at 9, while yours goes past the end of the array.
Using 10 as a "magic number" is not a good choice, either: it is much better to have the compiler compute the size for you. Finally, it is better to use index after the loop to decide if the command has been found or not:
int index = -1;
for ( int i = 0 ; i != sizeof(ftp) / sizeof(*ftp) ; i++ ) {
if (!strcmp(ftpstring, ftp[i])) {
index = i;
break;
}
}
if (index == -1) {
printf("%s is NOT a valid ftp command.", ftpstring);
}

Implementing loops on the basis of condition in C

I have a set of statements that need to be executed in two different loops; the loops identified on the result of a check condition. There are multiple such sets of this type.
Set A : statement 1
statement 2
statement 3
Set B : statement 4
statement 5
statement 6
and so on..
Now they need to be executed as follows:
if(condition 1)
loop over some Loop A
execute Set A
else if(condition 2)
loop over some loop B
execute Set A
These loops can be completely different from each other.
Now, for the sake of code clarity, I don't wish to write the code as mentioned above. Another reason being I'll have to make multiple sets in order to group them together.
Is there any mechanism by which I could achieve the following:
CHECK_CONDITION_AND_LOOP_HERE
execute Set A
I've tried using macros to achieve this, using braced-group within expression but could not . I also tried using ternary operators as well as fall through a switch case to achieve this, but could not get the same result.
Is there any way in C using which I could achieve the desired behavior?
Sample code for the problem:
if(condition A)
for(i=0; i<10; i++, k*=2) {
execute Set A; //Operations performed here use variable k
}
else if(condition B)
for(j=5; j<75; j+=5, k*=arr[j]) {
execute Set A; //Operations performed here use variable k
}
The answer to Version 1 of the question:
Given that the only difference is the range of values over which the statements are executed, you can use a couple of variables to store the range end-points, e.g.
int first = 0;
int last = -1;
if (condition1) {
first = 1;
last = 10;
} else if (condition2) {
first = 3;
last = 7;
}
for ( int i = first; i <= last; i++ )
execute set A
Note that initializing last to be less than first prevents the body of the loop from running if neither condition is met.
The answer to Version 2 of the question:
Here's the code from the question. I've made some changes for clarity, and to make the question more concrete.
if (cond1)
for (initA;condA;updateA)
execute SetX
else if (cond2)
for (initB;condB;updateB)
execute SetX
Here's the refactored code
int is1 = cond1;
int is2 = is1 ? 0 : cond2;
if (is1)
initA;
if (is2)
initB;
while ( (is1 && condA) || (is2 && condB) )
{
execute SetX
if ( is1 )
updateA;
if ( is2 )
updateB;
}
A function, maybe?
void func_A() {
printf("Here0\n");
printf("Here1\n");
}
...
if(a < b) {
for(i = 1; i <= 10; i++) {
func_A()
}
}
else if(a == b) {
for(i = 3; i <= 7; i++) {
func_A()
}
}
Or if you want to only make one call/block:
if(a < b) {
min = 1; max = 10;
}
else if(a == b) {
min = 3; max = 7;
}
for(i = 3; i <= 7; i++) {
printf("Here0\n");
printf("Here1\n");
}

Resources