Вопросы по С/С++ (СИ)
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
все понятно, если внимательно изучить возможности компилятора и стандарт языка.
как правило, под любое число выделяется int, и одновременно, практически каждый компилятор имеет опциональную возможность выделять под enum минимально возможный элемент, т.е. байт (если, конечно, перечисление содержит не более 256 элементов или не содержит элементов с явно заданными большими значениями).
для чего это нужно? снова понятно. язык Си слабо контролирует типы, стандарт С99 немного ужесточает контроль типов, но более-менее нормальный контроль есть только в С++. это означает, что когда в качестве параметра функции вы задаете тип-перечисление, компилятор может на этапе компиляции сообщить (обычно warning, но в С++ может быть и error), когда вы в функцию передаете число, не попадающее в перечисление - это немного помогает избежать грубых ошибок.
например, в WinAVR попробуйте скомпилировать оператор switch с аргументом перечисляемого типа - если вариантов case будет меньше, чем определено в перечислении, компилятор вам тут же сообщит, что не все варианты switch обработаны. для обычных типов чисел так он ругается только на отсутствие default.
но даже при полном отсутствии контроля типов в обычном Си человеческий фактор нельзя сбрасывать со счетов: абстрактный char практически ничего не скажет человеку-программисту, в то время как interrupt_mode уже содержит конкретный смысл, а взгляд на спрятанный за этим словом тип-перечисление сразу показывает допустимый диапазон значений.
P.S. я не в курсе, есть ли в каком-либо диалекте Си или С++ возможность определять "края" перечислений, как в Pascal... но это реально полезная фича!
как правило, под любое число выделяется int, и одновременно, практически каждый компилятор имеет опциональную возможность выделять под enum минимально возможный элемент, т.е. байт (если, конечно, перечисление содержит не более 256 элементов или не содержит элементов с явно заданными большими значениями).
для чего это нужно? снова понятно. язык Си слабо контролирует типы, стандарт С99 немного ужесточает контроль типов, но более-менее нормальный контроль есть только в С++. это означает, что когда в качестве параметра функции вы задаете тип-перечисление, компилятор может на этапе компиляции сообщить (обычно warning, но в С++ может быть и error), когда вы в функцию передаете число, не попадающее в перечисление - это немного помогает избежать грубых ошибок.
например, в WinAVR попробуйте скомпилировать оператор switch с аргументом перечисляемого типа - если вариантов case будет меньше, чем определено в перечислении, компилятор вам тут же сообщит, что не все варианты switch обработаны. для обычных типов чисел так он ругается только на отсутствие default.
но даже при полном отсутствии контроля типов в обычном Си человеческий фактор нельзя сбрасывать со счетов: абстрактный char практически ничего не скажет человеку-программисту, в то время как interrupt_mode уже содержит конкретный смысл, а взгляд на спрятанный за этим словом тип-перечисление сразу показывает допустимый диапазон значений.
P.S. я не в курсе, есть ли в каком-либо диалекте Си или С++ возможность определять "края" перечислений, как в Pascal... но это реально полезная фича!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Спасибо за разъяснения, потихоньку начинает проясняться.
Re: Вопросы по С/С++ (СИ)
ковыряю код принимающий и отправляющий данные по UART(AVR) и выводящий что отправлено/принято на дисплей, задачя убрать все из кода, что отвечает за отправку обратно в компьютер, начинаю с самого явного убираю из цикла ифы с кнопками и перестает работать вывод на лцд, вступительная заставка работает, стоит вернуть хоть один иф с кнопкой, начинает работать дисплей.
доб 22:14: странно, удаляя все "кнопки" из цикла, if(byte_receive) перестает работать, добавив задержку в 10мс. все работает, почему.
еще вопрос. как иначе записать if(byte_receive) если он один в цикле получается if ненужен?
Спойлер
Код: Выделить всё
//*** Пример работы с USART интерфейсом микроконтроллеров AVR ***
#include <avr/io.h>
#include <avr/interrupt.h>
#define BAUDRATE 9600 // Скорость обмена данными
#define F_CPU 8000000UL // Рабочая частота контроллера
unsigned char NUM = 0;
unsigned char count = 0;
unsigned char byte_receive = 0;
unsigned char i = 1;
// Функция задержки в мкс
void _delay_us(unsigned char time_us)
{ register unsigned char i;
for(i = 0; i < time_us; i++)
{
asm volatile(" PUSH R0 ");
asm volatile(" POP R0 ");
}
}
// Функция задержки в мс
void _delay_ms(unsigned int time_ms)
{ register unsigned int i;
for(i = 0; i < time_ms; i++)
{
_delay_us(250);
_delay_us(250);
_delay_us(250);
_delay_us(250);
}
}
#define RS PD2
#define EN PD3
// Функция передачи команды
void lcd_com(unsigned char p)
{
PORTD &= ~(1 << RS); // RS = 0 (запись команд)
PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
}
// Функция передачи данных
void lcd_data(unsigned char p)
{
PORTD |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p & 0xF0); // старший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
PORTD |= (1 << EN); // EN = 1 (начало записи команды в LCD)
PORTD &= 0x0F; PORTD |= (p << 4); // младший нибл
_delay_us(100);
PORTD &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
_delay_us(100);
}
// Функция инициализации LCD
void lcd_init(void)
{
_delay_ms(50); // Ожидание готовности ЖК-модуля
// Конфигурирование четырехразрядного режима
PORTD |= (1 << PD5);
PORTD &= ~(1 << PD4);
// Активизация четырехразрядного режима
PORTD |= (1 << EN);
PORTD &= ~(1 << EN);
_delay_ms(5);
lcd_com(0x28); // шина 4 бит, LCD - 2 строки
lcd_com(0x08); // полное выключение дисплея
lcd_com(0x01); // очистка дисплея
_delay_us(100);
lcd_com(0x06); // сдвиг курсора вправо
lcd_com(0x0C); // включение дисплея, курсор не видим
}
// Функция вывода строки на LCD
void lcd_string(unsigned char command, char *string)
{
lcd_com(0x0C);
lcd_com(command);
while(*string != '\0')
{
lcd_data(*string);
string++;
}
}
// Функция передачи данных по USART
void uart_send(char data)
{
while(!( UCSRA & (1 << UDRE))); // Ожидаем когда очистится буфер передачи
UDR = data; // Помещаем данные в буфер, начинаем передачу
}
// Функция передачи строки по USART
void str_uart_send(char *string)
{
while(*string != '\0')
{
uart_send(*string);
string++;
}
}
// Функция приема данных по USART
int uart_receive(void)
{
while(!(UCSRA & (1 << RXC))); // Ожидаем, когда данные будут получены
return UDR; // Читаем данные из буфера и возвращаем их при выходе из подпрограммы
}
// Функция инициализации USART
void uart_init(void)
{
// Параметры соединения: 8 бит данные, 1 стоповый бит, нет контроля четности
// USART Приемник: Включен
// USART Передатчик: Включен
// USART Режим: Асинхронный
// USART Скорость обмена: 9600
UBRRL = (F_CPU/BAUDRATE/16-1); // Вычисляем скорость обмена данными
UBRRH = (F_CPU/BAUDRATE/16-1) >> 8;
UCSRB |= (1 << RXCIE)| // Разрешаем прерывание по завершению приема данных
(1 << RXEN)|(1 << TXEN); // Включаем приемник и передатчик
UCSRC |= (1 << URSEL)| // Для доступа к регистру UCSRC выставляем бит URSEL
(1 << UCSZ1)|(1 << UCSZ0); // Размер посылки в кадре 8 бит
}
// Прерывание по окончанию приема данных по USART
ISR(USART_RXC_vect)
{
NUM = UDR; // Принимаем символ по USART
byte_receive = 1;
uart_send(NUM); // Посылаем символ по USART
if(NUM == 'a') // Если принят символ "a", включаем светодиод
PORTB |= (1 << PB0);
if(NUM == 'b') // Если принят символ "b", выключаем светодиод
PORTB &= ~(1 << PB0);
}
// Главная функция
int main(void)
{
DDRB |= (1 << PB0); // Светодиод
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xFF;
DDRD = 0b11111110;
PORTD = 0x00;
lcd_init(); // Инициализация LCD
uart_init(); // Инициализация USART
sei(); // Глобально разрешаем прерывания
str_uart_send("Initialization system\r\n"); // Передаем строку по USART
lcd_string(0x80, " AVR USART TEST "); // Выводим строку на LCD
_delay_ms(2500);
lcd_com(0x01); // Очищаем LCD
while(1)
{
if((PINC & (1 << PC0)) == 0) // Если нажата кнопка 1
{
while((PINC & (1 << PC0)) == 0){} // Ждем отпускания кнопки 1
str_uart_send("Button 1 TEST\r\n"); // Передаем строку по USART
lcd_string(0x80, "Button 1 TEST"); // Выводим строку на LCD
_delay_ms(1000);
lcd_com(0x01); // Очищаем LCD
}
if((PINC & (1 << PC1)) == 0) // Если нажата кнопка 2
{
while((PINC & (1 << PC1)) == 0){} // Ждем отпускания кнопки 2
str_uart_send("Button 2 TEST\r\n"); // Передаем строку по USART
lcd_string(0x80, "Button 2 TEST"); // Выводим строку на LCD
_delay_ms(1000);
lcd_com(0x01); // Очищаем LCD
}
if((PINC & (1 << PC2)) == 0) // Если нажата кнопка 3
{
while((PINC & (1 << PC2)) == 0){} // Ждем отпускания кнопки 3
str_uart_send("Button 3 TEST\r\n"); // Передаем строку по USART
lcd_string(0x80, "Button 3 TEST"); // Выводим строку на LCD
_delay_ms(1000);
lcd_com(0x01); // Очищаем LCD
}
if(byte_receive)
{
byte_receive = 0;
count++;
lcd_data(NUM); // Выводим символ на LCD
if(count > 16) // Если строка заполнена
{
count = 0;
lcd_com(0x01); // Очищаем LCD
}
}
}
}еще вопрос. как иначе записать if(byte_receive) если он один в цикле получается if ненужен?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
а у меня встречный вопрос: почему с задержками изобрели велосипед, если существует отличный модуль для формирования задержек util/delay.h?
на счет кнопок - у вас, как я понял, дребезг не отлавливается?
на счет кнопок - у вас, как я понял, дребезг не отлавливается?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Не знаю как правильно сформулировать запрос для гугла, поэтому попробую спросить здесь.
Есть такая штука как автозавершение кода. Допустим мы пишем имя структуры
MyStruct.
И здесь в редакторе вываливается доступный список её элементов, из них можно выбрать нужный.
Есть к примеру машина состояний, принимающая одно из N возможных константных значений(UP, DOWN, START, STOP и т.д.). Тогда мы пишем
state_machine = STATE_START;
Было бы удобнее собрать эти константные значения в какой-то объект SM_VAL и написать так:
state_machine = SM_VAL.[вываливается список, из которого выбираем]
Использую Си(не ++), есть ли такое?
Есть такая штука как автозавершение кода. Допустим мы пишем имя структуры
MyStruct.
И здесь в редакторе вываливается доступный список её элементов, из них можно выбрать нужный.
Есть к примеру машина состояний, принимающая одно из N возможных константных значений(UP, DOWN, START, STOP и т.д.). Тогда мы пишем
state_machine = STATE_START;
Было бы удобнее собрать эти константные значения в какой-то объект SM_VAL и написать так:
state_machine = SM_VAL.[вываливается список, из которого выбираем]
Использую Си(не ++), есть ли такое?
- Реклама
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Перечисления (enum).uk8amk писал(а): Было бы удобнее собрать эти константные значения в какой-то объект
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Только у меня не работает автозавершение перечислений?
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Эти выпадающие списки уже от используемого IDE.
Я, например, QtCreator использую - там такое есть.
Я, например, QtCreator использую - там такое есть.
Re: Вопросы по С/С++ (СИ)
Что за редактор используете?uk8amk писал(а):Только у меня не работает автозавершение перечислений?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Keil mdk 4.73, иногда Codevision.
Похоже ограничение самих IDE. В принципе можно прикрутить и внешний редактор, но пока и так сойдёт.
Похоже ограничение самих IDE. В принципе можно прикрутить и внешний редактор, но пока и так сойдёт.
Re: Вопросы по С/С++ (СИ)
В uVision http://www.keil.com/support/man/docs/uv ... decomp.htm попробуйте Ctrl-<пробел> после набора первых символов.uk8amk писал(а):Keil mdk 4.73, иногда Codevision.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
(void)0;
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Это где такое встретилось? А то что-то у меня чувство, что в C/С++ это бессмысленно. Вот (void*)0 - другое дело.
Re: Вопросы по С/С++ (СИ)
Увы, определённо можно лишь сказать , что это строка вырванная [вами] из контекста - потому и непонятная. Если это часть макроса во не-отладочной конфигурации - что встречается повсеместно - то судя по всему упреждает предупреждения компилятора типа "неэффективная операция". Что-то типа nop() но без всякого представления в скомпилированном объекте.FeCat писал(а):Что это такое? Приведение ноля к типу void? Не понимаю. Что это с точки зрения стандарта, что делает компилятор?Код: Выделить всё
(void)0;
На эту тему ещё нагугливается следующее:
Кроме того приведение к void предотвращает от использования макро в операциях присваивания - своего рода эмуляция функции не возвращающей ничего.The (void) cast is not merely a choice by a particular implementation; it's required by the C standard. Quoting the 2011 ISO C standard (similar wording appears in the 1990 and 1999 editions):If NDEBUG is defined as a macro name at the point in the source file where <assert.h> is included, the assert macro is defined simply as
#define assert(ignore) ((void)0)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Вопросы по С/С++ (СИ)
Доброго времени суток. Поскажите ответы на пару-тройку глупых вопросов. Железка ATMega16, пишется под AVR-GCC. Программа работает, но хочется понять как именно.
Есть пара функций:
И что-то я тут в двух соснах запутался. По первой все понятно: она выводит число на PORTB, формирует импульс разрешения чтения этих данных контроллером LCD-дисплея и формирует задержку, чтоб тот успел все переварить перед следющими командами. А вот со второй не совсем понятно.
Функция получает некоторую строку в таком виде: 'test'. При это запись *str означает, что в константу str запишется адрес первого элемента строки. Цикл while работает до тех пор, пока записанное по адресу str значение не равно нулю. И тут первый вопрос: оно же константа, цикл должен должен быть бесконечным, как может меняться значение *str? Дальше больше. Фукция записи получает значение находящееся по адресу str (т.е. первый элемент строки). После этого происходит инкремент. По логике, это должен быть инкремент адреса. Т.е. сперва над str происходит операция ++, потом *. Тут тоже вопрос: функция в какой момент времени получает свой аргумент? В нее улетит первый и второй элемент строки? Но, допустим, функция свое отработала, возвращаемся к циклу while. Куда сохраниться значение инкремента, которое должно проверятся в условии цикла, *str ведь константа?
Ужас какой-то с этими указателями, ничего не понятно.
Есть пара функций:
Код: Выделить всё
//Функция записи байта в контроллер
static void lcd_write(unsigned char data)
{
LCD_DATA = data; //выдача данных на PORTB
lcd_pulse_e(); //разрешение записи данных в контроллер
lcd_wait(); //ожиданием обработки данных котроллером
}
//Функция вывода строки
void lcd_puts(const char *str)
{
while(*str) //пока не кончится строка, для каждого элемента
{ //вызывается функция записи символа
lcd_write(*str++); //вывод символа на шину данных;
}
}Функция получает некоторую строку в таком виде: 'test'. При это запись *str означает, что в константу str запишется адрес первого элемента строки. Цикл while работает до тех пор, пока записанное по адресу str значение не равно нулю. И тут первый вопрос: оно же константа, цикл должен должен быть бесконечным, как может меняться значение *str? Дальше больше. Фукция записи получает значение находящееся по адресу str (т.е. первый элемент строки). После этого происходит инкремент. По логике, это должен быть инкремент адреса. Т.е. сперва над str происходит операция ++, потом *. Тут тоже вопрос: функция в какой момент времени получает свой аргумент? В нее улетит первый и второй элемент строки? Но, допустим, функция свое отработала, возвращаемся к циклу while. Куда сохраниться значение инкремента, которое должно проверятся в условии цикла, *str ведь константа?
Ужас какой-то с этими указателями, ничего не понятно.
We do what we must because we can (c) GLaDOS
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
str - не константа ! Это указатель на символ-константу.
"++" после переменной означает, что сначала с ней произойдут некие действия, а потом уже будет инкремент. В данном случае, сначала в функцию передастся символ по указателю, затем произойдёт инкремент указателя (для следующего символа). И так, пока указатель не будет указывать на нулевой символ.
Указатель-константа на символ:Указатель на символ-константу:Чувствуете разницу ? 
В первом случае указатель вы изменить не сможете, а символ по этому указателю сможете.
Во втором случает указатель сможете модифицировать, но символ по нему уже нет.
"++" после переменной означает, что сначала с ней произойдут некие действия, а потом уже будет инкремент. В данном случае, сначала в функцию передастся символ по указателю, затем произойдёт инкремент указателя (для следующего символа). И так, пока указатель не будет указывать на нулевой символ.
Указатель-константа на символ:
Код: Выделить всё
char* const ch;Код: Выделить всё
const char* ch;В первом случае указатель вы изменить не сможете, а символ по этому указателю сможете.
Во втором случает указатель сможете модифицировать, но символ по нему уже нет.
Re: Вопросы по С/С++ (СИ)
*str - это означает лишь разыменование указателя - а будет туда что-то писаться или наоборот, это значение куда-то присвоится - зависит от того куда вы в выражении это поставите - "слева" - будет попытка присваивания нового значения по указываемому адресу, "справа" - чтение значения по адресу. В данном примере очень важно уяснить следуюший момент (по крайней мере для стандартного соглашения о вызвах функций в С), что переменная str - это автоматическая переменная - копия той переменной которую вы передали в функцию - она живёт на стеке функции и уничтожается при выходе из функции. В вашем примере вы непосредственно инкрементируете указатель на начало строки меняя содержимое переменной str - т.е. экономите одну временую переменную-указатель на стеке функции. Это допустимо хотя и не приветствуется - поскольку str после исполнения цикла while указывает на конец строки - и когда парень, который будет после вас сопровождать и дорабатывать этот код, попытается ещё раз использовать str будучи наивно-уверенным что в str всё ещё есть исходная строчка - получит дополнительный опыт минус время жизни проведённое в отладчике.baron_P писал(а):При это запись *str означает, что в константу str запишется адрес первого элемента строки.Код: Выделить всё
//Функция вывода строки void lcd_puts(const char *str) { while(*str) //пока не кончится строка, для каждого элемента { //вызывается функция записи символа lcd_write(*str++); //вывод символа на шину данных; } }
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Немного не соглашусь и уточню.
Парень, который будет после сопровождать и дорабатывать код, получит проблемы, только если будет пытаться использовать str там же, внутри функции lcd_puts(), что вряд ли. А вот снаружи ничего страшного не произойдёт, потому что str - это копия указателя, как Вы сами и сказали. И внешний указатель никуда не денется, и тот же lcd_puts() можно будет вызывать с одним и тем же аргументом много раз подряд.
Парень, который будет после сопровождать и дорабатывать код, получит проблемы, только если будет пытаться использовать str там же, внутри функции lcd_puts(), что вряд ли. А вот снаружи ничего страшного не произойдёт, потому что str - это копия указателя, как Вы сами и сказали. И внешний указатель никуда не денется, и тот же lcd_puts() можно будет вызывать с одним и тем же аргументом много раз подряд.
Re: Вопросы по С/С++ (СИ)
Да, спасибо, уточнение принято. Нахожу его полезным в случае если всё предыдущее изложение о физическом смысле параметра функции как локальной копии всё-же не было осознано адресатом.WiseLord писал(а):Немного не соглашусь и уточню.
Парень, который будет после сопровождать и дорабатывать код, получит проблемы, только если будет пытаться использовать str там же, внутри функции lcd_puts(), что вряд ли.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Парень, который полезет править код этой функции, не разобравшись или по неопытности наживший от этого проблемы, будет сам виноват в этом.


