Печать элементов массива - PullRequest
       3

Печать элементов массива

3 голосов
/ 01 августа 2010

Ожидаемый результат следующей 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;

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

    return 0;
}

В чем причина?

Ответы [ 6 ]

6 голосов
/ 01 августа 2010

TOTAL_ELEMENTS без знака. -1, при преобразовании в беззнаковое, является действительно огромным числом, которое не меньше 6. Таким образом, ваш цикл никогда не запускается.

5 голосов
/ 01 августа 2010

При выполнении сравнения d <= (TOTAL_ELEMENTS-2) выполняется преобразование типа . d имеет тип signed int, а (TOTAL_ELEMENTS-2) имеет тип size_t, который является беззнаковым типом. Правила C гласят, что когда у оператора есть аргумент со знаком и без знака, а аргумент без знака больше или равен размеру аргумента со знаком, тогда аргумент со знаком преобразуется в без знака.

То есть сравнение заканчивается как:

(size_t) d <= (TOTAL_ELEMENTS-2)

И поскольку size_t без знака, (size_t) -1 - это действительно очень большое число, а не -1 больше. Для 32-разрядного size_t это будет 2 32 - 1 = 4 294 967 295.

Чтобы исправить это, вы можете явно привести правую сторону к подписанному int:

d <= (int) (TOTAL_ELEMENTS-2)

Или, лучше, просто избавиться от странной отрицательной индексации и тому подобного.

Для дальнейшего использования включите все предупреждения компилятора , которые вы можете. Например, gcc напечатает предупреждение, если вы включите -Wall -Wextra:

$ gcc -o arrayprint -Wall -Wextra -ansi arrayprint.c 
arrayprint.c: In function ‘main’:
arrayprint.c:11: warning: comparison between signed and unsigned
3 голосов
/ 01 августа 2010

Сначала я не знал.Но когда я скомпилировал его с помощью GCC, это было очевидно:

$ gcc -Wall -Wextra -Os a.c
a.c: In function `main':
a.c:11: warning: comparison between signed and unsigned

Итак, у вас есть сравнение следующим образом:

(int) -1 <= (size_t) 5

Поскольку один из типов подписан, а другойбез знака они сначала должны быть преобразованы в общий тип.В данном случае это size_t.Это делает это:

(size_t) -1 <= (size_t) 5

Теперь -1 нельзя представить в виде без знака.Следовательно, к нему добавляется 2 ^ 32 (или сколько угодно бит size_t), что делает его 4294967295. Таким образом, сравнение действительно таково:

4294967295 <= 5

И это false, поэтому тело цикланикогда не выполняется.

1 голос
/ 01 августа 2010

Причина в том, что цикл никогда не выполняется. Это потому, что TOTAL_ELEMENTS возвращает size_t, тип без знака.

Вы можете исправить это, приведя (TOTAL_ELEMENTS-2) к int.

0 голосов
/ 01 августа 2010

Просто измените

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))

С

#define TOTAL_ELEMENTS (int)(sizeof(array)/sizeof(array[0]))-2
0 голосов
/ 01 августа 2010

Вам необходимо сделать следующее:

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

как sizeof(...) создает значение без знака.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...