Compound conditions using while loop in C. - c

The program is ignoring Stop when amt is 0 until after 10 numbers have been entered. The program also doesn't stop after 10 numbers have been entered. Where is my error?
main() {
int amt;
int tot = 0; /* running total */
int i = 0; /* counts number of times in loop */
while (amt!=0 || i < 10)
{
printf("Enter a number (enter 0 to stop): ");
scanf("%d", &amt);
tot = tot + amt;
i++;
}
printf("The sum of those %d number is %d.\n", i, tot);
}

Your test is happening before amt is assigned. Thus its results are undefined. This test should be moved to the end of the iteration, i.e. a do/while. Whilst you could assign amt to some non-zero value this feels slightly untidy to me.
And surely you mean to use logical AND rather than logical OR? You only want to continue iterating if both amt is non-zero AND i<10.
Of course, if you did move the test to the end of the iteration then you would have to account for the fact that i had been incremented inside the loop.

In order to stop after 10 numbers or amt=0 (whichever first is met) you'll have to change the loop condition to while (amt!=0 && i < 10)

int amt;
Since you do not initialize it. It has some random value and that causes the Undefined Behavior in your program.
You should always initialize local variables with values.

Related

Finding max element in array - program won't recognize last element

I wrote this little code just to start learning some if statements and C coding in general. However, there is an issue. When running it, if the largest element is the last one, the code won't recognize it. Why is that?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(){
int num[100];
int max;
int i;
printf("Enter 10 numbers: \n");
for(i = 1; i < 10; i++){
scanf("%d\n", &num[i]);
}
max = num[0];
for(i = 0; i < 10; i++){
if(max < num[i]){
max = num[i];
}
}
printf("The biggest nr is: %d", max);
return 0;
}
Your first loop should start from 0, not 1.
for(i = 0; i < 10; i++){
scanf("%d\n", &num[i]);
}
max already starts with an uninitialized value, here be dragons.
Inside of:
for (i = 1; i < 10; i++) {
scanf("%d\n", &num[i]);
}
max = num[0];
max has an indeterminate value because the loop's counter variable i starts at 0, not 1 which gives the result that the first element of the array wasn't assigned inside of the loop. So you end up assigning this indeterminate value to max.
To use an indeterminate value in the following code:
if (max < num[i]) {
max = num[i];
}
invokes undefined behavior.
"However, if I change i=0, the program asks me for 11 inputs before moving on. And among those 11 inputs, the program still won't count the last one, if it is the largest."
"When running it, if the largest element is the last one, the code won't recognize it. Why is that?"
It doesn't actually ask you for an 11th input for any presumed 11th array element as you think it does and the last in the loops1 treated element of the array is not the one you think it is. That is just an impression to you.
This behavior is caused by the newline character in the format string of the scanf() call:
scanf("%d\n", &num[i]);
The newline character (\n ) is equal to any white space and with this directive, scanf() reads an unlimited amount of white space characters until it finds any-non white space character in the input to stop consuming and the control flow continues to the next statement.
Why does scanf ask twice for input when there's a newline at the end of the format string?
It doesn't ask for the input of the 11th element of the array (as you think it does). It simply needs any non-white space character that the directive fails.
The last element of the array (which is treated inside of the loops1) is still the 10th (num[9]), not the 11th (num[10]) and so is the output correct when you initialize the counter to 0 and it prints:
The biggest nr is: 10
because 10 is the value of the last treated element num[9].
1) Note that you made a typo at the declaration of num -> int num[100];. With this you define an array of one hundred elements, but you actually only need one of 10 elements -> int num[10];.
Side Note:
Also always check the return value of scanf()!
if (scanf("%d\n", &num[i]) != 1)
{
// Error routine.
}
There are two problems in the code one after another:
The loop should begin from 0 instead of 1:
for (int i = 0; i < 10; i++)
The main problem is here:
scanf("%d\n", &num[i]);
_________^^____________
Remove the \n and your problem will be fixed.

Issue with using multiple relational operators in C

