2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней. На страницу Пред.  1, 2, 3, 4, 5 ... 7  След.
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 21:39 
Заслуженный участник


20/08/14
11070
Россия, Москва
arseniiv
А если в массиве могут быть строки не только с нулём на конце (а и например с символом '$' как было кое-где в DOS)? Делать по макросу на каждый вариант окончания или назвать макрос сразу SYMBOL_SUFFIXED (сразу учесть в названии и не однобайтовые символы)? А если может заканчиваться не байтом, а к примеру двумя нулевыми байтами (как бывает для списка строк ровно из одной строки :facepalm:, если вдруг её надо передать в функцию обрабатывающую лишь списки строк, типа переменных окружения в DOS при запуске программы)?

На мой взгляд запись char s[3+1]; достаточно информативна (важно для не самых крутых профи) и лаконична (важно для профи).

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 21:49 
Заслуженный участник


27/04/09
28128
Dmitriy40 в сообщении #1344250 писал(а):
А если в массиве могут быть строки не только с нулём на конце (а и например с символом '$' как было кое-где в DOS)?
А с таким массивом будет удобно работать? Откуда он может появиться?

Вообще лично я бы просто не писал на C, или не писал на нём что-то, касающееся работы со строками. :mrgreen: Предложение было от балды.

Кстати, сначала хотел предложить сделать константу, равную единице, и прибавлять её, но быстро додумался до большего.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 21:54 


29/12/13
306
Я извиняюсь. Дискуссия очень интересная. Не смог пройти мимо.


warlock66613 в сообщении #1344128 писал(а):
лучше делать так:
Код:
char s[3 + 1];
scanf("%3s", s);
Тогда при любом содержимом входного файла переполнения не будет.

Обратите также внимание на запись 3 + 1 вместо просто 4: это снижает вероятность запутаться и забыть, что из четырёх байт только три можно задействовать для полезной информации.


Такое кодирование сразу бросается в глаза. Как что-то анормальное. Я не помню, кто когда-либо встречал такое. Поэтому имею вопросы.
1) Основное. Мне правда очень интересно стало, вы этот совет, где-то почерпнули или сами разработали?
2) Лирика. Само по себе, даже начинающих приучать писать бесполезный код. Вместо того, чтобы помнить и отлаживать, разве это может быть правильным подходом?
4) Странности. Почему 3+1 ? (push - 4 символа, pu - 2) ???
5)
warlock66613 в сообщении #1344128 писал(а):
Тогда при любом содержимом входного файла переполнения не будет.
--- Почему так уверены? Например, может быть переполнение arr[] при $$ Q > 20 $$

arseniiv в сообщении #1344229 писал(а):
Может, тогда вообще

#define ZERO_SUFFIXED(n) ((n)+1)
char s[ZERO_SUFFIXED(3)];


К слову. Это выглядит лучше, хотя бы потому, что 3+1 обрабатывается препроцессором, а не компилятором.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 21:55 


27/08/16
9426
Dmitriy40 в сообщении #1344250 писал(а):
А если в массиве могут быть строки не только с нулём на конце (а и например с символом '$' как было кое-где в DOS)?
Exterminate! :evil:

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:02 
Заслуженный участник


27/04/09
28128
Seman в сообщении #1344256 писал(а):
хотя бы потому, что 3+1 обрабатывается препроцессором, а не компилятором
:shock: Препроцессор не отменяет компилятора.

Вообще на самом деле я не понимаю, об чом спор. В нормальной программе нет магических констант, и максимальные длины всех строк, которые в код входят, имеют свои названия. В таком случае char s[MAX_LEN + 1]; (или аналогичной конструкции с явной единицей где-то внутри неё) там, где терминированные строки, никак не избежать.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:02 
Заслуженный участник


