2015-10-24 5 views
0

Я написал такую ​​программу c и ожидаю получить правильные выходы.Почему вывод этой программы C неверен

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    int t; 
    scanf("%d", &t); 
    int a[t-1], b[t-1]; 
    //printf("%d\n",sizeof(a)); 
    do{ 
    scanf("%d %d", &a[t-1], &b[t-1]); 
    }while(--t); 

    do{ 
     printf("%d\n",a[t-1] + b[t-1]); 
    }while(--t); 

    return 0; 
} 

Но я получаю случайные значения. Что не так с этой программой? Попытка ввести количество попыток, затем ввести значения, а затем распечатать добавление этих значений.

P.S Инициализация массива здесь динамична. Действительно ли это? Если нет, то какой должен быть правильный путь?

+2

Что вы программируете, и каков ваш ожидаемый результат? –

+2

Что вы подразумеваете под «случайными значениями»? Кроме того, вы изменяете 't' в своем первом цикле while. Как только он достигнет 0, первый цикл остановится. Второй цикл никогда не будет выполняться, потому что 't' равно 0. – Arc676

+1

' int a [t-1], b [t-1]; '->' int a [t], b [t], bk = t; '..' t = bk; do {' – BLUEPIXY

ответ

2

Когда вы объявляете массив длины 10, этот показатель от 0 до 9. Для этого массива нет индекса 10.

В вашем коде, ваш массив имеет размер t-1

int a[t-1], b[t-1]; 

Таким образом, в первой итерации, оператор scanf() и printf() доступ a[t-1], который не присутствует. И, поскольку его цикл do while, он гарантированно будет работать по крайней мере один раз.

Доступ к массиву за пределами его границ - Undefined behavior. Итак, как заметил Кук в комментариях, все может случиться.

+0

a [t-1] нет в scanf, как это может быть не так? если t равно 10, то я обращаюсь к [9], который должен присутствовать? и как следующий printf печатает случайные значения, когда t уже равен 0 из первого цикла while while. Он должен печатать только один раз. –

+0

@MloBootloader вы объявили свой массив как 'int a [t-1]'. – Haris

1

Между прочтением всех значений и печатью всех значений, вы никогда не возвращаете t к его первоначальному значению. Вам нужно будет это сделать, возможно, используя другую переменную, чтобы сохранить исходное значение.

+0

Можно ли это сделать без использования другой переменной? –

+0

@MloBootloader Да. Просто используйте один цикл (после устранения проблем). –

+0

@MloBootloader Вы можете сделать это, не используя дополнительную переменную типа [this] (http://ideone.com/aQcPRi), но обратите внимание, что вход сохраняется в обратном порядке, то есть первый вход сохраняется в последнем слоте из массива, в то время как последний вход сохраняется в первом слоте массива. –

0

Размер массива должен быть постоянным, его невозможно установить во время выполнения. Для распределения памяти времени выполнения вам нужно использовать переменную указателя с функцией malloc. Поэтому в первую очередь вам нужно назначить постоянное значение переменной t во время объявления.

Просто подскажите, всегда пытайтесь объявить и инициализировать переменную перед любыми утверждениями. Инициализация массива должна предшествовать scanf, делая это, вы можете четко видеть проблему, то есть вы выделяете память (некоторые случайные), а затем получаете значение от пользователя. Компилятор должен делать аналогичную вещь, выделяя некоторую память произвольного размера, а затем получая значение t, теперь это значение t будет использоваться только в ваших итерациях, а не для распределения массива, поскольку массивы распределяются раньше с некоторым размером rand (что когда-либо мусор значение t указывает на момент его объявления). Иногда программа будет отображать некоторые случайные значения, и когда-нибудь она может потерпеть крах при доступе к памяти, которая не привязана.

+1

Я думаю, что это зависит от компилятора. Я помню, что раньше у меня была эта проблема, и эта функция была просто добавлена ​​в новые компиляторы, и я также узнал, что мы не можем этого делать. Я снова пересматриваю c, и сегодня я не сталкиваюсь с какой-либо проблемой с массивом переменной длины с моей версией gcc gcc 4.6.3. –

+0

вычислить количество элементов в массиве a перед первой итерацией и распечатать значение, повторно запустить вашу программу много раз. Значение элементов не должно быть похоже на то, что вы ввели в первом scanf, а это значит, что это может привести к сбою, но если это похоже, то !! ... для вычисления элемента вы можете использовать этот оператор; int num_of_ele = 0; num_of_ele = sizeof (a)/sizeof (int); – neutrino

Смежные вопросы