I'm new to programming, but I searched for this topic before asking and still can't figure out what my program is doing wrong.
I have this:
int i;
do
{
i = get_int("Enter positive integer between 1-10: \n");
}
while(1>i && i<10)
I want to ask the user for a positive integer between one and ten. it doesn't accept anything less than one, which is good, but it will take anything positive. I understand how I can't do 1>i<10 since it reads it from left to right but I can't get it to recognize it has to follow both operators. What is my issue?
You probably want the loop to run the loop as long as user inputs a number between 1 to 10. Your condition in the while loop isn't correct. It should be as follows -
while(i>1 && i<10); # runs as long as i is in range 1 to 10
However, If you want to break the loop as soon as the user inputs any number inside the 1 to 10 range, then you should use the following -
while(!(i>1 && i<10)); # runs as long as i is outside the range 1 to 10
i can't get it to recognize it has to follow both operators.
Why would it be more applicable when the integer has to meet both criteria?
do {
....
} while(test);
When the test returns true, the input is re-tried as the loop iterates again. What is the criteria for re-trying, not what is the criteria for passing.
Input only needs to fail one of two tests to re-try: too low or too high. Hence the need for "or" (||).
} while(i < 1 || i > 10);
Your loop condition is incorrect. You should have used logical OR instead of logical AND.
This worked for me.
do
{
i= get_int ("Enter positive integer between 1-10: \n");
} while (i<1 || i>10);
you have been mistaken (syntax mistake) inside the while expression (2 mistakes their, the logic is not right and a syntnatx error with 1<i) - see fixes inline:
int i = 0; /*its better if you initialize the i here*/
do
{
i= get_int ("Enter positive integer between 1-10: \n");
}
while((i > 1) && (i < 10));
I want to ask the user for a positive integer between one and ten.
I think you want an integer in the range with inclusive 1 and 10.
When how will look such a condition of a valid positive integer?
It will look the following way
1 <= i && i <= 10
So the do while loop must continue its iterations while this condition is not true. So in the condition of the loop you should write a negation of the above condition
int i;
do
{
i= get_int ("Enter positive integer between 1-10: \n");
} while ( !( 1 <= i && i <= 10 ) );
If to remove the parentheses then the condition will look like
int i;
do
{
i= get_int ("Enter positive integer between 1-10: \n");
} while ( 1 > i || i > 10 ) );

What is the correct way of using GMP integer functions in C programs?

I'm trying to calculate the index of Fibonacci number with 1000 digits.
int i = 0, cnt = 2;
mpz_t limit;
mpz_init (limit);
mpz_ui_pow_ui(limit,10UL,999UL);
mpz_t fib[3];
for (i = 0; i < 3; i++)
mpz_init2(fib[i], 1024UL);
mpz_set_ui(fib[0],1UL);
mpz_set_ui(fib[2],1UL);
I think there's something wrong with assigning 1 to 1st and last element. I know that because those elements are not changing. But the loop should be valid till cnt becomes 4782.
The condition in while loop is only satisfied 2 times if.. <=0 or 3 times if .. >=0.
while(mpz_cmp(fib[i],limit)<=0) // should be <= only, not >=
{
i=(i+1)%3;
cnt++;
mpz_add(fib[i],fib[(i+1)%3],fib[(i+2)%3]);
}
for (i = 0; i < 3; i++)
mpz_clear(fib[i]);
mpz_clear(limit);
printf("Fibonacci number with more than 1000 digits: %d\n",cnt);
Please help find the logical error in this (it is compiling perfectly).
P.S. I don't want to use in-built mpz_fib_ui.
Integer Functions
After the for loop, i=3, so the conditional statement for the while loop depends on fib[3]
Adding i=0; before the while loop fixes it, and gives me the desired output:
Fibonacci number with more than 1000 digits: 4782

Programming while loop in C

