Wake of Gods Forum | Форум Во Имя Богов

Full Version: С++, общая тема
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
(02.04.2012 22:04)Efrit Wrote: [ -> ]Это не "тонкости", это вообще должно быть на уровне гигиены Ab Как "помыть руки перед едой". Если переменная содержит размер чего-либо (неважно чего), или же переменная является индексом массива - то её обязательно нужно объявлять как unsigned.
я считаю, что это хоть и правильный способ, но слишком муторный. в С++ он оправдан, но в языках с более строгим приведением типов может доставлять неудобства в надобности явно приводить переменную к беззнаковому типу (к тому же, большинство таких языков отслеживают выход за рамки массива).
(02.04.2012 22:04)Efrit Wrote: [ -> ]Создавать объекты в куче без особой надобности плохо, потому что это часто приводит к утечкам памяти.
только если потом эти массивы куда-нибудь переприсваивать, возвращать в результате функции и т.п. "открывающая скобка" new и "закрывающая скобка" delete для меня как для тебя индексы и размеры беззнаковых типов.
(02.04.2012 22:04)Efrit Wrote: [ -> ]Например, после такой инициализации нельзя делать return - будет явная утечка памяти, равно как и при break с continue.
почти всегда алгоритм можно построить таким образом, что он будет иметь ровно одну точку входа и одну точку выхода.
Вирт в Оберонах вообще убрал беззнаковый тип. Для 32 бит хватает и двухгигового размера, а для 64 знаковый тип неисчерпаем.