20/08/14
11070
Россия, Москва
arseniiv в сообщении #1344253 писал(а):
А с таким массивом будет удобно работать? Откуда он может появиться?
Неудобно. А что делать если функция вывода строки из DOS-а (№9 в int 21h) берёт на вход именно такие строки ... Неудачное решение, да.
Что под DOS уже давно никто не пишет - согласен. Однако строки с ненулевым терминатором всё же встречаются (например часто удобно CR+LF таковым считать), во всяком случае в микроконтроллерах (где как раз и памяти часто жалко).

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:06 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Dmitriy40 в сообщении #1344250 писал(а):
А если может заканчиваться не байтом, а к примеру двумя нулевыми байтами (как бывает для списка строк ровно из одной строки)?

Списки чего бы то ни было не рекомендуется делать zero-terminated. Либо явный счётчик, либо связный список (желательно двусвязный).

Списки строк не стоит хранить в сплошном буфере - со строками часто бывают нужны модифицирующие операции. Так что, массив указателей (или список указателей, или как угодно).

Dmitriy40 в сообщении #1344250 писал(а):
На мой взгляд запись char s[3+1]; достаточно информативна (важно для не самых крутых профи) и лаконична (важно для профи).

Подпишусь. Макросы тут излишни (строка комментария - возможно, не излишня; именованная константа для длины - тоже).

Seman в сообщении #1344256 писал(а):
Это выглядит лучше, хотя бы потому, что 3+1 обрабатывается препроцессором, а не компилятором.

Это вообще не плюс.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:07 
Заслуженный участник


27/04/09
28128
Dmitriy40 в сообщении #1344260 писал(а):
А что делать если функция вывода строки из DOS-а (№9 в int 21h) берёт на вход именно такие строки ...
Мне просто прочиталось, что вы предлагали в одном и том же массиве держать и 0- и '$'-терминированные строки. А если надо их выводить в DOS, то, видимо, строк первого типа в нём не должно быть? А то вспоминается недавняя тема сами знаете кого про одновременно и даблы, и инты в одном массиве вместо как минимум двух.

Dmitriy40 в сообщении #1344260 писал(а):
Однако строки с ненулевым терминатором всё же встречаются
Ну, против этого я выше и не возражал. :-)

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:15 
Заслуженный участник


20/08/14
11070
Россия, Москва
Munin в сообщении #1344261 писал(а):
Списки чего бы то ни было не рекомендуется делать zero-terminated.
Что не рекомендуется для своих списков/строк - понятно. Но бывает люди пишут свою обработку внешнего источника строк (как тот пример с переменными окружения). А потом хотят воспользоваться этой обработкой для одной строки чтобы не переписывать сложную обработку и не варганить обёртку. Конечно по правильному надо бы сначала разделить общий список на отдельные строки (и сложить в удобную структуру) и потом уже обрабатывать ... С некоторой надуманностью задачи согласен.

arseniiv в сообщении #1344262 писал(а):
Мне просто прочиталось, что вы предлагали в одном и том же массиве держать и 0- и '$'-терминированные строки. А если надо их выводить в DOS, то, видимо, строк первого типа в нём не должно быть?
Не должно. По крайней мере тех, что будут выводиться, хранить то можно любые. Но смешивать я не предлагал. :-) По хорошему такие массивы надо вообще другого типа делать, чтобы компилятор проверял ошибочное использование, а не глюки в рабочей программе ловить.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:16 
Заслуженный участник


02/08/11
6874
Seman в сообщении #1344256 писал(а):
вы этот совет, где-то почерпнули
Да, это из какой-то книги, но из какой - не могу сказать. Собственно, 3 + 1 - это частность. Идея в том, что часть функций принимает на вход длину без учёта нулевого байта, а часть - с учётом, поэтому в коде обязательно будут прибавления и/или отнимания единицы. И вот для единообразия и чтобы меньше путаться где размер с учётом нулевого байта, а где - без, предлагается везде использовать размер без нулевого байта, а когда нужен размер с учётом нулевого байта - прибавлять единицу явным образом и "по месту".

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:17 