First, I am a total beginner, so the question is probably very obvious for all of you, but i don't get what's wrong with the while loop in this program. Te aim of the program is to calculate the average between numbers where the user inputs 0 when he wants to continue putting numbers in and inputs 1 when he wants to stop, so the loop is supposed to stop when the user puts 1 and to compute a sum of the values when he enters 0 at the end. So this is what i wrote, i used stdio.h and stdlib.h as libraries :
int decision;
int value;
int sum = 0;
float av;
int order = 1;
printf ("for continue press: 0\n ");
printf ("for stopping press: 1\n ");
while (decision == 0) {
printf("input value:");
scanf("%d", &value);
sum = sum + value;
printf ("continue?");
scanf("%d", &decision);
order = order + 1;
}
av = (float) sum / (float) order;
printf("the average is: %.2f", av);
return EXIT_SUCCESS;
what the terminal displays is just "the average is:0.00", it skips the whole operation above.
You should initialize decision to 0
int decision = 0;
so that the while loop is true
while (decision == 0) {
on the first iteration.
In C, simply declaring a variable does not assign it a value of 0. You have to do that. In fact, actually using a variable that has not been initialized is undefined behavior. Most likely, the variable contains whatever contents was in the memory location assigned to it.
The solution is to actually define decision.
int decision = 0;
In C, declaring a variable does not initialize it. So the initial value of decision is more or less random. If it's not zero (and it likely is not), the cycle is never entered.
Perversely, when in "debug mode" or using some instrumentation such as valgrind, memory might be either zeroed or initialized consistently, leading to "unreproducible" bugs that may be difficult to track. That is why you really want to always initialize your variables
Try with:
int decision = 0;
Also, turn on all compiler warning flags. You want to be warned when such things happen, and the compiler can do so if you tell it to.
Another way
You do not need decision anywhere else, so it's good to have one less variable in the outer scope:
for (;;) {
int decision; /* The variable only lives inside this loop */
printf("input value:");
scanf("%d", &value);
sum = sum + value;
printf ("continue?");
scanf("%d", &decision);
if (0 == decision) {
break;
}
order = order + 1;
}
Notice
If you start order from 1, and enter only one value, order will be increased to 2, and this will get your calculation off. Either start from 0 or increase the value after decision confirmation.
You have not initialized the decision variable and that is why the error.
int decision = 0;

C function call as test condition

Few days ago I've a weird idea came into my mind that manipulate if(); statement in a weird way.Let's go on to a simple code.
The Code :
if(printf("blahblah\n");{
}
My Idea :
1.)To me I think this code will always evaluated to be true(my assumption) since the test condition is substituted with a function call.
So today I'm doing an exercise provided by a book(just to help me refresh what i learn few days ago).This is the code.
The Code :
#include <stdio.h>
int main(void) // This program would add up the value enter by user , for e.g with the
{ //input of 20 , it will print out the sum of 1+2+3+4+5.....20.
int count , sum , size;
count = 0;
sum = 0;
printf("Enter a value to find the sum of it from 1 : ");
scanf("%d" , &size);
while (count++ < size)
sum = sum + count;
printf("sum = %d\n" , sum);
return 0;
}
By using my idea on the first code , I modified the second code into this.
#include <stdio.h>
int main(void)
{
int count , sum , size;
count = 0;
sum = 0;
printf("Enter a value to find the sum of it from 1 : ");
while (scanf("%d" , &size) && count++ < size )
sum = sum + count;
printf("sum = %d\n" , sum);
return 0;
}
The Question :
1.)Based on the assumption made by me in the first code , the scanf() function suppose to be always evaluated to true.That's why the second test condition count++ < size is the one that determine whether the statement in while statement will be executed or not.
2.)But when I run the program , I input 30 but it doesn't work , the program just stop there without doing anything after i hit enter.
3.)I try to switch the to test condition with the `count++ < size as left operand while the input function as right operand.
4.)After doing so , the result i get is different.When i try to run the program , the program execute the second printf() function statement , and print out sum = 0.
Your help is much appreciated , do correct me for mistakes.I'm willing to learn from it.
To me I think this code will always evaluated to be true(my assumption) since the test condition is substituted with a function call.
This is incorrect. The function (in this case, printf) returns a value (in this case, an int). When you use it as the condition in the if statement, the function is called and the value it returns becomes the condition: if it returns zero it evaluates to false; if it returns nonzero it evaluates to true.
There is no difference between
if (printf("Hello, World!")) { }
and
int i;
i = printf("Hello, World!");
if (i) { }
(aside, of course, from the additional variable in the second example.)
In your modified second example, scanf is called each time the loop condition is checked. You could rewrite the loop like this:
while (1)
{
int result_of_scanf;
result_of_scanf = scanf("%d", &size);
if (result_of_scanf == 0)
break;
if (count++ >= size)
break;
sum += count;
}
scanf doesn't just get called once; it gets called for each iteration of the loop. scanf returns the number of elements that it read successfully, so in this case it will return either 1 (if you input a valid integer within the range of int) or 0 (if you give any other input).
The program appears to be stuck but actually it is expecting you to input numbers. That is you will have to enter numbers till the count is equal to the input number.

Resources