can anyone explain me the output
I have code like
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
for(d=-1;d <= (TOTAL_ELEMENTS);d++)
{
printf("%d\n",array[d+1]);
}
It shows no output why it is so ?
But when i change the value of d in for loop like d=1 it shows the output why?
if i remove macro TOTAL_ELEMENT wit d<=4 ; i get the desired output why ?
As other stated in their answers, with d = -1 it does not print anything as in:
d <= TOTAL_ELEMENTS
d is converted to an unsigned integer type (TOTAL_ELEMENTS is of type size_t because of sizeof). After conversion d value becomes a huge unsigned integer and the comparison with TOTAL_ELEMENTS value fails.
Then:
printf("%d\n",array[d+1]);
will overflow your array as the last element of your array is at index TOTAL_ELEMENTS - 1 and you access your array up to TOTAL_ELEMENTS + 1.
To display your array elements just use the regular form starting from index 0:
int i;
for (i = 0; i < TOTAL_ELEMENTS; i++)
{
printf("%d\n", array[i]);
}
You need to understand "Conversion rules for comparision between signed and unsigned types". In the example, for(d=-1;d <= (TOTAL_ELEMENTS);d++), here d is signed int, and TOTAL_ELEMENTS is unsigned, and d <= TOTAL_ELEMENTS converts d to unsigned. Unsigned -1 is huge number which is not < TOTAL_ELEMENTS, so the loop never gets executed. Typecast as shown below. It will work.
for(d=-1;d <= (int)(TOTAL_ELEMENTS);d++)
try casting TOTAL_ELEMENTS to int
for(d=-1;d <= (int)(TOTAL_ELEMENTS);d++)
Related
I don't know why the sizeof operator is not evaluated in a for loop condition at run time. I am trying this simple code with different C compilers but it always print nothing. But if I replace sizeof(i) with 4 then it works fine:
for(int i = -2; i <= 4; i++)
#include <stdio.h>
int main()
{
for(int i = -2; i <= sizeof(i); i++)
printf("Hello World");
return 0;
}
The problem is , the result of sizeof() operator is of type size_t, which is an unsigned type.
Next, in the comparison, i <= sizeof(i) as per the usual arithmetic conversion rules, -2, which is a signed value, gets promoted to an unsigned value, producing a huge value, evaluating the condition to false. So the loop condition is not satisfied and the loop body is not executed.
Run your program through a debugger and see the values in each step, it'll be more clear to you once you see the promoted values in the comparison.
sizeof yields a value of unsigned type variety (size_t). The i is converted to that type and the comparison executed as
(size_t)-2 <= 4
something like 4000000000 < 4
you need to typecast sizeof(i) into int. that should solve the problem.
so just replace for(int i = -2; i <= sizeof(i); i++) with for(int i = -2; i <= (int) sizeof(i); i++)
sizeof() returns size_t which is an unsigned type.
You can try this code instead:
#include<stdio.h>
int main()
{
int i=-2,j;
j=(int)sizeof(i);
for(i=-2;i<=j;i++)
printf("HELLO\n");
return 0;
}
You can typecast sizeof() to int.
Below is the code I am having issues with. I understand constants and believe I understand the sizeof function but must be missing something. Here is what I have tried to do to solve on my own:
- printf statement with TOTAL_ELEMENTS as the %d - it returns 7
- printf statement of TOTAL_ELEMENTS - 2 - it returns 5 (as expected)
- substitute 5 in the for loop - loop runs correctly
- initialize a global int variable of any name and set it equal to (sizeof(array) / sizeof(array[0])). Then used the variable in the for loop where TOTAL_ELEMENTS would go - again the loop runs correctly.
So (at least in my head), it has to be something involving both the constant and the sizeof function - I'm positive the array/array[0] also plays a part but through testing and substitution I can't figure out what the issue is. I have read up on the sizeof function as well as constants to no avail. I have tried searching but have gotten no where as I'm not fully certain what I'm searching for. I don't necessarily need answers but if someone could point me in the right direction it would be much appreciated. Thank you in advance.
#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;
}
This issue is not related to sizeof. this is because of the comparing signed with unsigned value. In your code , (TOTAL_ELEMENTS-2) has an unsigned value , but d is a signed variable. therefore , for condition will compare 5 with 0xFFFFFFFF and 5 is less than 0xFFFFFFFF then it is false always!
For example :
int main()
{
int d;
unsigned int e = 5;
for (d = -1; d <= e; d++)
printf("%d\n", array[d + 1]);
return 0;
}
It do not print any things! , same as your code.
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.
what is wrong with this code ? can anyone explain ?
#include <stdio.h>
#include <malloc.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23,34,12,17,204,99,16};
int main()
{
int num;
int d;
int size = TOTAL_ELEMENTS -2;
printf("%d\n",(TOTAL_ELEMENTS-2));
for(d=-1;d <= (TOTAL_ELEMENTS-2);d++)
printf("%d\n",array[d+1]);
return 0;
}
when i print it gives 5, but inside for loop what is happening ?
The sizeof operator returns a value of type size_t, which is an unsigned value. In your for loop condition test:
d <= (TOTAL_ELEMENTS-2)
you are comparing a signed value (d) with an unsigned value (TOTAL_ELEMENTS-2). This is usually a warning condition, and you should turn up the warning level on your compiler so you'll properly get a warning message.
The compiler can only generate code for either a signed or an unsigned comparison, and in this case the comparison is unsigned. The integer value in d is converted to an unsigned value, which on a 2's complement architecture ends up being 0xFFFFFFFF or similar. This is not less than your TOTAL_ELEMENTS-2 value, so the comparison is false.
You're starting the loop by setting d = -1, it should be d = 0. So for the first element you're reading random bits of memory.
If you fix that, then you can change your printf to be
printf("%d\n",array[d]);
As you've also marked this as homework, I'd advise also take a look at your loop terminating condition.
#include <stdio.h>
int arr[] = {1, 2,3,4,5};
#define TOT (sizeof(arr)/sizeof(arr[0]))
int main()
{
int d = -1, x = 0;
if(d<= TOT){
x = arr[4];
printf("%d", TOT);
}
printf("%d", TOT);
}
TOT has the value 5 but the if condition is failing..why is that?
Because there are "the usual arithmetic conversions" at work for the if.
The sizeof operator returns an unsigned type ... and d is converted to unsigned making it greater than the number of elements in arr.
Try
#define TOT (int)(sizeof(arr)/sizeof(arr[0]))
or
if(d<= (int)TOT){
That's because sizeof returns an unsigned number, while d is signed. When d implicitly converted to a singed number, and then it is much much larger than TOT.
You should get a warning about comparison of signed-unsigned comparison from the compiler.
Your expression for TOT is an unsigned value because the sizeof() operator always returns unsigned (positive) values.
When you compare the signed variable d with it, d gets automatically converted to a very large unsigned value, and hence becomes larger than TOT.
return type of sizeof is unsigned integer ....that is why if is failing ...because "d" which is treated as signed by the compiler is greater than TOT