Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322

Открыть новую тему     Написать ответ в эту тему

Crazy_Shrike



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Вопросы по программированию на C/С++

 
  • Справочники, книги
  • Выбор IDE (среды программирования)
     
    Постарайтесь дать как можно больше информации о возникшей проблеме - это в конце концов в ваших же интересах чтобы вам помогли.

    Решения конкретных задач собираются и обсуждаются в теме Задачи по C/С++ .

    Прежде чем просить помощи в задании...
    Если позарез надо и вы даже готовы заплатить

    Как правильно задавать вопросы, если вы хотите получить ответ.

    Полезные ссылки:
    C++(eng)

  • Всего записей: 241 | Зарегистр. 25-03-2004 | Отправлено: 13:37 06-05-2004 | Исправлено: AZJIO, 19:45 12-05-2014
    WiseAlex



    Софтовых дел М...
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude
    если нужна очень высокая скорость лучше вообще ничего стандартного для преобразований не использовать - посмотри на rsdn - там пробегала функция быстрого преобразования. можешь и сам написать, но я бы сначала сделал по-простому ч/з stl или c-stdlib и после профилирования уже думал что делать дальше

    Всего записей: 1001 | Зарегистр. 02-03-2003 | Отправлено: 14:22 24-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    И еще один вопрос:

    Код:
     
     
    const std::string &somefunc()
    {
      ...
      return somestring;
    };
     
    ...
     
    std::string str;
    ...
    str=somefunc();
     

     
    Насколько я понимаю, в строке в последней строке ( str=somefunc() ) функция возвращает ссылку на somestring, и строка str копирует из somestring все символы в свой буфер. А как надо объявить str чтобы она не копировала символы, а просто сама становилась ссылкой на somestring? Типа как если бы это был указатель на объект, и функция тоже возвращала указатель:

    Код:
     
     
    const std::string* somefunc()
    {
      ...
      return &somestring;
    };
     
    ...
     
    std::string *str;
    ...
    str=somefunc();
     


    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 14:37 24-01-2007
    FMeat

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Mickey_from_nsk
    Мне оно действительно надо и вот почему:
    "Реальные кулхацкеры" - наверное я перепутал данное вырожение, но я имел в виду что - это  озабоченные малолетки, накачавшие себе "хакерских" утил, долбящиеся куда нипоподя с дурацкими приколами, вроде удаления ntldr, отключения windowsInstaler, закачивания за твой счёт чего либо с интернета и самого пожалуй изощрённого - прописать строку в boot.ini, точнее в строке названия операционной системы, что мол "У вас установленна нелецензионная копия Windows! Некоторые возможности будут недоступны! ".
    Рабочий стол - после целого дня трещания телефона, с вопросами "Ой! А у меня деньги со счёта пропали! Что делать?" или "А у меня что то пираты с Windows'ом сделали!" просто на стену лезеш... Так что руки ой как чешуться чтобы надрать точку схождения двух прямых!
    Вы можете посоветовать как их подловить?
     
    Спасибо.

    Всего записей: 30 | Зарегистр. 25-12-2006 | Отправлено: 15:50 24-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    FMeat
    Реально легче накачать таких же хакерских утилит, и всех этих кулхацкеров - ими же да по тому же месту. А для того чтобы что-то толковое самому написать - уйдет уйма времени на изучение всех тонкостей системного и сетевого программирования. А лучше всем юзерам в сети рекомендовать пользоваться файрволами, но это уже другой топик.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 16:34 24-01-2007
    Labutin



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору

    Код:
    const std::string &somefunc()  
    {  
      ...  
      return somestring;  
    };  
     
    ...  
     
    std::string str;  
    ...  
    str=somefunc();

    Это страшная вещь! Лучше так вообще не пытаться. На что будет возвращаться ссылка? somestring где объявлена? Если это локальная переменная, то после выхода из функции будет возвращена ссылка на УНИЧТОЖЕННУЮ переменную! Возможно код будет казаться рабочим. Но на самом деле вы попадается в ситуацию "неопределенного поведения" программы.

    Код:
    const std::string* somefunc()  
    {  
      ...  
      return &somestring;  
    };

    Та же самая проблема. Если же somestring - это глобальная переменная, тогда еще можно рассчитывать на определенное поведение программы. Но вряд ли оно вам нужно.

    Всего записей: 935 | Зарегистр. 31-07-2001 | Отправлено: 17:00 24-01-2007
    Qraizer



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Mickey_from_nsk
    Цитата:
    Там просто это по определению невозможно (если разработчики не используют, конечно, TLS).
    Именно TLS для этого и используется. Посмотри исходники rtl-я.
    Отложенное копирование - это когда при создании копии строки на самом деле сохраняется только ссылка на оригинал, а разделение происходит только при необходимости, например, при модификации? Когда-то это считалось круто. На самом деле это только добавляет головной боли разработчикам и весьма не сильно влияет на производительность. Достаточно посмотреть такой пример
    Код:
    std::string str1("some string"), str2(str1);
     
    char &ch=str2[3];
    ch='E';
    чтобы понять, во что выливается "экономия" производительности. Не говоря уже о том, что в мультитридном окружении защитить экземпляр строки несложно, но с учётом возможности существования таких вот ch - практически невозможно.
    xdude
    Цитата:
    Иначе проделывается куча работы по выделению/освобождению памяти, если мне надо часто конвертирвать строки в числа.
    И еще я прочитал, что конвертирование чисел в строки и наоборот с помощью stringstream гораздо медленнее, чем с помощью atoi, atof, itoa и т.д. Так почему бы не использовать их? Только потому что это функции С, и стандарты не позволяют их использовать?
    Почему не позволяют? Библиотека C++ включает всю библиотеку C. Это даже в стандарте записано. Пользуйся на здоровье.
    Что касается производительности, то я не думаю, что состояние дел выглядит так уж катастрофически. Во-первых, используя stringstream-ы ты получаешь всю мощь локалей, форматирования и автоматического управления буфером. С учётом этого падение производительности уже не представляется таким большим. По крайней мере, чтобы самому динамически управлять буфером и выполнять форматирование после itoa, а то и _fcvt, это ещё написать и отладить надо, и не факт, что получится быстрее, чем у stringstream-а, а если ещё завязаться на localeconv() при этом, то я вообще не возьмусь за это забесплатно - слишком муторно и неинтересно. Во-вторых, форматированный ввод/вывод - это такая штука, которая весьма нечасто оказывается высокотребовательной к производительности. Какая мне разница, сколько времени программа будет разгребать коммандную строку, например? Когда это всё-таки бывает, то другое дело, имеет смысл пооптимизировать. В общем, я согласен платить некоторым падением производительности за тот сервис, который получаю.
    Кроме того, не надо каждый раз создавать новые stringstream-ы. Создай один раз и пользуйся. Строки можно подменять методом std::basic_stringbuf<>::str(), а для конкретного экземпляра указатель на буферизирующий класс можно получить std::basic_stringstream<>::rdbuf(). Да и seek-и ещё не отменяли.
    Цитата:
    А как надо объявить str чтобы она не копировала символы, а просто сама становилась ссылкой на somestring?
    Ну так и объяви её ссылкой: std::string& str;

    Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 17:06 24-01-2007 | Исправлено: Qraizer, 17:10 24-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Labutin

    Цитата:
    Это страшная вещь! Лучше так вообще не пытаться. На что будет возвращаться ссылка? somestring где объявлена?

    На самом деле все не так уж страшно Возвращается ссылка на приватную мемберскую переменную класса, так что она не уничтожится до конца жизни экземпляра класса.
     
    Qraizer

    Цитата:
    Ну так и объяви её ссылкой: std::string& str;

    Когда-то очень давно пробовал - компилятор начал ругаться, поэтому я почему-то думал, что это невозможно. Наверно, компилятор такой был

    Цитата:
    Строки можно подменять методом std::basic_stringbuf<>::str()

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

    Цитата:
    используя stringstream-ы ты получаешь всю мощь локалей, форматирования и автоматического управления буфером.

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

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 18:43 24-01-2007
    Labutin



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    xdude

    Цитата:
    На самом деле все не так уж страшно  Возвращается ссылка на приватную мемберскую переменную класса, так что она не уничтожится до конца жизни экземпляра класса.  

    Ну тогда да - проблем не будет. Просто из заголовка функции нельзя было понять, что это метод класса. Я предположил, что это обычная функция.

    Всего записей: 935 | Зарегистр. 31-07-2001 | Отправлено: 19:08 24-01-2007
    Qraizer



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    xdude
    Цитата:
    Я так и делаю, но ведь на самом-то деле строки не подменяются, а тупо копируются из одного места в другое, причем, если, например, происходит парсинг немаленького файла - то таких копирований происходит немерянное количество, тогда как при нормальном раскладе парсить можно из одного единственного буфера - того, в который изначально считан файл.
    Значит совет был лишний. Я имел в виду, что можно сэкономить на создании/уничтодении самого stringstream-f и его буфера. Объясни только, зачем читать из потока (файла) в строку, затем передавать её копию другому потоку (памяти), и только оттуда уже парсить? А сразу парсить файл не вариант? Вообще-то stringstream-ы предназначены для форматирования именно в памяти.
    Мне в общем-то тоже не совсем понятно, почему в STL не предусмотрели возможность просто указать строку-буфер. Может имеет смысл сделать производный от std::basic_stringbuf<> класс, т.е. создать свой класс буфера? И в нём позволить работать с буфером совместно с другим кодом программы.
    Цитата:
    В том-то и дело, что локали мне не нужны, а чрезмерная автоматика только мешает тонкой ручной настройке производительности.
    Ой ли? Вот это ты зря. Не пробовал пользоваться
    Код:
    std::locale locRus("RUS");
    someStream.imbue(locRus);
    ? И кроме того, боясь показаться назойливым, но тем не менее спрошу: ты реально смотрел разницу во времени работы программы, прежде чем утверждать, что вот в этом конкретном месте программы каждый десяток миллисекунд важен?
    Ну и напоследок. Если у меня возникла потребность максимально оптимизировать форматирование в памяти по производительности, то я бы в первую очередь попробовал использовать фасеты напрямую. Глянь вот сюда, я там выступал под Boroda-ой. У меня разница между num_get и atof составила 8%. В пользу atof(), правда, но если сравнить их потенциал функциональности... то это просто даром.

    Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 21:32 24-01-2007 | Исправлено: Qraizer, 21:33 24-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Объясни только, зачем читать из потока (файла) в строку, затем передавать её копию другому потоку (памяти), и только оттуда уже парсить?

    Ну, например, если я читаю не из обычного файла, а из сокета. Более того: данные могут быть зашифрованы (OpenSSL), т.е. их еще нужно пропустить через библиотеку OpenSSL. Можно, конечно, написать свой класс потока (или буфера, незнаю точно) для чтения из сокетов, и как вариант - из зашифрованных сокетов, но это долгий путь. Мне это нужно было всего-то для одной маленькой части одного большого проекта. Вот я и использовал std:string как накопительный буфер для получаемых данных, которые получались кусочками по 512 байт (специфика протокола), и все эти кусочки склеивал в std::string, а потом эту строку передавал в istringstream::str() и оттуда парсил. В общем, создавалась куча временных объектов, с множеством копирований/дублирований одних и тех же кусков одной и той же строки, и всего этого можно было избежать, если б время не поджимало. И вот теперь время не очень поджимает, и хочется разобраться. Но ситуация немного другая: есть входной буфер данных, я его пока что держу в std::string. Для парсинга юзаю string::find_first_of,  string::find_last_of, string::find_first_not_of, string::find_last_not_of. Так вот, у меня теперь такой вопрос: допустим, я нашёл какой-то кусок строки (скажем, начиная с 3-го и заканчивая 8-м символом строки), который мне нужно теперь преобразовать в число. Как это можно сделать наиболее оптимальным образом? Или, например, мне нужно передать этот кусок в функцию, которая потом скопирует его в std::string. Как это сделать без испотльзования лишних объектов/копирований? Можно ли использовать 2 итератора (на начало и конец отрезка), передать их в функцию, которая потом уже с их помощью инициализирует std::string? Или лучше/оптимальней передать этой функции найденные числовые индексы начала и конца строки, и ссылку на строку-буфер?
     

    Цитата:
    ты реально смотрел разницу во времени работы программы, прежде чем утверждать, что вот в этом конкретном месте программы каждый десяток миллисекунд важен?

    Вот эту табличку я сегодня нарыл в инете, поэтому и поднял вопрос:
    http://www.codeproject.com/string/string_conversions.asp
     

    Цитата:
    Не пробовал пользоваться
    Код:std::locale locRus("RUS");  
    someStream.imbue(locRus);  
    ?

    Дык в том-то и дело, что мне не нужна работа с локалями. Я работаю в основном с сетевыми протоколами, а там везде локаль один стандартный юзается - С (или POSIX). Т.е., мне не нужно число 12345678 представлять в форме 12 345 678 или 12,345,678, и наоборот тоже.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 23:24 24-01-2007
    Mickey_from_nsk

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    FMeat
    Думаю, в этом случае надо решать вопрос организационно. Чтобы определить кто это, когда и как делает - надо знать топологию сети. Если у вас один backbone, можно поставить на него свою машину-ловушку. Далее - по IP выяснить, кто в сети урод и принять меры вплоть до показательного перекусывания его кабеля (не обязательно сетевого ).  
    Отвечать уродством на уродство - это еще большее уродство. Просто таким придуркам надо сразу дать понять, что возмездие неотвратимо - сразу успокоятся.
    Ну и намекнуть им, что то что они делают - реальное уродство, а пользоваться вороваными кулхацкерскими прогами - реальная возможность нарваться на ОБЭП
    В общем, главное найти уродов. Если напишешь как устроена сеть - попробуем помочь с комплексом оперативно-розыскных мероприятий. Правда, боюсь, что тема offtopic.
    Qraizer
    Именно TLS для этого и используется. Посмотри исходники rtl-я.  
    Хм... Возможно. Но все равно, прелести strtok одной многозадачностью не ограничиваются. Полное отсутствие реентерабельности не позволяет организовать отдельно парсинг подстрок. В общем - хреноватая функция. Мой выбор - regex.
     
    Добавлено:
    Qraizer
    Ну и еще - в догонку. Случаем string::operator [] не const ли char возвращает?

    Всего записей: 636 | Зарегистр. 21-10-2002 | Отправлено: 11:04 25-01-2007 | Исправлено: Mickey_from_nsk, 11:07 25-01-2007
    Qraizer



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    xdude

    Цитата:
    Можно, конечно, написать свой класс потока (или буфера, незнаю точно) для чтения из сокетов, и как вариант - из зашифрованных сокетов, но это долгий путь.
    Не долгий. Если возьмёшь базовым классом уже готовой std::basic_stringbuf<>, и добавишь в него функциональность, которую ты и так должен будешь написать, то время не изменится. И новый "форматирующий" класс писать не надо. Простой std::basic_istream<> тебе вполне подойдёт.
    Табличку не смотри - так, как это там сделано, можно и самому результаты получить, поэтому на серьёзное исследование это статья не похожа. Ещё раз глянь мою ссылку и попробуй найти хоть одно существенное отличие.
    Цитата:
    ...допустим, я нашёл какой-то кусок строки (скажем, начиная с 3-го и заканчивая 8-м символом строки), который мне нужно теперь преобразовать в число. Как это можно сделать наиболее оптимальным образом?
     
    Наиболее оптимальный - прямое использование std::num_get<>::get, как это сделано в коде по ссылке из предыдущего поста. Тебе понадобятся итераторы. Аналогично итераторы же (или пару индекс/размер) выгоднее передавать в функцию, т.к. инициализация почти всегда эффективнее, чем переинициализация.
    Mickey_from_nsk
    Насчёт "других" недостатков strok я и не говорил. Я утверждал только наличие многопоточной безопасности. Причём для всех "неудобных" с этой точки зрения функций.
    Цитата:
    Ну и еще - в догонку. Случаем string::operator [] не const ли char возвращает?
    Их два:
    Код:
    const_reference operator[](size_type _Off) const;
    reference operator[](size_type _Off);
    Второй, как видишь, возвращает неконстантную ссылку.

    Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 13:20 25-01-2007
    FMeat

    Newbie
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude
    Ну такой способ я сам назыаю юзерством. По мойму не стоит делать того что сам не понимаеш. То есть качать неизвестно что, затем что б сделать нипойми чё. Раз оффтоп, обсуждать не будем, просто хочу заметить что юзеры, на то и юзеры, что файрвол им, как однокнопочная мыш...
    Mickey_from_nsk
    Спасибо за предложение, но думаю что я если мне не понятен смысл слова "backbone" то остальное будет мне тёмным лесом. Кстати, я не админ, просто его хороший друг, который не редко заходит на кружку чая.
     
    Чтоб мой пост не был полным оффтопом, всй же порошу вас, посоветовать мне какой либо ресурс, посвещённый данной проблеме, естественно применительно к C++.

    Всего записей: 30 | Зарегистр. 25-12-2006 | Отправлено: 19:13 25-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Отвечать уродством на уродство - это еще большее уродство.


    Цитата:
    Ну такой способ я сам назыаю юзерством.

    Блин, я не имел в виду заниматься тем же, чем и они. Я имел в виду накачать таких же уже готовых хакерских/крякерских утилит (а не писать их самому), чтобы отследить, кто этим уродством страдает. Изначально задача как была поставлена?

    Цитата:
    просканит он мои порты, к примеру, а я ему качаю свой *.txt (15 штук на рабочий стол, чтоб не проворонил) где пишу что "побаловался и хватит", и ссылку на двух битовый номер в троичной системе счисления.

     
     
    Добавлено:
    Qraizer

    Цитата:
    Аналогично итераторы же (или пару индекс/размер) выгоднее передавать в функцию, т.к. инициализация почти всегда эффективнее, чем переинициализация.

    Дык я так и не понял, что все-таки выгоднее (или удобнее) передавать: итераторы или начальный/конечный индекс (или индекс/размер) + ссылку на строку? Или это уже без разницы?

    Цитата:
    std::num_get<>::get

    Разбираюсь потихоньку

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 19:36 25-01-2007
    Qraizer



    Advanced Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Без разницы. Стандартом гарантируется, что операции копирования над итераторами являются дешёвыми. Подтверждение тому - практически везде по STLю они передаются по значению. Разыменование их - аналогично.

    Всего записей: 613 | Зарегистр. 08-08-2006 | Отправлено: 22:24 25-01-2007 | Исправлено: Qraizer, 22:25 25-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Может кто-нибудь подсказать, как лучше оформлять код: для вызова каждой функции, которая может вызвать исключительную ситуацию, создавать свой блок try ... catch, и отлавливать все возможные эксепшены, которые может  выкинуть функция, или создавать один блок try ... catch, а в нем уже вызывать серию необходимых функций?
    Например, надо вызвать такую послеовательность функций:

    Код:
     
      config.Load("config.ini");
      task=task_manager.LoadTask(config);
      task->perform;
     

    Каждая из этих функций может вызвать различные исключительные ситуации, и некоторые из них вызывают одинаковые исключения, например CFileAccessException. Как лучше поступить, чтоб потом самому не запутаться?
    И вообще, кто-нибудь может мне порекомендовать какие-нибудь источники, в которых можно почитать о стилях оформления исходного кода? Я сейчас в поисках оптимального стиля, кое-что об этом почитал, но для себя так толком ничего и не вынес. Например, одни рекомендуют делать так:

    Код:
     
    int some_func1()
    {
      int ret_val;
      ...
      if (some_func2() != err)
      {
        ...
        if (some_func3() != err)
        {
          ...
          if (some_func4() != err)
          {
            ...
            ret_val=ok;
            ...
          }
          else
            ret_val=err3;
          ...
        }
        else
          ret_val=err2;
        ...
      }
      else
        ret_val=err1;
      return ret_val;
    }
     

    другие так:

    Код:
     
    int some_func1()
    {
      ...
      if (some_func2() == err)
      {
        ...
        return err1;
      };
      ...
      if (some_func3() == err)
      {
        ...
        return err2;
      };
      ...
      if (some_func4() == err)
      {
        ...
        return err3;
      };
      ...
      return ok;
    };
     

    Что предпочтительней и почему - непонятно.
    Еще один момент: кто-то советует все переменные объявлять в самом начале функции, чтобы улучшить читабельность кода, кто-то - по мере их необходимости в коде.
    Где можно почитать об общих рекоммендациях по этим вопросам, чтобы определить для себя САМЫЙ_УДОБНЫЙ_И_ОПТИМАЛЬНЫЙ_СТИЛЬ_В_МИРЕ ?
    Заранее спасибо.

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 02:11 26-01-2007
    TeXpert



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    И вообще, кто-нибудь может мне порекомендовать какие-нибудь источники, в которых можно почитать о стилях оформления исходного кода?

    Керниган и Пайк, Практика программирования.
     
    А вот я предпочитаю такой стиль:

    Код:
     
    int some_func1(){  
      ...  
      if (some_func2() == err){  
        ...  
        return err1;  
      };  
      ...  
      if (some_func3() == err){  
        ...  
        return err2;  
      };  
      ...  
      if (some_func4() == err){  
        ...  
        return err3;  
      };  
      ...  
      return ok;  
    };
     

    Конструкция  

    Код:
     
    if (some_func4() != err)  
          {  
            ...  
            ret_val=ok;  
            ...  
          }  
          else if (some_func5() != err){
                 ...
                 ret_val=err5;
                 }
            ret_val=err3;
          ...
     

    раздражает тем, что трудно читаема при многократном вложении.
    А про объявления -- глобальные лучше вначале.

    ----------
    Майкудук, Пришахтинск не предлагать!:)
    А на Пирогова приходит снова весенний гомон...

    Всего записей: 3604 | Зарегистр. 08-02-2003 | Отправлено: 03:08 26-01-2007 | Исправлено: TeXpert, 03:14 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    TeXpert

    Цитата:
    Керниган и Пайк, Практика программирования

    Спасибо, надо будет поискать.
     

    Цитата:
    А вот я предпочитаю такой стиль...  

    А вот такой ещё вопросик тогда При программировании WinAPI/COM/OLE сталкивался. В функции последовательно инициализируются какие-то OLE-объекты (причем, это не С++, а С. т.е., классов нет, возвращаются указатели на структуры), для этого нужно вызвать около 10 функций, и если какая-то из них что-то инициализировать не смогла, то все инициализированные перед этим указатели нужно освободить и вернуть из функции код ошибки. Это как оптимальнее всего сделать? Я использовал сначала типа такой конструкции:

    Код:
     
    void* somefunc()
    {
      int err;
      void *obj1=NULL,*obj2=NULL,...,*objN=NULL;
      ...
      obj1=APIfunc1(...);
      if (!obj1)
      {
        return NULL;
      };
      ...
      obj2=APIfunc2(...);
      if (!obj2)
      {
        free(obj1);
        return NULL;
      };
      ...
      objN=APIfuncN(...);
      if (!objN)
      {
        free(objN-1);
        ...
        free(obj2);
        free(obj1);
        return NULL;
      };
     
    return SOMETHING;
    };
     

    Потом решил использовать goto, хотя глубоко убежден, что он противоречит принципам структурированного программирования, и использовать его в языках высокого уровня - это кощунство. Но получилось гораздо более компактно:

    Код:
     
    void* somefunc()
    {
      int err;
      void *obj1=NULL,*obj2=NULL,...,*objN=NULL;
      ...
      obj1=APIfunc1(...);
      if (!obj1)
        goto _err;
      ...
      obj2=APIfunc2(...);
      if (!obj2)
        goto _err;
      ...
      objN=APIfuncN(...);
      if (!objN)
        goto _err;
      ...
    _err:
      if (objN) free(objN);
      if (objN-1) free(objN-1);
      ...
      if (obj2) free(obj2);
      if (obj1) free(obj1);
      return (is_err ? NULL : SOMETHING);
    };
     

     
    А есть какой-то другой способ?
     
    Добавлено:
    И еще вопрос по мультипоточности: чёй-то никак не пойму, если у меня есть char *buf=(char*)malloc(255), ну или любой другой буфер в хипе, можно ли из него читать одновременно несколькими потоками без блокирования всякими мьютексами и иже с ними? И что будет, если несколько потоков одновременно попытаются записать в этот буфер (например, buf[0]=0;)? Просто данные могут потеряться, или система закроет программу (типа "segmentation fault" или "Программа выполнила недопустимую операцию...")?
     
    Добавлено:
    Потоки=threads, а не потоки ввода-вывода из <iostream>

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 03:26 26-01-2007 | Исправлено: xdude, 04:34 26-01-2007
    TeXpert



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    xdude

    Цитата:
    free(obj1);

    А где malloc?
     
    Сам по себе goto неплох, но вот

    Цитата:
    Но получилось гораздо более компактно

    у тебя там ошибка -- ты рискуешь освобождать нулевые указатели. А насчёт другого способа надо подумать.
    Можно так: указатели obj1, obj2,..., objN заносишь в массив, а с массивом всё компактней в цикле.
     
    Я думаю, читать из бефера можно, без блокировки, а вот при записи нужно даже блокировать чтение другими потоками. В противном случае катастрофы вряд ли произойдёт, а вот достоверность данных никто не будет гарантировать.

    ----------
    Майкудук, Пришахтинск не предлагать!:)
    А на Пирогова приходит снова весенний гомон...

    Всего записей: 3604 | Зарегистр. 08-02-2003 | Отправлено: 04:07 26-01-2007 | Исправлено: TeXpert, 04:17 26-01-2007
    xdude



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    TeXpert

    Цитата:
    у тебя там ошибка -- ты рискуешь освобождать нулевые указатели.

    Да, протупил, торопился - забыл if-ы повставлять. Исправил исходный пост, на самом деле оно вот так выглядит.

    Цитата:
    Я думаю, читать из бефера можно,

    Я тоже так думаю, но хотелось бы убедиться наверняка.

    Цитата:
    В противном случае катастрофы вряд ли произойдёт

    А это точно? Система не завершит работу программы? Или могут быть и такие системы, которые при этом тупо убьют процесс?

    Всего записей: 481 | Зарегистр. 04-11-2004 | Отправлено: 04:17 26-01-2007
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по программированию на C/С++


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru