Добрый день! Накропал простенькую ф-цию — реверс. Ф-ция не работает — не меняет местами элементы.
В отладке выдает унайбл экцепишн. Компилятор 6 студия.
Кривые руки?
1. Стандартные подключаемые файлы пишутся в угловых скобках, например <iostream.h>
2. В качестве аргумента передается указатель на константу. Не зннаю, как в шестерке, а в дотнете тут точно будет засада — константу изменять нельзя.
3. В цикле j < count; — помысли-ка на д этим...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>1. Стандартные подключаемые файлы пишутся в угловых скобках, например <iostream.h>
Угу. LVV>2. В качестве аргумента передается указатель на константу. Не зннаю, как в шестерке, а в дотнете тут точно будет засада — константу изменять нельзя.
Пример был взят из книжки Шилдта "Самоучитель С++ 3 изд. дополненное и переработанное" стр.540 8 реш. Вот так.
И как мне теперь доверять всему тому, что я прочитал в ней? LVV>3. В цикле j < count; — помысли-ка на д этим...
в коде указано i < count. Но и тут ошибка, если следовать этому, то проходить будет весь массив, а count задает интервал,
поэтому нужно i < j тогда будет только заданный интервал.
Здравствуйте, Andruxa-1, Вы писали:
A1>Здравствуйте, LaptevVV, Вы писали:
LVV>>1. Стандартные подключаемые файлы пишутся в угловых скобках, например <iostream.h> A1>Угу. LVV>>2. В качестве аргумента передается указатель на константу. Не зннаю, как в шестерке, а в дотнете тут точно будет засада — константу изменять нельзя. A1>Пример был взят из книжки Шилдта "Самоучитель С++ 3 изд. дополненное и переработанное" стр.540 8 реш. Вот так. A1>И как мне теперь доверять всему тому, что я прочитал в ней? LVV>>3. В цикле j < count; — помысли-ка на д этим... A1>в коде указано i < count. Но и тут ошибка, если следовать этому, то проходить будет весь массив, а count задает интервал, A1>поэтому нужно i < j тогда будет только заданный интервал.
Ну, это просто говорит о том, что книгам Шилдта доверять не стОит. Или всен проверять. Бывают просто опецитки. Мы как-то взяли и набили его парсер арифметических выражений из какой-то его книжки. Обнаружили три ошибки, но все три можно было отнести к опечаткам — вроде того, что буква не та использовалась, или одна скобка вместо другой.
В книжках часто такое бывает — издательству нужно получать прибыль...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Ну, это просто говорит о том, что книгам Шилдта доверять не стОит. Или всен проверять. Бывают просто опецитки. Мы как-то взяли и набили его парсер арифметических выражений из какой-то его книжки. Обнаружили три ошибки, но все три можно было отнести к опечаткам — вроде того, что буква не та использовалась, или одна скобка вместо другой. LVV>В книжках часто такое бывает — издательству нужно получать прибыль...
Ну! Там вроде должон сидеть тех редактор (etc) и ошибка на опечатку не похожа — строковый литерал + указатель на него = const char* (вроде)
A1>Пример был взят из книжки Шилдта "Самоучитель С++ 3 изд. дополненное и переработанное" стр.540 8 реш. Вот так. A1>И как мне теперь доверять всему тому, что я прочитал в ней? LVV>>3. В цикле j < count; — помысли-ка на д этим... A1>в коде указано i < count. Но и тут ошибка, если следовать этому, то проходить будет весь массив, а count задает интервал, A1>поэтому нужно i < j тогда будет только заданный интервал.
Наверное Шилдта имел в виду:
void revers(char * pText)
{
int coutText = strlen(pText);
if (coutText <= 0)
return;
char tmpChe = '\0';
int j = coutText-1;
coutText /= 2;
for (int i = 0; i < coutText; i++)
{
tmpChe = pText[i];
pText[i] = pText[j];
pText[j] = tmpChe;
--j;
}
return;
}
Здравствуйте, LaptevVV, Вы писали:
LVV>1. Стандартные подключаемые файлы пишутся в угловых скобках, например <iostream.h>
Нет такого стандартного хедера как <iostream.h>. Есть <iostream>.
Кстати, книжки Шилдта известны очень низким качеством. Никому не рекомендую их читать.
LVV>2. В качестве аргумента передается указатель на константу. Не зннаю, как в шестерке, а в дотнете тут точно будет засада — константу изменять нельзя.
Здесь происходит конверсия строковой константы к char*. Такое компилируется (gcc тоже компилирует, с предупреждением), но потом может упасть в runtime.
Здравствуйте, alexeiz, Вы писали:
A>Здравствуйте, LaptevVV, Вы писали:
LVV>>1. Стандартные подключаемые файлы пишутся в угловых скобках, например <iostream.h> A>Нет такого стандартного хедера как <iostream.h>. Есть <iostream>.
Чел писал на VC6. Это было еще до стандарта... A>Кстати, книжки Шилдта известны очень низким качеством. Никому не рекомендую их читать.
Да фиг знает. Некоторые — довольно ничего так. LVV>>2. В качестве аргумента передается указатель на константу. Не зннаю, как в шестерке, а в дотнете тут точно будет засада — константу изменять нельзя. A>Здесь происходит конверсия строковой константы к char*. Такое компилируется (gcc тоже компилирует, с предупреждением), но потом может упасть в runtime. A>Вот так правильно: A>
A> char str[] = "1234567890";
A>
Эт да...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Andruxa-1, Вы писали:
A1>Пример был взят из книжки Шилдта "Самоучитель С++ 3 изд. дополненное и переработанное" стр.540 8 реш. Вот так. A1>И как мне теперь доверять всему тому, что я прочитал в ней?
Именно этой книге не доверять и выкинуть на помойку.
Здравствуйте, minorlogic, Вы писали:
M>Здравствуйте, Andruxa-1, Вы писали:
A1>>Пример был взят из книжки Шилдта "Самоучитель С++ 3 изд. дополненное и переработанное" стр.540 8 реш. Вот так. A1>>И как мне теперь доверять всему тому, что я прочитал в ней?
M>Именно этой книге не доверять и выкинуть на помойку.
A>>Кстати, книжки Шилдта известны очень низким качеством. Никому не рекомендую их читать. LVV>Да фиг знает. Некоторые — довольно ничего так.
То, что книги Шилдта — порядочное дерьмо — факт в мире С/С++ довольно известный. Как я понимаю, исключений нет. Да и если приведенный фрагмент из его книги — то это еще раз показывает качество его книг и его "ничего" книги уже неинтересны, потому как ничего хорошего в них.
accu.org, 11 reviews:
* C/C++ Programmer's Reference 2ed. by Herbert Schildt
* C: The Complete Reference 4ed by Herbert Schildt
* C++ from the Ground Up by Herbert Schildt — Not recommended
* C++ from the Ground Up (2nd ed) by Herbert Schildt — Not recommended
* C/C++ Programmer's Reference by Herbert Schildt — Not recommended
* Expert C++ by Herbert Schildt — Not recommended
* Java Programmers Reference by Herbert Schildt&Joe O'Neil — Not recommended
* MFC Programming from the GROUND UP 2nd Ed by Herbert Schildt — Not recommended
* STL Programming from the Ground Up by Herbert Schildt — Not recommended
* Teach Yourself C++ 3ed by Herbert Schildt — Not recommended
* Windows NT 4 Programming from the Ground Up by Herbert Schildt — Not recommended
Of course, the code must be complete enough to compile and link.
Некорректное использование данной функции пока оставим за скобками, рассмотрим саму функцию:
Первая алгоритмическая ошибка, которую уже заметили — это неправильное условие цикла — i < count вместо i < j;
Вторая алгоритмическая ошибка, менее заметная. Единица вычитается из count только в том случае, если count мы вычисляем внутри функции. А что будет в случае, если переменная count была вычислена и передана в функцию? А в этом случае мы получим совсем не тот результат, который ожидаем. Потому что значение j позиционируется в этом случае не на последнем символе строки, а следующем после него;
Использование значения по умолчанию для count говорит о том, что пишем мы на C++. Тогда не понятно почему обмен значениями мы реализуем "в рукопашную", с использованием лишних переменных, а не с использованием стандартного std::swap;
Семантика данной функции несколько неочевидна: предназначена ли она только для нуль-терминированных строк, или для произвольных последовательностей символов? Я бы вместо использования параметра по умолчанию в данном случае определил бы две функции с их реализацией одну через другую. Мы при этом однозначно понимаем намерения пользователя, и нет необходимости угадывать их при помощи проверки if(!count);
Использование постинкремента: i++, j-- там, где можно, ничего не меняя, использовать преинкремент — не есть хорошо;
К сведению, оператор "[]" для указателей — то же самое, что и "+". Следующие выражения эквивалентны:
str[i];
i[str]; //Оратите внимание на это выражение - оно корректно!
str + i;
i + str;
Т.е. в данном коде выполняется двойная арифметика — сперва для индексов, а потом для операций индексирования. Использование арифметики указателей в данном случае позволило бы избежать лишних операций сложения.
Последние два пункта касаются популярного вопроса о преждевременной оптимизации/пессимизации, и часто являются поводом для споров. С одной стороны ну чего "экономить на спичках", оптимизатор и сам сделает все "как надо". С другой стороны, на оптимизатор надейся, а сам не плошай. Зачем писать хуже, если, совершенно ничего не теряя, можно написать лучше?