Quote:почти всегда алгоритм можно построить таким образом, что он будет иметь ровно одну точку входа и одну точку выхода.
Всегда.
если использовать goto - да, всегда. хотя контрпример привести не могу.
Дейкстра доказал, что любая программа может быть переписана без goto. Break/continue/return/raise - это goto разной степени ограниченности. У меня любой исходник без указанных. Размеры - до 15 килострок (Эра и WiseEval).
хм, точно, так и есть.
gamecreator Wrote:почти всегда алгоритм можно построить таким образом, что он будет иметь ровно одну точку входа и одну точку выхода.
Да, я знаю.
Но это может привести к ухудшению читаемости кода: (Click to View)
   
   
Berserker Wrote:Вирт в Оберонах вообще убрал беззнаковый тип.
Ну и зря. Например, я хочу написать свой класс - динамический массив типа наподобие std::vector, с перегруженной операцией "квадратные скобки". И при этом, я хочу иметь нумерацию его элементов именно с нуля - дабы программист не мог обратиться к "отрицательному" элементу. И как же мне сделать это в Обероне, если там нету беззнакового типа?
(03.04.2012 10:55)Efrit Wrote: [ -> ]Согласись ведь, что такой код выглядит значительно лучше, чем если бы он составлялся без goto-подобных switch и return?
ай-яй-яй! как ты мог забыть про статический массив? он тут как нельзя кстати (и зачем вообще указатель передавать, это ведь не позволит передавать в функцию обычные значения; и почему это вдруг цифра (у тебя!!!) потребовала 32 бита?):
PHP Code:
charname_of_digit(unsigned char digit)  // функция возвращает название цифры в десятичной системе
{
   static 
char names[10][] = {"Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine"};
   if (
digit >=&& digit <=9) return names[digit];
   else return 
0;

(03.04.2012 10:55)Efrit Wrote: [ -> ]И как же мне сделать это в Обероне, если там нету беззнакового типа?
одна проверка, одно исключение
gamecreator Wrote:ай-яй-яй! как ты мог забыть про статический массив? он тут как нельзя кстати (и зачем вообще указатель передавать, это ведь не позволит передавать в функцию обычные значения; и почему это вдруг цифра (у тебя!!!) потребовала 32 бита?)
А причём здесь всё это? Как захотел объявить функцию, так и объявил. Понятное дело, что в реальности я всегда передаю обычные числа по значению... Ты смотри не на сигнатуру функции, а внутрь неё.
А приведённый тобой код содержит return Spiteful

gamecreator Wrote:одна проверка, одно исключение
Да я это прекрасно понимаю. Только в таком случае, ошибка будет обнаружена лишь на этапе исполнения программы. В то время как при использовании unsigned - уже на этапе компиляции!
(03.04.2012 16:05)Efrit Wrote: [ -> ]А приведённый тобой код содержит return Spiteful
ой. но это легко решаемо (тем более, что оказывается в многомерных массивах символов таки нужно указывать все размеры Bad хотя это логично, учитывая что в памяти они будут одномерными; более того, функция должна возвращать указатель на константу):
PHP Code:
const charname_of_digit(unsigned char digit)  // функция возвращает название цифры в десятичной системе
{
   static 
char names[11][6] = {"Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine",0};
   if (
digit <|| digit >10digit=10;
   return 
names[digit];



(03.04.2012 16:05)Efrit Wrote: [ -> ]В то время как при использовании unsigned - уже на этапе компиляции!
только если ты напрямую впишешь туда отрицательную константу
кстати в таком случае при ошибке возвратится не нулевой указатель, а пустая строка.
для возвращения нулевого указателя придется объявить переменную:
PHP Code:
const charname_of_digit(unsigned char digit)  // функция возвращает название цифры в десятичной системе
{
   static 
char names[10][6] = {"Zero","One","Two","Three","Four","Five","Six","Seven","Eight","Nine"};
   
char *result 0;
   if (
digit >=&& digit <=9result names[digit];
   return 
result;

Ну и чем твой получившийся код лучше моего? Ab Тебе приводится вводить не только дополнительную переменную, но и целый двумерный массив (кстати, нафига он static?) - и всё лишь ради того, чтобы избежать дублирования return-ов. Мне же проще использовать shared_ptr - и создавать ВСЁ в стеке, не парясь про утечки памяти при return-ах.


gamecreator Wrote:только если ты напрямую впишешь туда отрицательную константу

Да хотя бы и так. Всё равно, я получу сообщение об ошибке уже на этапе компиляции, и гарантированно исправлю её - в то время как ты узнаешь об ошибке лишь тогда, когда пользователь доберётся до критичной строчки кода. А это может случиться через сто лет, если код большой и всевозможных ситуаций много. Есть разница?

К тому же - сейчас, даже если вписать на место unsigned-переменной просто int-переменную (не обязательно константу) - то нормальные компиляторы всегда выдадут варнинг. То есть ошибка в любом случае будет замечена...
Ну вот я кажется уже неплохо стал ориентироваться в ссылках и указателях (за что всем спасибо)
Но все же вопросы остались.

Состряпал код, который внезапно работал только на половину.
Входной массив 012345, выходной 123455.
В функции прибавляю к каждому значению ячейки 1 (как видите последний не захотел)

После долгих попыток заставить работать последний адрес массива я решил попробовать вывести этот самый злосчастный адрес на форму, и посмотреть на него (может прозрение случилось бы,не сидеть же сложа руки =) ).
Корректно вывести не получилось(как мне кажется он неверен.) (Кстати не подскажите как?)
Но код внезапно заработал! Почему?
P.S. В книге "Моя первая программа на C/C++ - Нейбауэр А. " хорошо написано, а вот в справочнике "Программирование в C++ Builder А. Я. Архангельский" я недостаточно понял =(
Пакка, ещё бы твой пример работал Ab У тебя массив kakoy_to_massiv состоит лишь из 5 элементов, в то время как ты пытаешься "пройтись" вплоть до шестого его элемента (индексы от 0 до 5 включительно, то бишь всего 6 штук).

Да и объявлена функция kakaya_to_functcia как-то коряво. По уму, она должна принимать два элемента: первый - это адрес первого элемента массива, а второй - это размерность этого массива (в данном случае - число 5). В подобных функциях размерность массива должна всегда быть одним из её параметров, учти это.

Кстати, скажу тебе по секрету: запись &kakoy_to_massiv[0] эквивалентна записи kakoy_to_massiv 118 Поскольку "имя массива" в С - это и есть адрес его первого элемента.
Вот тебе отличная статья про массивы и указатели.

P.S. А вообще здорово, что ты пытаешься разобраться с указателями. Это, возможно, самый сложный шаг в освоении C++.
Quote:выглядит значительно лучше, чем если бы он составлялся без goto-подобных switch и return?
char* result = "error";
switch ...
case ... result = ...
case ... result = ...
return result.

В Обероне массивы начинаются с нуля, отрицательные константные смещения запрещены, границы проверяются во время выполнения.
Berserker Wrote:char* result = "error";
switch ...
case ... result = ...
case ... result = ...
return result.
Ну так switch-то ты в итоге никуда и не дел Ab

Berserker Wrote:В Обероне массивы начинаются с нуля, отрицательные константные смещения запрещены, границы проверяются во время выполнения.
Так я же говорил про свой класс "массива", а не про "встроенные" обероновские массивы... В C++ я увижу подобную ошибку уже при компиляции, а в Обероне - лишь при исполнении.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
Reference URL's