Unexpected output Signed and Unsigned comparison in for loop [duplicate] - c

This question already has answers here:
Comparison operation on unsigned and signed integers
(7 answers)
sizeof() operator in if-statement
(5 answers)
Closed 2 years ago.
unsigned int array[5],length = 5;
for(int i = -1; i < length; ++i)
{
array[i] = i;
printf("%d\n", array[i]);
}
Output: No Output // nothing is printing
I am expecting It should print the array.
Why no output of this c code ? What is the reason ?

The types of i and length are different (int and unsigned int respectively). So in the comparison i < length, i gets converted to an unsigned int because unsigned int has higher rank as per usual arithmetic conversions.
The value of -1 converted to unsigned int is UINT_MAX. Thus the comparison is equivalent to UINT_MAX < 5 in the first iteration. Which is false and the loop is never entered.

Related

Unsigned vs Signed Integer [duplicate]

This question already has answers here:
Why does counting down an unsigned int loop forever in C?
(5 answers)
Closed 4 years ago.
What's wrong with this code?
#include<stdio.h>
int main()
{
unsigned int i;
for(i=100;i>=0;i--)
{
printf("%u ",i);
}
return 0;
}
This code doesn't work but if i use for(i=100;i>0;i--) then it works!
or another way is to use integer instead of using unsigned integer.
An unsigned int can never be negative, so i >= 0 holds true all the time. So, it is effectively an infinite loop.
Since variable i is declared as unsigned int, this condition i>=0 never fails, hence results in infinite loop rotation.
unsigned int i;
for(i=100;i>=0;i--) { /* i will never become negative */
printf("%u \n",i);
}
Note that UINT_MAX is 4294967295 see this i.e it ranges from 0 to 4294967295 so when i=0 it prints & gets decremented, next it won't be -1, it will be 4294967295, hence above for loop results in infinite loop.
another way is to use integer instead of using unsigned integer ? you can do the same using unsigned integer also by replacing the condition part as i>0 so that when i=0 it fails & comes out of loop.
What's wrong with this code?
i>=0 is always true as i is unsigned. Then for(i=100;i>=0;i--) loops forever.
To continue using unsigned i:
Since the coding goal always wants to enter the loop at least once, instead of testing the loop condition in the begining, test at the end.
//for(i=100;i>=0;i--) {
// printf("%u ",i);
//}
i = 100; // or any unsigned constant.
do {
printf("%u ",i);
} while (i-- > 0);
another way is to use integer (int) instead of using unsigned integer (unsigned).(?)
Use int. Of course this will not work if i needs to start at values greater than INT_MAX. If such large values are needed, consider a wider signed type like long long.
int i;
for(i=100;i>=0;i--) {
printf("%u ",i);
}

Why this code is printing "False", though size of int is greater than -1? [duplicate]

This question already has answers here:
Why is this happening with the sizeof operator when comparing with a negative number? [duplicate]
(2 answers)
sizeof() operator in if-statement
(5 answers)
Closed 5 years ago.
According to the code below, size of int is not greater than -1. Why is it so? Why "False" was printed instead of "True"?
#include <stdio.h>
#include <stdlib.h>
int main() {
if(sizeof(int) > -1) {
printf("True\n");
}
else {
printf("False\n");
}
// Here size of int is equals to 4
printf("Size of int: %ld\n", sizeof(int));
return 0;
}
Well sizeof returns size_t which is unsigned and when it is compared with int the int is promoted to unsigned and the bit representation all 1's now considered as unsigned, which is bigger than -1 and also that of sizeof int. That's why this result.
Correct format specifier for size_t is %zu.

why is sizeof() returning 4 bytes rather than 2 bytes of short int? [duplicate]

This question already has answers here:
Why does sizeof(char + char) return 4?
(2 answers)
Why must a short be converted to an int before arithmetic operations in C and C++?
(4 answers)
sizeof operator returns 4 for (char + short ) [duplicate]
(3 answers)
What happens here? sizeof(short_int_variable + char_variable)
(5 answers)
How does sizeof work for different data types when added and calculated? [duplicate]
(1 answer)
Closed 5 years ago.
To print the size of the variables using sizeof()
#include <stdio.h>
main()
{
int a = 10,b = 20;
short int c;
short int d = sizeof(c = a+b);
int e = sizeof(c*d); //e holds the value of 4 rather than 2
double f = sizeof(e*f);
printf("d:%d\ne:%d\nf:%lf\n",d,e,f);
}
Why is sizeof() returning the size of int rather than short int which is meant to be 2 bytes?
The statement
sizeof(c = a+b);
doesn't measure the size of variable c but the size of the value computed from expression c = a+b. It is the value of a+b that is assigned to c but it is also the value of the entire expression.
The integral values whose storage type is smaller than int that appear in an arithmetic expression are promoted to int (or unsigned int) for the computation. The storage type of the result of the arithmetic expression is int. This is not affected that the fact that you store it in a short int variable. Hence the value returned by sizeof().
The same for sizeof(c*d).

comparison operation [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Unsigned and signed comparison
A riddle (in C)
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d = -1;
if (d < TOTAL_ELEMENTS)
printf("of course -1 is less than %d",TOTAL_ELEMENTS);
else
printf("how on earth");
return 0;
}
answer is:::Output of the above program is : how on earth
When you perform mixed signed vs. unsigned comparison (where signed type is not larger than unsigned one), the comparison is performed in unsigned domain, i.e. the signed operand is implicitly converted to unsigned type.
In your case TOTAL_ELEMENTS has type size_t, which is unsigned. That means that your d is also implicitly converted to size_t type. So, your d < TOTAL_ELEMENTS is actually interpreted as (size_t) d < TOTAL_ELEMENTS or (size_t) -1 < TOTAL_ELEMENTS.
(size_t) -1 is an extremely large positive value. It is actually the largest possible value of type size_t. Hence the result you get.
In your case you apparently want a signed comparison. For that you have to explicitly convert the unsigned value to signed type (paying close attention not to cause overflow). For example, this will work "as expected"
if (d < (int) TOTAL_ELEMENTS)
...
This is because sizeof_t is mapped to an unsigned long type, so -1 becomes 0xFFFFFFFFFFFFFFFF, a rather large positive integer. Try this:
#include<stdio.h>
#define TOTAL_ELEMENTS(a) ((int)(sizeof((a))/sizeof(*(a))))
int array[] = {23,34,12,17,204,99,16};
int main() {
int d = -1;
if (d < TOTAL_ELEMENTS(array)) {
printf("of course -1 is less than %d",TOTAL_ELEMENTS(array));
} else {
printf("how on earth");
}
return 0;
}
Note how I re-wrote your macro to reference array as its parameter, and added a cast to int to ensure that comparing to -1 would bring an expected result.

automatic type conversions [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
signed to unsigned conversions
A riddle (in C)
I am trying to understand why this program is not working
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int d;
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
I came across this program when I was going through automatic type conversions in C.But I don't understand how conversions happen between signed and unsigned data types.Please explain.
Thank you,
Harish
sizeof() is of type unsigned, wile d is signed.
you check if d is smaller then an unsigned integer. Thus, the signed d is converted to unsinged.
But the bits representaion of the signed -1 when read as unsigned is greater then 2^31, and obviously greater then TOTAL_ELEMENTS-2, thus the condition is never met and you do not enter the for loop even once.
Look at this code snap, it might clear up things for you:
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned int x = 50;
int y = -1;
printf("x < y is actually %u < %u which yields %u\n", y,x,y < x);
return 0;
}
The above code prints:
x < y is actually 4294967295 < 50 which yields 0

Resources