Ага, спасибо. Нашел 5-й IAR 2000-го года. На нем сходу скомпилировалось без ошибок и предупреждений. А со сборкой - облом. Тот паренек ушлый оказался - сделал пару ссылок на внешние модули чтоб без него пересобрать нельзя было
Вопросы по С/С++ (СИ)
- paskal
- Нашел транзистор. Понюхал.
- Сообщения: 160
- Зарегистрирован: Пн сен 05, 2011 10:03:06
- Откуда: Тула
Re: Вопросы по С/С++ (СИ)
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3178887#p3178887"]похоже старый IAR[/uquote]
Ага, спасибо. Нашел 5-й IAR 2000-го года. На нем сходу скомпилировалось без ошибок и предупреждений. А со сборкой - облом. Тот паренек ушлый оказался - сделал пару ссылок на внешние модули чтоб без него пересобрать нельзя было
Ага, спасибо. Нашел 5-й IAR 2000-го года. На нем сходу скомпилировалось без ошибок и предупреждений. А со сборкой - облом. Тот паренек ушлый оказался - сделал пару ссылок на внешние модули чтоб без него пересобрать нельзя было
Если бы на станции "Мир" стояли Винды, она бы еще висела и висела...
- Реклама
Re: Вопросы по С/С++ (СИ)
Немного достаёт новый XC микрочиповский. Особенно, предупреждениями о неявном преобразовании знаковый-беззнаковый. Вот такая строчка:
пока все у меня объявлены как беззнаковые проблем нет. Но мне хочется переменную timezone объявить знаковой, так как она может быть и отрицательной. Так вот стоит это сделать, как получаю предупреждение:
Можно ли сделать, чтобы при отрицательном timezone оно вычиталось бы? Беззнаковость unixtime хотелось бы сохранить - 32 разряда и так еле хватает.
Пока я вижу вариант - делать две ветви для положительного и отрицательного. В одном суммировать, а вдругом вычитать абсолютное беззнаковое значение.
Код: Выделить всё
epoch = unixtime + (3600ul * (timezone + (flag.dst ? 1u : 0u)));Код: Выделить всё
main.c:421: warning: (373) implicit signed to unsigned conversionПока я вижу вариант - делать две ветви для положительного и отрицательного. В одном суммировать, а вдругом вычитать абсолютное беззнаковое значение.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
XC8 V1.38
Ругани нет 
PS: Работоспособность не проверял.
Добавлено after 5 minutes 20 seconds:
Попробуйте такой вариант :
Ну а воббще, он правильно ругается. Некоторые части выражения могут быть отрицательными, значение которых оперируется с беззнаковыми переменными.
Код: Выделить всё
volatile unsigned long epoch=0, unixtime=0;
volatile signed long timezone=0;
struct{
unsigned dst:1;
}flag;
void main(void){
flag.dst=1;
epoch = unixtime + (3600ul * (timezone + (flag.dst ? 1u : 0u)));
while(1){}
}
PS: Работоспособность не проверял.
Добавлено after 5 minutes 20 seconds:
Попробуйте такой вариант :
Код: Выделить всё
epoch = (signed long)unixtime + (3600L * (timezone + (flag.dst ? 1u : 0u)));Re: Вопросы по С/С++ (СИ)
[uquote="uldemir",url="/forum/viewtopic.php?p=3182934#p3182934"]Немного достаёт новый XC микрочиповский. Особенно, предупреждениями о неявном преобразовании знаковый-беззнаковый.[/uquote]
Предупреждает и правильно делает, это довольно распространенный тип ошибок. Например, чему равно -10 + 5U? Ответ 4294967291, хотя компилятор такой код с константами и не пропустит, но если речь идет о переменных и это часть более сложного выражения, то можно получить не самую очевидную ошибку.
Предупреждает и правильно делает, это довольно распространенный тип ошибок. Например, чему равно -10 + 5U? Ответ 4294967291, хотя компилятор такой код с константами и не пропустит, но если речь идет о переменных и это часть более сложного выражения, то можно получить не самую очевидную ошибку.
Re: Вопросы по С/С++ (СИ)
Мда. предупреждение, действительно, верное и критичное. Придётся вводить просто флаг запад-восток и делать две ветки.
Я тут на прошлой неделе почитывал MPLAB® XC8 C Compiler User’s Guide - оказывается, занимательнейшее чтиво.
Это началось с какойто из 1.4Х версии: http://radiokot.ru/forum/viewtopic.php? ... 1#p3108891
Я тут на прошлой неделе почитывал MPLAB® XC8 C Compiler User’s Guide - оказывается, занимательнейшее чтиво.
Это началось с какойто из 1.4Х версии: http://radiokot.ru/forum/viewtopic.php? ... 1#p3108891
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Реклама
Re: Вопросы по С/С++ (СИ)
строго говоря, в общем случае сдвиг времени в зоне не обязан быть целым часом. Например вот эти:volatile signed long timezone=0;
...
epoch = unixtime + (3600ul * (timezone + (flag.dst ? 1u : 0u)));
Asia/Colombo +05:30
Asia/Kathmandu +05:45
Asia/Kolkata +05:30
Australia/Broken_Hill +09:30
Re: Вопросы по С/С++ (СИ)
Спасибо, я в курсе. Но такая задача не стоит из-за того, что конфигурирование будет через-чур сложным.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Zhuk72
- Сверлит текстолит когтями
- Сообщения: 1231
- Зарегистрирован: Ср янв 29, 2014 08:41:31
- Откуда: Баку
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Я тоже недавно вместе с обновлением МПЛаба до четверки и компилятор обновил до 1.43, после чего и полезли эти "имплисит конвершны".
Каждый имеет право на свое личное ошибочное мнение.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
У меня было тяжелое детство - я до 14 лет смотрел черно-белый телевизор.
Re: Вопросы по С/С++ (СИ)
Здравствуйте нe у кого нет этой книги "Программирование графики в Windows 95 М. Янг" очень она бы мне пригодилась , большое спасибо.
- Chip115
- Сверлит текстолит когтями
- Сообщения: 1132
- Зарегистрирован: Пт фев 16, 2007 14:18:20
- Откуда: Новосибирск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Всем привет!
Требуется в массиве tmp получить строку из четырех символов (цифры).
В массиве, при этом,появляется '1' '2' '\0' '\0'.
Как заставить sprintf вывести в массив строку '0012'? Два нуля sprintf интерпретирует как конец строки. А если включить оптимизацию (юзаю IAR), то он еще и символ пробела добавляет.
Требуется в массиве tmp получить строку из четырех символов (цифры).
Код: Выделить всё
uint16_t data = 0012;
char tmp [4];
sprintf(tmp, "%u", data );
Как заставить sprintf вывести в массив строку '0012'? Два нуля sprintf интерпретирует как конец строки. А если включить оптимизацию (юзаю IAR), то он еще и символ пробела добавляет.
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
© Альберт Эйнштейн
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
"%04u" попробуйте. Должен нулями заполнять свободные символы.
Добавлено after 4 minutes 15 seconds:
PS: Совет. Размер массива увеличьте. Должен быть всегда запас под символ окончания строки ('\0').
Добавлено after 4 minutes 15 seconds:
PS: Совет. Размер массива увеличьте. Должен быть всегда запас под символ окончания строки ('\0').
Re: Вопросы по С/С++ (СИ)
Здравствуйте, помогите упростить код если это возможно, есть 2 кейса практически идентичных, в первом кейсе выключает затем включает пин МК, во втором наоборот включает а затем выключает, можно ли это собрать как то в функцию при этом уменьшив объем занимаемого кода :
Код: Выделить всё
case 1:
if (flag==0){
PORTB &=~(1<<PB1);
if (tic>=Timer1){flag++; tic= 0;}
}
else {
PORTB |= (1<<PB1);
if (tic>=Timer2){tic = 0; flag=0;}
}
break;
case 2:
if (flag==0){
PORTB |= (1<<PB1);
if (tic>=Timer1){flag++; tic= 0;}
}
else {
PORTB &=~(1<<PB1);
if (tic>=Timer2){tic = 0; flag=0;}
}
break;- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
char tmp;
switch(???){
case 1: tmp = flag; break;
case 2: tmp = !flag; break;
}
if (tmp==0){
PORTB &=~(1<<PB1);
if (tic>=Timer1){flag++; tic= 0;}
} else {
PORTB |= (1<<PB1);
if (tic>=Timer2){tic = 0; flag=0;}
}скорее всего оптимизация вашего кода должна быть глубже, чем только этот кусочек
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]
В массиве, при этом,появляется '1' '2' '\0' '\0'.[/uquote]
На самом деле 0012 это восьмеричная константа (поскольку нолик в начале) а не десятичная - и этот код заполнит буфер тремя символами '1', '0', '\0'.
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]Как заставить sprintf вывести в массив строку '0012'?[/uquote]
Про %04u вам уже сказали, но при этом нужно либо размер tmp увеличить до 5 - поскольку терминатору место нужно. Или использовать snprintf, контролирующий "берега" приёмного буфера. Ну и написать либо data = 12 либо data = 014.
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]Два нуля sprintf интерпретирует как конец строки.[/uquote]
К тому моменту когда sprintf получает data параметром - тех "нулей" и след простыл. И 012 и 0012 и 000012 все равны 10 (decimal).
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]А если включить оптимизацию (юзаю IAR), то он еще и символ пробела добавляет.[/uquote]
Как уже сказано выше sprintf помещает в буфер три символа - пробел в этой позиции был изначально. Оптимизация просто сменила полжение буфера и там оказался немножко другой "мусор".
Код: Выделить всё
uint16_t data = 0012;
char tmp [4];
sprintf(tmp, "%u", data );
На самом деле 0012 это восьмеричная константа (поскольку нолик в начале) а не десятичная - и этот код заполнит буфер тремя символами '1', '0', '\0'.
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]Как заставить sprintf вывести в массив строку '0012'?[/uquote]
Про %04u вам уже сказали, но при этом нужно либо размер tmp увеличить до 5 - поскольку терминатору место нужно. Или использовать snprintf, контролирующий "берега" приёмного буфера. Ну и написать либо data = 12 либо data = 014.
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]Два нуля sprintf интерпретирует как конец строки.[/uquote]
К тому моменту когда sprintf получает data параметром - тех "нулей" и след простыл. И 012 и 0012 и 000012 все равны 10 (decimal).
[uquote="Chip115",url="/forum/viewtopic.php?p=3203433#p3203433"]А если включить оптимизацию (юзаю IAR), то он еще и символ пробела добавляет.[/uquote]
Как уже сказано выше sprintf помещает в буфер три символа - пробел в этой позиции был изначально. Оптимизация просто сменила полжение буфера и там оказался немножко другой "мусор".
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Вопросы по С/С++ (СИ)
Доброго времени суток. Читаю про хорошие манеры программирования на Си. Один из пунктов: "По возможности используйте do { } while(выражение)". Нигде не могу найти объяснение, чем оно лучше while(выражение) { }.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
не берите в голову, если это не про макросы сказано. ничем оно не лучше и не хуже.Пока_без_кота писал(а):По возможности используйте do { } while(выражение)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
-
Пока_без_кота
- Потрогал лапой паяльник
- Сообщения: 359
- Зарегистрирован: Чт авг 08, 2013 01:06:54
Re: Вопросы по С/С++ (СИ)
Благодарствую.
Re: Вопросы по С/С++ (СИ)
в общем случае "while(){}" использует дополнительную команду перехода, т.е. медленнее.Нигде не могу найти объяснение, чем оно лучше while(выражение) { }.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
в общем случае - это рядом со сферическим конём в вакууме? в общем случае как раз наоборот, между всеми вариантами циклов while, for и do нет никакой разницы, а вот в частных случаях она может появляться.smalcom писал(а):в общем случае "while(){}" использует дополнительную команду перехода
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Тело цикла do ... while() выполняется по крайней мере один раз.
Многие компиляторы код проверки условия и переход на начало тела цикла располагают после тела цикла. Код, генерируемый для циклов for(){} и while() {} отличается тем, что для обеспечения проверки условия перед первой итерацией цикла, генерируется команда перехода на проверку условия.
То есть для цикла
генерируется:
Для цикла
генерируется:
Для цикла
генерируется:
Отсюда видно, что наиболее короткий и простой код генерируется для цикла do...while().
Но пользоваться лучше тем, который больше подходит для данного конкретного случая.
Многие компиляторы код проверки условия и переход на начало тела цикла располагают после тела цикла. Код, генерируемый для циклов for(){} и while() {} отличается тем, что для обеспечения проверки условия перед первой итерацией цикла, генерируется команда перехода на проверку условия.
То есть для цикла
Код: Выделить всё
do
<body>
while(<e1>)
Код: Выделить всё
L1:
<body>
if( <e1> ) goto L1
Код: Выделить всё
while( <e1> )
{
<body>
}
Код: Выделить всё
goto Ltest;
L1:
<body>
Ltest:
if( <e1> ) goto L1
Код: Выделить всё
for(<e2>; <e1>; <e3> )
{
<body>
}
Код: Выделить всё
<e2>
goto Ltest;
L1:
<body>
<e3>
Ltest:
if( <e1> ) goto L1
Но пользоваться лучше тем, который больше подходит для данного конкретного случая.
Последний раз редактировалось Const14 Пт окт 27, 2017 09:26:15, всего редактировалось 4 раза.


