Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Есть ли аналог exception? чтобы в Си выйти из циклов и вложений... 
:(
    Опции темы
Rockie
Дата 11.4.2007, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



Цитата(Anton Vatchenko @  11.4.2007,  17:08 Найти цитируемый пост)
Пишу сервер... В нем во многих местах идет чтение из сокета. И тут я узнаю, что соединение закрыто, то есть нужно выйти из цикла... Но проблема в том, что это узнает моя функция read, а она может быть вызвана из другой функции и т. д...

Anton Vatchenko, вопрос не оч. понятен, но наверное можно использовать глобальную переменную - флаг, например:
Код
int isSocketClosed = 0;

и уже из разных функций считывать/устанавливать ее значение.




--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
MAKCim
Дата 11.4.2007, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(bilbobagginz @  11.4.2007,  19:10 Найти цитируемый пост)
но я правда не понимаю зачем писать что-то на Си, если можно использовать готовые средства Си++.

хм, интересная логика


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bilbobagginz
Дата 11.4.2007, 19:48 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 3
Всего: 317



MAKCim, я сам на Си пишу, когда нужно smile
я не против Си, а к тому, что если уже пишешь приложение на Си, нужно серьезно взвешивать, если это и есть путь истинный - коли тебе нужны исключения и т.д. - не фиг писАть на Си.

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



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
ivashkanet
Дата 11.4.2007, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(MAKCim @  11.4.2007,  17:52 Найти цитируемый пост)
ivashkanet, пример

MAKCim, хороший пример, но: у тебя только одна функция, а не 
Цитата(Anton Vatchenko @  11.4.2007,  16:08 Найти цитируемый пост)
она может быть вызвана из другой функции и т. д...

В пределах одной функции проблема ясна и решается более-менее просто.

Вопрос ведь в том, как "просигналить" функциям которые выше текущей по стеку, а не в том, как обработать ситуацию в самой функции.
Цитата(powerfox @  11.4.2007,  17:54 Найти цитируемый пост)
Можно реализовать какую-нибудь функции exception(bla-bla);
А там обрабатывать bla-bla и иметь набо goto.

Не совсем понятно, но все же:
В С/С++ можно "прыгать" за пределы функции в другую функцию? И что тогда будет со стеком, что будет с методом, который вызвал эту функцию и ожидает ответа от нее?

В любом случае механизм получится негибким. Что будет если мы захотим добавть новую функцию в цепочку...
Цитата(Rockie @  11.4.2007,  18:23 Найти цитируемый пост)
int isSocketClosed = 0;

ИМХО, лучший способ. А вместо try/catch --- if/else
Правда наличие выставленного флага не прерывает выполнение функции и не ищет "ближайшую инструкцию отлова этого флага" (как в случае с exception), но это, все-таки, решение.
PM MAIL WWW ICQ   Вверх
MAKCim
Дата 11.4.2007, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(ivashkanet @  11.4.2007,  20:44 Найти цитируемый пост)
Вопрос ведь в том, как "просигналить" функциям которые выше текущей по стеку, а не в том, как обработать ситуацию в самой функции.

ошибки в функциях обрабатывать с помоощью goto <обработчик> и возвращать код ошибки
применяя рекурсивно данный подход ко всем функциям в программе - решаем проблему
Код

int do_code() {
    int error = 0; /* ошибки нет */
    key_t key = ftok(KEY_PATH, 0);
    if (key < 0) 
        return errno; /* тут все нормально */
    int sem_id = semget(key, SEMAPHORES_COUNT, IPC_CREAT | IPC_EXCL | 0666);
    if (sem_id < 0)
        return errno; /* тут тоже все хорошо */
    int shm_id = shmget(key, PAGE_SIZE, IPC_CREAT | IPC_EXCL | 0222);
    if (shm_id < 0) { /* а вот тут уже не хорошо, потому как семафор уже создан и необходимо его освободить */
        error = errno;
        goto destroy_sem;
    }
    int fd = open(PATH, O_RDONLY);
    if (fd < 0) { /* а тут совсем нехорошо, надо освободить и семафор, и shared memory */
        error = errno;
        goto destroy_shm;
    }
    void *ptr = malloc(PAGE_SIZE);
    if (ptr == NULL) /* а тут катастрофа - 3 открытых ресурса */
        goto destroy_file;
...
destroy_file:
    close(fd);
destroy_shm:
    shmctl(shm_id, IPC_RMID, NULL);
destroy_sem:
    semctl(sem_id, 0, IPC_RMID);
success:
    return error; /* 0 или код ошибки */
}


Добавлено через 2 минуты и 28 секунд
bilbobagginz
вообщем согласен
но, имхо, исключения - это не такая большая проблема, чтобы менять язык разработки


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
ivashkanet
Дата 12.4.2007, 08:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(MAKCim @  11.4.2007,  20:37 Найти цитируемый пост)
ошибки в функциях обрабатывать с помоощью goto <обработчик>

Повторяю еще раз: внутри самой функции можно хоть с ГоуТами, хоть с Ифами, хоть с чем угодно.
Твой код, например, можно запросто переписать не используя goto и смотреться он будет не менее красиво.
Цитата(MAKCim @  11.4.2007,  20:37 Найти цитируемый пост)
возвращать код ошибки
применяя рекурсивно данный подход ко всем функциям в программе - решаем проблему

Вот тут самая тонкость. Но все же, это решение (которое я давал несколькими постами выше).

Итог (личное мое ИМХО):
Лучший вариант --- возвращать код ошибки и обрабатывать его во всех функциях, которые в этом нуждаются.
Тоже вариант --- выставлять некий флаг и "ждать" его в определенном месте, если он пришел, то объявлять ошибочными все данные полученные до этой строчки и обрабатывать ошибку. (этот вариант ближе к механизму exception'ов, но, ИМХО, хуже, так как выполнение программы продолжается).
PM MAIL WWW ICQ   Вверх
MAKCim
Дата 12.4.2007, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(ivashkanet @  12.4.2007,  08:44 Найти цитируемый пост)
Твой код, например, можно запросто переписать не используя goto и смотреться он будет не менее красиво.

 smile  smile  smile 
(только на С пожалуйста)

Это сообщение отредактировал(а) MAKCim - 12.4.2007, 08:52


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bilbobagginz
Дата 12.4.2007, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 3
Всего: 317



Цитата

но, имхо, исключения - это не такая большая проблема, чтобы менять язык разработки 

смотря какие аспекты механизма исключения тебе нужны.

да, хотелось бы видеть читабельный и удобный для доработок примерчик без goto smile

(сумлеваюсь, что есть такой...)


--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
ivashkanet
Дата 12.4.2007, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



MAKCimbilbobagginz, вот пример без goto и, ИМХО, не менее читабельный (по мне, даже более)
+ работа с ресурсами и "сборка мусора" превратились в два, относительно, независимых процесса.

1) Вариант кода с излишними коментариями:
Код

        int do_code()
        {
            int errno = -1269; // Код ошибки

            int error = 0; /* ошибки нет */
            int key = ftok(KEY_PATH, 0);
            if (key < 0)
                return errno; /* тут все нормально */
            int sem_id = semget(key, SEMAPHORES_COUNT, IPC_CREAT | IPC_EXCL | 0666);
            if (sem_id < 0)
                return errno; /* тут тоже все хорошо */
            // Так как выше все нормально, то я это не трогал, 
            // но все же я бы это тоже поменял

            // Начало моего кода
            // Единственное, пришлось объявлять переменные отдельно
            int fd;
            void *ptr;

            int shm_id = shmget(key, PAGE_SIZE, IPC_CREAT | IPC_EXCL | 0222);
            if (shm_id >= 0)
            {
                fd = open(PATH, O_RDONLY);
                if (fd >= 0)
                {
                    ptr = malloc(PAGE_SIZE);
                    if (ptr != NULL)
                    {
                        //
                        // работаем с полученными ресурсами
                        //
                    }
                    /* а тут катастрофа - 3 открытых ресурса */
                    //ничего не делаем. "Сборка мусора" и установка флага ошибки будет в конце функции
                }
                /* а тут совсем нехорошо, надо освободить и семафор, и shared memory */
                //ничего не делаем. "Сборка мусора" и установка флага ошибки будет в конце функции
            }
            /* а вот тут уже не хорошо, потому как семафор уже создан и необходимо его освободить */
            //ничего не делаем. "Сборка мусора" и установка флага ошибки будет в конце функции


            if (sem_id >= 0)
            {
                semctl(sem_id);
                if (shm_id >= 0)
                {
                    shmctl(shm_id);
                    if (fd >= 0) 
                    { 
                        close(fd);
                        if (ptr == null) { /* все 3 ресурса созданы, а ptr -- нулл => ошибка */ error = errno; }
                    }
                    else { /* семафор и shared memory созданы, а дескриптор нет => ошибка */ error = errno; }
                }
                else { /* семафор создан, а shared memory нет => ошибка */ error = errno; }
            }

            return error;
        }


2) Вариант того же кода, но без лишних коментариев:
Код

        int do_code()
        {
            int errno = -1269; // Код ошибки

            int error = 0; /* ошибки нет */
            int key = ftok(KEY_PATH, 0);
            if (key < 0)
                return errno; /* тут все нормально */

            int sem_id = semget(key, SEMAPHORES_COUNT, IPC_CREAT | IPC_EXCL | 0666);
            if (sem_id < 0)
                return errno; /* тут тоже все хорошо */


            // Начало моего кода
            int fd;
            object ptr;

            int shm_id = shmget(key, PAGE_SIZE, IPC_CREAT | IPC_EXCL | 0222);
            if (shm_id >= 0)
            {
                fd = open();
                if (fd >= 0)
                {
                    ptr = malloc();
                    if (ptr != null)
                    {
                        // работаем с полученными ресурсами
                    }
                }
            }

            // "Сборка мусора и отлов ошибок"
            if (sem_id >= 0)
            {
                semctl(sem_id);
                if (shm_id >= 0)
                {
                    shmctl(shm_id);
                    if (fd >= 0) 
                    { 
                        close(fd);
                        if (ptr == null) { /* все 3 ресурса созданы, а ptr -- нулл => ошибка */ error = errno; }
                    }
                    else { /* семафор и shared memory созданы, а дескриптор нет => ошибка */ error = errno; }
                }
                else { /* семафор создан, а shared memory нет => ошибка */ error = errno; }
            }

            return error;
        }


