Вопросы по С/С++ (СИ)
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Вопросы по С/С++ (СИ)
Спасибо.
Т.е. lcd_write(*str++) означает, что *str (символ-константа) отправится на обрабоку в функцию, а str (переменная-адрес) инкрементируется и идет дальше на проверку условия перед след. итераций цикла while. Тогда еще глупые вопросы: почему в функцию отправляется не конечный результат выражения *str++, а промежуточный (ведь все выражение стоит в качестве аргумента)?
const char *str - переменная-указатель на символ-константу
const *char str - указатель-константа на символ переменную
Логику в этих выражениях не уловил, постараюсь просто запомнить.
О состоянии str сложно написано, не понял в чем возможны проблемы с этим выражением. Я передаю *str в качестве аргумента функции lcd_write. Что она там с ним делает не важно - после выхода из функции эта переменная перестает существовать, ведь локальная. Внутри функции lcd_puts указатель str в явном виде инкрементирует и почему кто-то (кроме меня, еще не вкурившего возню с указателями) должен подумать, что там останется старое значение, непонятно. А вне функции lcd_puts переменная опять же бессмыслена, т.к. локальная.
Но еще один вопрос вызывает использование класса static. Он тут применен для фукнции которая ничего не возвращает (void же), зачем это сделано?
Т.е. lcd_write(*str++) означает, что *str (символ-константа) отправится на обрабоку в функцию, а str (переменная-адрес) инкрементируется и идет дальше на проверку условия перед след. итераций цикла while. Тогда еще глупые вопросы: почему в функцию отправляется не конечный результат выражения *str++, а промежуточный (ведь все выражение стоит в качестве аргумента)?
const char *str - переменная-указатель на символ-константу
const *char str - указатель-константа на символ переменную
Логику в этих выражениях не уловил, постараюсь просто запомнить.
О состоянии str сложно написано, не понял в чем возможны проблемы с этим выражением. Я передаю *str в качестве аргумента функции lcd_write. Что она там с ним делает не важно - после выхода из функции эта переменная перестает существовать, ведь локальная. Внутри функции lcd_puts указатель str в явном виде инкрементирует и почему кто-то (кроме меня, еще не вкурившего возню с указателями) должен подумать, что там останется старое значение, непонятно. А вне функции lcd_puts переменная опять же бессмыслена, т.к. локальная.
Но еще один вопрос вызывает использование класса static. Он тут применен для фукнции которая ничего не возвращает (void же), зачем это сделано?
We do what we must because we can (c) GLaDOS
- Реклама
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Есть понятие преинкремента и постинкремента. Например:baron_P писал(а):еще глупые вопросы: почему в функцию отправляется не конечный результат выражения *str++, а промежуточный (ведь все выражение стоит в качестве аргумента)?
Код: Выделить всё
char ch = 'a';
lcd_write(ch++);
lcd_write(ch);Код: Выделить всё
char ch = 'a';
lcd_write(++ch);
lcd_write(ch);При постинкременте для вычисления всего выражения используется старое значение переменной, и только потом переменная инкрементируется.
При преинкременте - сначала вычисляется значение переменной, а уж потом оно используется для других вычислений.
Так и здесь - при lcd_write(*str++) в функцию отправится число, находящееся по старому адресу, и лишь потом адрес изменяется.
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
baron_P
В функцию и отправляется только вычисленный результат выражения, а не набор каких-то непонятных операторов. Это происходит на этапе компиляции проекта.
К static функциям обращаться можно внутри одного файла-модуля C. Внешне они недоступны.
В функцию и отправляется только вычисленный результат выражения, а не набор каких-то непонятных операторов. Это происходит на этапе компиляции проекта.
К static функциям обращаться можно внутри одного файла-модуля C. Внешне они недоступны.
Re: Вопросы по С/С++ (СИ)
Результат выражения и есть символ по исходному указателю. Инкремент-же указателя - можете считать "побочным" эффектом.baron_P писал(а):Тогда еще глупые вопросы: почему в функцию отправляется не конечный результат выражения *str++, а промежуточный (ведь все выражение стоит в качестве аргумента)?
Окровенно говоря тип "*char" встречаю впервые - хотелось бы развёрнутый пример применения. Подозреваю имелось ввиду char* const str - т.е. указатель-константа - который нельзя изменить в отличие от переменной-указателя на константу менять который можно.baron_P писал(а):const *char str - указатель-константа на символ переменную
Попробую пояснить кодом:
Код: Выделить всё
const char* str1 = "const char* str1\n"; // указатель-переменная
const char* str2 = "const char* str2\n"; // указатель-переменная
char* const cstr = "const char* cstr\n"; // указатель-константа
int _tmain(int argc, _TCHAR* argv[])
{
printf(str1);
printf(str2);
printf(cstr);
str2 = str1; // можно присваивать
printf(str2);
str1 = cstr; // можно присваивать
printf(str1);
cstr = "just a char*"; // error C3892: 'cstr' : you cannot assign to a variable that is const
printf(cstr);
return 0;
}
Вы инструктаж по технике безопасности регулярно проходите? Тем не менее никого не удивляет что ноги-руки-пальцы регулярно отрезаются, отвёртки-молотки пробивают-калечат подушечки пальцев а киловольты исправно жгут тела нарушителей ТБ. Вот и считайте это своего рода инструктажем. Долгоживущий код имеет тенденцию к разбуханию и функция в процессе разработки и поддержки может принимать такие причудливые формы что то, что было очевидно исходному писателю просто теряется в глубине спагетти-кода. Разобрать даже собственный код по прошествии времени требует усилий - потому как оно всегда и бывает - лепим по быстрому, пробный прогон - косяк, отладчик - мать-мать-мать - минус десять минут жизни коорые можно было сохранить соблюдая правила. Посему если оптимизация не довлеет - писать нужно ясно и понятно и не только для себя самого.baron_P писал(а):Внутри функции lcd_puts указатель str в явном виде инкрементирует и почему кто-то (кроме меня, еще не вкурившего возню с указателями) должен подумать, что там останется старое значение, непонятно.
Класс static для глобальных объектов - это гарантия того, что нигде кроме как в этом модуле этот объект не используется - в общем такая-же "техника безопасности".baron_P писал(а):Но еще один вопрос вызывает использование класса static. Он тут применен для фукнции которая ничего не возвращает (void же), зачем это сделано?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Вопросы по С/С++ (СИ)
Спасибо.
Не сразу дошло, что *str++ и *(str+1) не одно и то же.
По static-функциям вроде понятно.
А с костантами-указателями путаница.
const char *str;
const char* str;
Это одно и тоже или нет? К чему тут применяется разыменование указателя?
Я правильно понял, что здесь str1 - это адрес первого элемента строки и *srt1 == 'c'?
Т.е. *str1 это константа, а str1 - переменная, за счет изменения которой я и могу считать несколько констант, составляющих строку?
А здесь костанты две - cstr и *cstr. Т.е. я не могу ни изменить записанный в cstr адрес, ни поменять записанный в *cstr символ. Так?
Не сразу дошло, что *str++ и *(str+1) не одно и то же.
По static-функциям вроде понятно.
А с костантами-указателями путаница.
const char *str;
const char* str;
Это одно и тоже или нет? К чему тут применяется разыменование указателя?
Код: Выделить всё
const char* str1 = "const char* str1\n";Т.е. *str1 это константа, а str1 - переменная, за счет изменения которой я и могу считать несколько констант, составляющих строку?
Код: Выделить всё
char* const cstr = "const char* cstr\n";We do what we must because we can (c) GLaDOS
- Реклама
- GARMIN
- Держит паяльник хвостом
- Сообщения: 954
- Зарегистрирован: Вс дек 02, 2012 16:58:33
- Откуда: от туда
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Это одно и то же. Первая запись более правильная, так как указывает, что str является указателем.baron_P писал(а): const char *str;
const char* str;
Это одно и тоже или нет? К чему тут применяется разыменование указателя?
Как пример, показывающий разницу в использовании:
const char* str1, str2;
const char *str1, str2;
в первом примере не видно, что str2 не указатель, а символ.
здесь есть строка без имени "const char* cstr\n", расположенная где-то в памяти, и константный указатель на неё cstr. Строка может располагаться в ОЗУ, тогда её можно изменить. Явно это не указывается, зависит от контекста.baron_P писал(а):Я правильно понял, что здесь str1 - это адрес первого элемента строки и *srt1 == 'c'?Код: Выделить всё
const char* str1 = "const char* str1\n";
Т.е. *str1 это константа, а str1 - переменная, за счет изменения которой я и могу считать несколько констант, составляющих строку?
А здесь костанты две - cstr и *cstr. Т.е. я не могу ни изменить записанный в cstr адрес, ни поменять записанный в *cstr символ. Так?Код: Выделить всё
char* const cstr = "const char* cstr\n";
Re: Вопросы по С/С++ (СИ)
Это лишь разные стили объявления одного и того-же типа переменной - указателя на неизменяемые данные. И как водится по поводу положения этой звёздочки идут бесконечные битвы остроконечников с тупоконечниками - одни говорят, что звёздочка принадлежит типу и кошернее писать "char*" а другие моментально двигают им под нос вот такой код:baron_P писал(а):А с костантами-указателями путаница.
const char *str;
const char* str;
Это одно и тоже или нет? К чему тут применяется разыменование указателя?
Код: Выделить всё
const char* str2 = "str2", str3 = "str3"; // ошибка!
const char* str2 = "str2", *str3 = "str3"; // ОК - но некрасиво-же!
const char *str2 = "str2", *str3 = "str3"; // И ОК и красиво!
Даbaron_P писал(а):str1 - переменная, за счет изменения которой я и могу считать несколько констант, составляющих строку?
Верно. Мне пожалуй стоило сразу сделать свой пример нагляднее добавлением вот такого такого копирования:baron_P писал(а):А здесь костанты две - cstr и *cstr. Т.е. я не могу ни изменить записанный в cstr адрес, ни поменять записанный в *cstr символ. Так?Код: Выделить всё
char* const cstr = "const char* cstr\n";
Код: Выделить всё
char data[10] = { 0 };
char* const cstr = data;
[...]
for (int i = 0; i < 9; i++)
cstr[i] = str1[i]; // ага.. работает!
cstr = "just a char*"; // error C3892: 'cstr' : you cannot assign to a variable that is const
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Вопросы по С/С++ (СИ)
Спасибо, вроде понял, но ваше дополнение вызвало к жизни еще пару вопросов.
А почему работает? cstr и str1 это ведть не массивы и не строки, а только только одно число (адрес первого сивола соотв. строки). Разве можно к не заданному явно массиву обращаться по индексам?
Я правильно понял, что тут, если б cstr не было константой, в него б записался адрес первого символа строки?
Код: Выделить всё
for (int i = 0; i < 9; i++)
cstr[i] = str1[i]; // ага.. работает!Код: Выделить всё
cstr = "just a char*"We do what we must because we can (c) GLaDOS
Re: Вопросы по С/С++ (СИ)
Указатель хранит лишь адрес им указываемого объекта. cstr и str1 - это соответственно константа и переменная, хранящие адрес на первые байты соответствующих данных. Содержимое по указателю появляется лишь как результат разыменования указателя. Тип указателя (char*, uint16_t*, uint32_t*) определяет размер элемента в виртуальном массиве на начало которого и указывает указатель. Т.е. к нему равноправно можно обращаться как разыменованием так и доступом а-ля массив [индекс]. Индекс массива - суть смещение от начала массива. Это смещение - на размер элемента!baron_P писал(а):Спасибо, вроде понял, но ваше дополнение вызвало к жизни еще пару вопросов.А почему работает? cstr и str1 это ведть не массивы и не строки, а только только одно число (адрес первого сивола соотв. строки). Разве можно к не заданному явно массиву обращаться по индексам?Код: Выделить всё
for (int i = 0; i < 9; i++) cstr[i] = str1[i]; // ага.. работает!
Код: Выделить всё
uint32_t data = 0x11223344;
uint16_t* p = (uint16_t*)&data;
// оба вызовы равнозначны - выведут "верхнее" и "нижнее" слова - нюансы endian-ности опустим для простоты ;-)
pritnf( "%04x %04x\n", p[0], p[1]);
pritnf( "%04x %04x\n", *p, *(p + 1));
Разъяснение смотрите выше. Указатель хранит лишь адрес указуемого объекта.baron_P писал(а):Я правильно понял, что тут, если б cstr не было константой, в него б записался адрес первого символа строки?
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
cstr - это не число, это указатель. Указатель константый, то есть он измениться не может. Поэтому ему нельзя присвоить значение, он может указывать только в одно место, т.е. хранить постоянный адрес. Но данные, на которые он указывает, менять никто не мешает.Siarzhuk писал(а):cstr и str1 это ведть не массивы и не строки, а только только одно число
А по поводу обращения по индексам - запись a абсолютно эквивалентна записи *(a + i); Обращаться можно как угодно.
Например, код
Код: Выделить всё
char a;
char *b;
b = &a;
a = b[7];Другое дело, что на компьютере такая программа хоть и скомпилируется, но, скорее всего, будет завершаться с ошибкой, так как операционная система обычно отслеживает, чтобы программа не копалась в областях памяти, которые выделены не ней, и прибивает её в таких случаях.
- baron_P
- Нашел транзистор. Понюхал.
- Сообщения: 183
- Зарегистрирован: Вт сен 14, 2010 23:07:10
- Откуда: Ростов
Re: Вопросы по С/С++ (СИ)
Спасибо, кажется понял.
До разъяснения думал, что указатель все же хранит некоторое число, которое и есть адрес в памяти той ячейки, на которую он указывает. И с этим числом можно работать как с обычной переменной соотвествующего типа. Но все оказалось таки сложнее.
До разъяснения думал, что указатель все же хранит некоторое число, которое и есть адрес в памяти той ячейки, на которую он указывает. И с этим числом можно работать как с обычной переменной соотвествующего типа. Но все оказалось таки сложнее.
We do what we must because we can (c) GLaDOS
Re: Вопросы по С/С++ (СИ)
Позволю себе дополнить - если переменная 'а' выделена локально на стеке функции - при чтении ничего страшного не произойдёт, при записи - новое значение уйдёт в одну из переменных которая была объявлена за 'b' (если компилятор их не перетасовал) либо просто в неиспользуемую часть стека функции. При выделении в глобальной области - изменится одна из соседних переменных, либо, если 'a' выделена буквально в самом конце сегмента данных и в 7-ми байтах "правее" находится невыделенная область памяти - произойдёт исключение нарушения доступа - обработчик которого и завершит программу. Но всё конечно же зависит от конкретной архитектуры и того куда эту переменную "поселил" компилятор.WiseLord писал(а):вполне допустим. В результате в a будет записано значение, которое раньше было в байте на 7 ячеек правее.Код: Выделить всё
char a; char *b; b = &a; a = b[7];
Другое дело, что на компьютере такая программа хоть и скомпилируется, но, скорее всего, будет завершаться с ошибкой, так как операционная система обычно отслеживает, чтобы программа не копалась в областях памяти, которые выделены не ней, и прибивает её в таких случаях.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Что-то мы плохо разъясняем. 
Именно так - там хранится адрес.baron_P писал(а):До разъяснения думал, что указатель все же хранит некоторое число, которое и есть адрес в памяти той ячейки, на которую он указывает.
Именно так © - лишь компилятор будет ворчать на несоответствия типов. Это число N можно использовать чтобы "отсчитать" N-ое количество байт от начала памяти и прочитать содержимое указуемой переменной:baron_P писал(а): И с этим числом можно работать как с обычной переменной соотвествующего типа.
Код: Выделить всё
int a = 1234567890;
int* pa = &a;
char* p = (char*)0; // указатель на "начало" памяти ;-)
char* pc = &p[(int)pa]; // используем 'pa' - как индекс в памяти, приведение типа - чтобы компилятор не ругался
int* pi = (int*)pc; // мы ведь хотим прочитать оттуда не один байт ( т.е. sizeof(char)) а целых sizeof(int) байт, верно?
printf("%d или %d\n", *pa, *pi); // и что нам покажет smoke test? ;-)Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Так и есть. Указатель - это именно число, которое есть некий адрес, на который он указывает. Но с этим числом-указателем можно работать только в ограниченном диапазоне операций - например, прибавлять-отнимать некое значение (перемещаться по памяти), разыменовывать указатель (*p - получить значение). Можно обращаться как к массиву (и получать значения из соседних с указываемой ячеек). Но нельзя, например, сложить два указателя, или умножить на что-то.baron_P писал(а):До разъяснения думал, что указатель все же хранит некоторое число, которое и есть адрес в памяти той ячейки, на которую он указывает. И с этим числом можно работать как с обычной переменной соотвествующего типа.
В AVR8 любой указатель занимает 2 байта, не важно на что он указывает. Хоть на char, хоть на long long.
В машинах с архитектурой фон Неймана уже другие размеры указателей: в x86 - 32 байта, в x86_64 - 64 байта. Собственно, разрядность системы и определяет размер указателя.
Отсюда, кстати, и принципиальная невозможность тех же 32битных архитектур адресовать больше 4Гб памяти. Потому что 2³² = 4 294 967 296, и указатель в принципе не может хранить большее число. Если очень нужно - приходится извращаться и вводить дополнительные абстракции типа страниц памяти, и тому подобных.
- Chip115
- Сверлит текстолит когтями
- Сообщения: 1132
- Зарегистрирован: Пт фев 16, 2007 14:18:20
- Откуда: Новосибирск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Всем привет! Подскажите, пожалуйста, как реализовать не блокирующею функцию задержки.
В общем, вот псевдокод тела функции, которая, на ряду с остальными, вызывается в общем цикле
Есть затык в виде delay_ms, но в этом месте надо выдержать 1 сек.
Нужна ф-ция, которая не вешает проц. ибо подобных мест в программе будет достаточно и если в каждой будем тупить, то будет плохо.
Можете подсказать решение проблемы?
В гугле пытался найти "не блокирующая функция задержки". Выдает всякую фигню.
Ставить FreeRTOS не охота.
В общем, вот псевдокод тела функции, которая, на ряду с остальными, вызывается в общем цикле
Код: Выделить всё
u8Funk_1 ();
vFunk_2(a);
vFunk_2(b);
delay_ms(1000);
u8Funk_1 ();
vFunk_2(a);
vFunk_2(c);
some_variable1 = 1;
some_variable2= 2;
some_variable3 = 3;
some_variable4 = 4;
Нужна ф-ция, которая не вешает проц. ибо подобных мест в программе будет достаточно и если в каждой будем тупить, то будет плохо.
Можете подсказать решение проблемы?
В гугле пытался найти "не блокирующая функция задержки". Выдает всякую фигню.
Ставить FreeRTOS не охота.
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
© Альберт Эйнштейн
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Не совсем задача корректно поставлена, но попробую пояснить, как я подобное делал для термодатчика DS18B20.
Суть там в том, измерение он производит в течение 750мс. То есть, после команды на измерение надо выждать 750мс, и только тогда можно вызвать функцию, которая запросит результат у датчика.
Решение в лоб - такое:Но возникает та же проблема, что Вы описали - МК висит в цикле ожидания. Не самое лучшее решение.
Идея обойти в этом - запустить функцию измерения температуры раз в 750мс по таймеру, по прерыванию. И тогда можно будет сделать такой набор функций:А в основном цикле температуру узнавать как
Главное - не вызывать updateTemp() чаще, чем надо.
Не знаю, для чего нужна задержка Вам, но принцип может быть похожим.
Суть там в том, измерение он производит в течение 750мс. То есть, после команды на измерение надо выждать 750мс, и только тогда можно вызвать функцию, которая запросит результат у датчика.
Решение в лоб - такое:
Код: Выделить всё
measureTemp();
_delay_ms(750);
temp = getTemp();Идея обойти в этом - запустить функцию измерения температуры раз в 750мс по таймеру, по прерыванию. И тогда можно будет сделать такой набор функций:
Код: Выделить всё
updateTemp() { // вызывать не чаще раза в 750мс по таймеру
_temp = getTemp(); // узнаём у датчика последнее значение температуры
measureTemp(); // запускаем новое измерение
}
int getTemp() {
return _temp;
}Код: Выделить всё
temp = getTemp();Не знаю, для чего нужна задержка Вам, но принцип может быть похожим.
Re: Вопросы по С/С++ (СИ)
Так а че процессору делать если не висеть в цикле? Вот конкретно в вашем примере?
Если у него есть другая работа, то используются таймеры или прерывания. Тогда и вся структура программы другая будет. И RTOS для таких простых МК нафиг не уперлась.
Если у него есть другая работа, то используются таймеры или прерывания. Тогда и вся структура программы другая будет. И RTOS для таких простых МК нафиг не уперлась.
Re: Вопросы по С/С++ (СИ)
Подскажите гуру, как убрать предупреждения компилятора.
В общем, пишу знакогенератор:
Собственно, проблема в предупреждении:
В каком месте мне нужно поставить неопределённый артикль... Кхм, в каком месте тут всплывает int, если аргументы 8-ми разрядные, беззнаковые и операции побитные?
И очень не хотелось бы править инклюд, потому как этот инклюд, планируется использовать с любой шириной данных. В последнем проекте там был, вроде, вообще 32-х разрядный регистр.
В общем, пишу знакогенератор:
Код: Выделить всё
#define seg_a ((uint8_t)(1<<7))
#define seg_b ((uint8_t)(1<<5))
#define seg_c ((uint8_t)(1<<3))
#define seg_d ((uint8_t)(1<<0))
#define seg_e ((uint8_t)(1<<1))
#define seg_f ((uint8_t)(1<<6))
#define seg_g ((uint8_t)(1<<4))
#define seg_h ((uint8_t)(1<<2))
#include "chars7.c"
----теперь фрагмент инклюда:
#define invertmask ~
#define let_1 invertmask(seg_b | seg_c)
#define let_2 invertmask(seg_a|seg_b|seg_d|seg_e|seg_g)
---- итд.
const uint8_t charset[16] = {let_0, let_1, let_2, let_3, \
let_4, let_5, let_6, let_7, \
let_8, let_9, let_A, let_b, \
let_c, let_d, let_E, let_ };
Код: Выделить всё
main.c(17): warning: #69-D: integer conversion resulted in truncation const uint8_t charset[16] = {let_0, let_1, let_2, let_3, \И очень не хотелось бы править инклюд, потому как этот инклюд, планируется использовать с любой шириной данных. В последнем проекте там был, вроде, вообще 32-х разрядный регистр.
Re: Вопросы по С/С++ (СИ)
В #define invertmask он и всплывает
Re: Вопросы по С/С++ (СИ)
Спасибо. Действительно, стоит убрать, как предупреждений нет. осталось придумать как побитно инвертировать, чтобы не было больно.


