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

c arrays

18418 просмотра

6 ответа

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

Какова причина ?

Автор: josh Источник Размещён: 12.11.2019 09:40

Ответы (6)


5 плюса

Решение

Когда вы делаете сравнение d <= (TOTAL_ELEMENTS-2), выполняется преобразование типа . dимеет тип signed intwhile, (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
Автор: John Kugelman supports Monica Размещён: 01.08.2010 06:10

6 плюса

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

Автор: zvrba Размещён: 01.08.2010 06:02

3 плюса

Сначала я не знал. Но когда я скомпилировал его с помощью 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не может быть представлен без знака. Следовательно, size_tк нему добавляется 2 ^ 32 (или сколько бы битов ), что делает его 4294967295. Таким образом, сравнение действительно таково:

4294967295 <= 5

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

Автор: Roland Illig Размещён: 01.08.2010 06:11

1 плюс

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

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

Автор: Frerich Raabe Размещён: 01.08.2010 06:04

0 плюса

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

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

as sizeof(...)выдает значение без знака.

Автор: reece Размещён: 01.08.2010 06:07

0 плюса

Просто поменяй

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

С участием

#define TOTAL_ELEMENTS (int)(sizeof(array)/sizeof(array[0]))-2
Автор: Cristy Размещён: 01.08.2010 06:30
Вопросы из категории :
32x32