29/12/13
306
arseniiv в сообщении #1344259 писал(а):
Seman в сообщении #1344256 писал(а):
хотя бы потому, что 3+1 обрабатывается препроцессором, а не компилятором
:shock: Препроцессор не отменяет компилятора.

Вообще на самом деле я не понимаю, об чом спор.

1) Я ни с кем пока не спорю. Мне интересно стало откуда такой совет. Кто вообще может давать такие советы?
2) Да, вы правы, переклинило, что препроцессор 4 посчитает и подставит. Нет он 3+1 так и подставляет, поэтому без разницы.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:22 
Заслуженный участник


02/08/11
6874
Seman в сообщении #1344256 писал(а):
Вместо того, чтобы помнить и отлаживать, разве это может быть правильным подходом?
Идеальный код не требует отладки (всё и так ясно при одном взгляде на него) и мучительных попыток вспомнить, о чём вы (а часто - кто-то другой) думали, когда писали код.

-- 07.10.2018, 23:24 --

Seman в сообщении #1344256 писал(а):
Почему 3+1 ?
Потому что я показывал не как исправить ошибку (про это уже сказали), а как отрефакторить ошибочный код, чтобы ошибку было легче заметить.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:33 


29/12/13
306
warlock66613 в сообщении #1344266 писал(а):
Да, это из какой-то книги, .


Ясно.

(Оффтоп)

Тоже, дам совет, может кому пригодится. Я не настаиваю, на его универсальности. Какие-то книжки тоже хорошо.
Но чтобы научится что-то делать хорошо, имеет смысл посмотреть как это делают профессионалы и стараться делать также. Возьмите любой доступный вашему пониманию проект с открытым кодом. Написанный опытными программистами, например, coreutils . (это основные простые юниксовые утилиты). Посмотрите, как реализованы на C простые утилиты таже cat, сам стиль кодирования. И старайтесь подражать.(разобрав и понимая как у них, разумеется, не просто подражая)


-- 07.10.2018, 22:35 --

warlock66613 в сообщении #1344268 писал(а):
Идеальный код не требует отладки


(Оффтоп)

Идеального не существует. Отлаживать надо уметь. Новичок, через отладку человек учится понимать свои ошибки на опыте. ИМХО

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:42 
Заслуженный участник


02/08/11
6874

(Оффтоп)

Seman в сообщении #1344271 писал(а):
И старайтесь подражать.
Не получится: в разных проектах стиль диаметрально противоположный. Кроме того, надо просто знать чему конкретно подражать, сами вы этого просто не заметите.

 Профиль  
                  
 
 Re: Странное поведение оператора if else в языке Си
Сообщение07.10.2018, 22:46 
Заслуженный участник
Аватара пользователя


30/01/06
72407
Dmitriy40 в сообщении #1344265 писал(а):
Но бывает люди пишут свою обработку внешнего источника строк (как тот пример с переменными окружения).

Если мне не совсем изменяет склероз, переменные окружения-то передаются вполне как массив указателей, слава богу, это ещё с рождения Си так заведено.

Seman в сообщении #1344267 писал(а):
Кто вообще может давать такие советы?

Люди опытные, сталкивающиеся с типовыми проблемами новичков. Ещё из той же серии: проверка на равенство не
    if (a==1)
а
    if (1==a)
во избежание ошибки "присваивание вместо равенства" (впрочем, мне кажущийся менее удачным, я так и не научился).

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

Seman в сообщении #1344271 писал(а):
Но чтобы научится что-то делать хорошо, имеет смысл посмотреть как это делают профессионалы и стараться делать также.

Не всё, написанное профессионалами, стоит сразу воспроизводить новичку. Следует подняться к этому, накапливая (возможно, годами) свой опыт. Поначалу следует писать проще (да и крутому профессионалу следует писать проще, это высший дзен).

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Эта тема закрыта, вы не можете редактировать и оставлять сообщения в ней.  [ Сообщений: 102 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 7  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group