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
11969
Россия, Москва
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
11103
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
11969
Россия, Москва
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
11969
Россия, Москва
Munin в сообщении #1344261 писал(а):
Списки чего бы то ни было не рекомендуется делать zero-terminated.
Что не рекомендуется для своих списков/строк - понятно. Но бывает люди пишут свою обработку внешнего источника строк (как тот пример с переменными окружения). А потом хотят воспользоваться этой обработкой для одной строки чтобы не переписывать сложную обработку и не варганить обёртку. Конечно по правильному надо бы сначала разделить общий список на отдельные строки (и сложить в удобную структуру) и потом уже обрабатывать ... С некоторой надуманностью задачи согласен.

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

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


02/08/11
7059
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
7059
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
7059

(Оффтоп)

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, Супермодераторы



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

Сейчас этот форум просматривают: HungryLion


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

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