Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Loop starting at -1 doesn't print anything [duplicate]

This program is supposed to print out the elements of array, but when it is run, no output is shown.

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

Why doesn't this program show any output?

like image 839
rohit kumar Avatar asked Aug 13 '17 05:08

rohit kumar


People also ask

How do you stop a repeating loop?

repeat loop in R: A repeat loop is used to iterate over a block of code multiple number of times. There is no condition check in repeat loop to exit the loop. The only way to exit a repeat loop is to call break. These are not commonly used in statistical or data analysis applications but they do have their uses.


Video Answer


1 Answers

sizeof returns an unsigned integer, so TOTAL_ELEMENTS is also unsigned.

d is signed. Initially, d is -1. However, when doing the comparison, d is implicitly typecast to unsigned, so it is no longer -1 when being compared to TOTAL_ELEMENTS, it is actually UINT_MAX (which is 4294967295 on my machine, but might differ for others).

Also,

If you want to fix this, typecast TOTAL_ELEMENTS to int:

for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++)  

This will print:

23 34 12 17 204 99 16 

As you'd expect. You may also want to look at Comparison operation on unsigned and signed integers for more information on the topic of signed-unsigned comparisons.

It is worth noting that turning on compiler warnings would've helped you figure out what was going on (as observed by hyde in his comment):

$ gcc -Wall -Wextra test.c test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]       for(d = 0; d < TOTAL_ELEMENTS; d++)                ~ ^ ~~~~~~~~~~~~~~ 1 warning generated. 

Alternatively, why not start d at 0 and run to TOTAL_ELEMENTS - 1 instead? You can even drop the typecast, that is necessary only for the corner case of d = -1.

for(d = 0; d < TOTAL_ELEMENTS; d++)      printf("%d\n", array[d]); 

As a footnote, here are the relevant C99 Standard excerpts:

  1. 6.3.1.8p2 defines the conversion from signed to unsigned type.

    If the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

  2. 6.3.1.3p2 defines how the conversion is done: By adding UINT_MAX + 1 to the signed representation.

    If the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

    So -1 => -1 + (UINT_MAX + 1) = UINT_MAX, for this scenario.

like image 145
cs95 Avatar answered Sep 26 '22 21:09

cs95