PDA

Просмотр полной версии : Программа на С(нет ошибки переполнения)


Tikson
04.01.2007, 22:17
Почему не возникает ошибка переполнения, при введении числа больше 32767 или меньше -32767 , при испольновании переменной типа int, хотя она должна возникать ?



#include <iostream.h>
void main(void)

{
int count;
int ending_value;
cout << "Введите конечное значение и нажмите Enter: ";
cin >> ending_value;
for (count = 0; count <= ending_value; count++)
cout << count << ' ';
}

_Great_
04.01.2007, 22:32
int, потя она должна возникать ?
о, ужас, кто тебе это сказал?
нифига она не должна возникать

Tikson
04.01.2007, 22:50
выдержка из книги, может это я что-то неправильно понял...
Следующая программа ASKCOUNT.CPP выводит сообщение, запрашивающее пользователя ввести число, при котором цикл должен завершиться. Затем программа выводит числа от одного до указанного значения:

#include <iostream.h>

void main(void)

{
int count;
int ending_value;
cout << "Введите конечное значение и нажмите Enter: ";
cin >> ending_value;
for (count = 0; count <= ending_value; count++)
cout << count << ' ';
}

Экспериментируйте с этой программой, вводя разные числа, например 10, 1 и даже 0. Если вы вводите значение 0 или 1, цикл for никогда не выполняется, потому что условие count <= ending_value сразу же ложно. Помните, если вы введете значение вне диапазона значений, которые может хранить переменная типа int, возникнет ошибка переполнения. Например, запустите программу и введите значение 50000. Поскольку это значение превышает наибольшее возможное для переменной типа int, то переполнение приводит к отрицательному значению, которое предотвращает выполнение цикла.
а что должно тогда происходить?

Tikson
04.01.2007, 23:36
_Great_
я совсем глупый вопрос задал? =)
хоят там же написано...
Например, запустите программу и введите значение 50000. Поскольку это значение превышает наибольшее возможное для переменной типа int, то переполнение приводит к отрицательному значению, которое предотвращает выполнение цикла.

_Great_
05.01.2007, 00:11
Попробуй запусти ее в отладчике и введи 5000000000000.
Ты увидишь, что записывается в переменную верхний предел для значений типа int: 2147483647. Переполнения не происходит по простой причине: оператор cin>>int_var "знает" размер переменной и не запишет в нее больше, чем она вмещает.
Переполнение возникает тогда, когда функция "не знает" размера буфера и случайно записывает больше, чем он вмещает.
Пример:

void main()
{
char local_buffer[10];
gets(local_buffer);
return 0;
}

gets() не знает размер буфера (он просто-напросто ей не передается), поэтому она записывает туда вслепую - авось, да поместится. А попробуй введи строчку длиннее 10 символов, например, ййййййййййййййййййййййййй . Буфер переполнится и инструкция return 0 вылетит с Access Violation.

Совет - читай мою статью про переполнение буфера:
https://forum.antichat.ru/thread26791.html

Zadoxlik
05.01.2007, 00:57
Тут имеется ввиду переполнение в знаковом разряде

Zadoxlik
05.01.2007, 01:19
Не возникает, потому что 32767 - это максимальное знаковое int для 16битных систем. У тебя книга старая. Щас уже во всю у всех 32битные процы и соответствующие компиляторы. Не говорю уже о том, что многие пересаживаютчя на 64битные.

В твоем случае (32 bit) переполнение наверно произойдет после 2147483647 (0x7FFFFFFF), дальнейшее увеличение числа приведет к появлению 1цы в знаковом разряде, что и называется переполнением ;)

_Great_
05.01.2007, 01:35
Аааа, если имеется в виду флаг Cf, тогда да.

Zadoxlik
05.01.2007, 15:37
Арифметических операций никаких не выполняется, поэтому флаг Cf тут непричем =Ь

_Great_
05.01.2007, 16:02
туплю %)

Tikson
05.01.2007, 19:59
В твоем случае (32 bit) переполнение наверно произойдет после 2147483647 (0x7FFFFFFF)
не , не происходит, ввожу 999999999999999999999999 и всеравно печатает
У тебя книга старая.посоветуйте новую , с сылкой если можно на скачку =)