Жду ваших комментариев  smile 

P.S. Код отформатирован так, как я люблю, поэтому он кажется громоздким. Но если его отформатировать в стиле MAKCim'а, то он будет не намного больше, чем с goto.
P.P.S. "Отлов ошибок" можно было оставить и в первом блоке, но, ИМХО, ему логичнее быть именно во втором.
P.P.P.S. Проверил несколько раз, но все равно могут быть несостыковки, так что сильно ногами не пинать smile

Добавлено через 13 минут и 43 секунды
А если еще совместить первые два блока, то еще лучше получится:
Код

        int do_code()
        {
            int errno = -1269; // Код ошибки

            int error = 0; /* ошибки нет */
            int key = ftok(KEY_PATH, 0);
            if (key < 0)
                return errno; /* тут все нормально */
            int sem_id = semget(key, SEMAPHORES_COUNT, IPC_CREAT | IPC_EXCL | 0666);
            if (sem_id < 0)
                return errno; /* тут тоже все хорошо */

            // Начало моего кода
            int fd;
            object ptr;

            int shm_id = shmget(key, PAGE_SIZE, IPC_CREAT | IPC_EXCL | 0222);
            if (shm_id >= 0){
                fd = open();
                if (fd >= 0){
                    ptr = malloc();
                    if (ptr != NULL){
                        // работаем с полученными ресурсами
                    }
                    else { /* все 3 ресурса созданы, а ptr -- нулл => ошибка */ error = errno; }
                    close(fd); // уничтожаем дескриптор, так как он уже не нужен
                }
                else { /* семафор и shared memory созданы, а дескриптор нет => ошибка */ error = errno; }
                shmctl(shm_id); // уничтожаем shared memory, за ненадобностью
            }
            else { /* семафор создан, а shared memory нет => ошибка */ error = errno; }
            semctl(sem_id); // уничтожаем семафор, за ненадобностью

            return error;
        }