Zadoxlik
05.01.2007, 20:35
А ты введи 2147483648 =)

Deem3n®
05.01.2007, 21:49
Tikson не путай "ошибку переполнения" т.е "превышение диапазона значений переменной" с bof.

Почему не возникает ошибка переполнения, при введении числа больше 32767 или меньше -32767 , при испольновании переменной типа int, хотя она должна возникать ?Она и возникает - выводит неправильное значение. Почему? Пример:#include <iostream>
using namespace std;

main(void)

{
unsigned short short_var = 99999999;
cout << short_var << endl;

return 1;
}

Допустим что у тебя 32битный проц -> у unsigned short 2 байта = 16 бит (0 - 65535).
Так вот:
101111101011110000011111111(bin) = 99999999(dec)
Дабы вместить значение в 2хбайтовую переменную, то что отмечено красным отбрасывается - вот и все. Остается:
1110000011111111(bin) = 57599
что и выводится на экран :)

Zadoxlik
05.01.2007, 22:16
bof = buffer overflow = переполнение буфера =) И может случиться оно и до тех пор, когда биты вылезут за разрядную сетку, занимаемую переменной в памяти =Р Если тип signed

Deem3n®
05.01.2007, 22:27
Zadoxlik - примером не порадуешь? А то у меня твой пост в голове не укладывается =)

Zadoxlik
05.01.2007, 22:29
Пример приведен топикстартером =)

_Great_
05.01.2007, 22:34
Допустим что у тебя 32битный проц -> у unsigned short 2 байта = 16 бит (0 - 65535).
Так вот:
101111101011110000011111111(bin) = 99999999(dec)
Дабы вместить значение в 2хбайтовую переменную, то что отмечено красным отбрасывается - вот и все. Остается:
1110000011111111(bin) = 57599
что и выводится на экран
это произойдет еще на этапе компиляции, причем умный компилер даже выдаст ворнинг о превышении даипазона значений.

bof = buffer overflow = переполнение буфера =) И может случиться оно и до тех пор, когда биты вылезут за разрядную сетку, занимаемую переменной в памяти =Р Если тип signed
никогда не получится запихнуть, например, в 2-х байтовую переменную три байта, поэтому переполнения буфера не будет никогда. Просто в переменную запишется другое, урезанное значение.

Zadoxlik
05.01.2007, 22:39
никогда не получится запихнуть, например, в 2-х байтовую переменную три байта, поэтому переполнения буфера не будет никогда. Просто в переменную запишется другое, урезанное значение.
естественно =Ь Но ситуация когда в переменную пытаются записать значение б0льшее чем она может вместить тоже называется переполнением. Происходить может на операционном устройстве, тогда будет передано сообщение в виде установленного флага CF или на этапе компиляции, тогда об этом любезно скажет компилятор

_Great_
05.01.2007, 22:42
Но ситуация когда в переменную пытаются записать значение б0льшее чем она может вместить тоже называется переполнением. Происходить может на операционном устройстве, тогда будет передавно сообщение в виде флага Cf или на этапе компиляции, тогда об этом любезно скажет компилятор
никто и не спорит :)

Zadoxlik
05.01.2007, 22:49
Да а еще может происходить просто при записи данных в память, выделенную под переменную, тогда об этом никто не скажет =) Как в примере автора темы

_Great_
05.01.2007, 23:02
В примере автора ничего плохого не случится. Просто запишется максимальное число, если введут число, большее максимально допустимого для переменной.
Гораздо страшнее, если будет чето-нить в роде gets(local_buffer)

Zadoxlik
05.01.2007, 23:06
не максимальное только, оно потом в минус уйдет неожиданно

_Great_
05.01.2007, 23:07
не максимальное только, оно потом в минус уйдет неожиданно'
вполне ожиданно, потому что установится самый старший знаковый бит числа, если число со знаком, конечно.
то есть для short это будет -32768 (кажется ;)), а для unsigned short: 65536

Zadoxlik
05.01.2007, 23:53
А кто тебе сказал что она должна вылетать?

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

_Great_
05.01.2007, 23:57
Как всегда разговор идет о разных вещах

Deem3n®
05.01.2007, 23:59
ОК .. тему закрываю.