PM MAIL WWW ICQ   Вверх
powerfox
Дата 12.4.2007, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 2
Всего: 97



ivashkanet, твой код ничем особенным не отличается от кода Максима, так как ты, по сути дела, просто перенёс тела функций по обработке ошибок в основную, что не есть хорошо:
1. Такой стиль подвержен ошибкам + тяжело их отслеживать (делать локализацию ошибки).
2. Если ошибка возникла в самом начале, то зачем продолжать выполнение функции? Это лишнее время (пользователя и машинное).
3. Читается хуже. Читающий программу увидит, конечно, что ты в случае ошибки что-то творишь с переменной error (и прочее), но чем рысскать по коду, лучше сразу перейти к функциям-обработчикам.

Код Максима - классический пример того, как подобные вещи пишутся на Си.


--------------------
user posted image
PM WWW   Вверх
ivashkanet
Дата 12.4.2007, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
ничем особенным не отличается от кода Максима

Даже больше: ничем, кроме отсутствия goto
Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
1. Такой стиль подвержен ошибкам + тяжело их отслеживать (делать локализацию ошибки).

Кто к чему привык ;-) Мне понятнее мой вариант. Тем более с нормальными коментариями.
Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
2. Если ошибка возникла в самом начале, то зачем продолжать выполнение функции? Это лишнее время (пользователя и машинное).

Посмотри внимательно, ИМХО, у меня нет ни одной лишней инструкции после возникновения ошибки. Только то, что нужно для удаления ресурсов.
Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
3. Читается хуже. Читающий программу увидит, конечно, что ты в случае ошибки что-то творишь с переменной error (и прочее), но чем рысскать по коду, лучше сразу перейти к функциям-обработчикам.

То же что и по первому пункту.
Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
Код Максима - классический пример того, как подобные вещи пишутся на Си. 

Разные задачи требуют разные подходы к ее решению. В данном случае, когда требуется скорость работы, код Максима, возможно, и лучше.

Добавлено через 1 минуту и 6 секунд
Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
ты, по сути дела, просто перенёс тела функций по обработке ошибок в основную

Вот это я не понял :(
PM MAIL WWW ICQ   Вверх
powerfox
Дата 12.4.2007, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I wanna fork()
****


Профиль
Группа: Комодератор
Сообщений: 3990
Регистрация: 1.10.2005
Где: Санкт-Петербург

Репутация: 2
Всего: 97



Цитата(ivashkanet @  12.4.2007,  17:29 Найти цитируемый пост)
осмотри внимательно, ИМХО, у меня нет ни одной лишней инструкции после возникновения ошибки. Только то, что нужно для удаления ресурсов.


Извини, просто невчитался.
Цитата(ivashkanet @  12.4.2007,  17:29 Найти цитируемый пост)
Цитата(powerfox @  12.4.2007,  14:13 Найти цитируемый пост)
ты, по сути дела, просто перенёс тела функций по обработке ошибок в основную

Вот это я не понял :( 


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


--------------------
user posted image
PM WWW   Вверх
MAKCim
Дата 12.4.2007, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



ivashkanet
не все так гладко  smile 
по функционалу, конечно, все верно, но
1. Код менее читабелен (имхо)
2. Количество вложенных if-ов растет пропорционально количеству выделенных ресурсов
3. Необходимость повторения "лесенки" из if-ов 2 раза
4. Эффективность кода страдает (вложенные if-ы при всей оптимизации ничего хорошего кроме частой перезагрузки конвеера не дают)
Цитата(ivashkanet @  12.4.2007,  16:29 Найти цитируемый пост)
Разные задачи требуют разные подходы к ее решению. В данном случае, когда требуется скорость работы, код Максима, возможно, и лучше.

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


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
ivashkanet
Дата 12.4.2007, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(powerfox @  12.4.2007,  16:10 Найти цитируемый пост)
Максим для каждой ошибки вызывал свой разработчик. Ты возвращаешь код ошибки, то есть функция, которая получила его, должна сама что-то предпринять. 

goto: xy --- это вызов своего обработчика? Не согласен.

Мой код делает ТО ЖЕ САМОЕ, что и код Максима.

P.S. ИМХО, если взять ну очень умный компилятор, то он должен преобразовать мой и Максима код в одни и те же инструкции. Причем, эти инструкции будут ближе к коду Максима (это только потому, что компиляторы вовсю используют goto направо и налево smile ).

Добавлено через 10 минут и 57 секунд
MAKCim,  smile 

Цитата(MAKCim @  12.4.2007,  16:15 Найти цитируемый пост)
3. Необходимость повторения "лесенки" из if-ов 2 раза

Вторую "лесенку" можно заменить на отдельные if-ы, правда код будет менее эффективен.
Цитата(MAKCim @  12.4.2007,  16:15 Найти цитируемый пост)
2. Количество вложенных if-ов растет пропорционально количеству выделенных ресурсов

Наличию связанных выделенных ресурсов.
Цитата(MAKCim @  12.4.2007,  16:15 Найти цитируемый пост)
я не знаю, ты конечно можешь утверждать, что тебе он понятнее и т. п, но, честно говоря, если бы такой код, как у тебя, попался мне в реальном проекте, я бы его скорее всего (если бы была такая возможность) переписал 

А никто не говорит, что я такой код написал бы у себя в проекте, боже упаси  smile
Просто я предоставил код без goto максимально приближенный к твоему.
PM MAIL WWW ICQ   Вверх
MAKCim
Дата 12.4.2007, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(ivashkanet @  12.4.2007,  17:20 Найти цитируемый пост)
это только потому, что компиляторы вовсю используют goto направо и налево smile 

goto = jmp, вызов функции = call, jmp - более эффективен
Цитата(ivashkanet @  12.4.2007,  17:20 Найти цитируемый пост)
Наличию связанных выделенных ресурсов.

без разницы, связаны они или нет, главное их освободить
кроме того, в моем примере только создание ключа (ftok()) связано с возможностью дальнейшего выполнения


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1054 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.