Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
IM1
Грызет канифоль
Сообщения: 268
Зарегистрирован: Вт фев 16, 2010 12:10:38
Откуда: Воронеж, Россия

Re: Вопросы по С/С++ (СИ)

Сообщение IM1 »

shads писал(а):У меня 6-ка выдает
Код:
x = 6, a = 3 (как и в 4-ке. IM1 проверь еще раз у себя, скорее всего у тебя ошибка)
x = 2, a = 2 (в 4-ке было 2 и 3)
Странно. У нас с Вами вроде одна и та же сборка студии (судя по сообщению в соседней ветке).
Да, и наверное, стоит это воспринимать как некий казус и впредь не давать компилятору двусмысленных задач, и тогда все будет ОК.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Re: Вопросы по С/С++ (СИ)

Сообщение Kavka »

Выше написал же viewtopic.php?p=1619519#p1619519 (см. подчёркнутое).
Язык допускает только такое написание, но как оно должно работать в стандарте не указано.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Вопросы по С/С++ (СИ)

Сообщение unalex »

shads писал(а):Именно поэтому, в моем случае (первоначальном, с указателями), компилятор считает что я сравниваю данные под одним адресом, а они, по мнению компилятора не могут быть разными, и он просто вырезает условие (делает свое дело - оптимизирует)....


unalex писал(а):это называется оптимизация
зачем их сравнивать, если изначално понятно, что они указывают на одинаковые/разные объекты?

через 2 страницы выяснилось, что мои выводы подтвердились, что именно так и думает компилятор, обрабатывая эту строку кода

Совесть писал(а):Один нашел в этой строчке "одинаковые/разные объекты". Второй не разбираясь лепит "volatile". Браво!!! :)))

браво, Совесть, как всегда ни слова по делу, ни строчки о том с чем связана проблема, а лишь попытки обгадить других

не очень удачный способ поднять свою самооценку
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Вопросы по С/С++ (СИ)

Сообщение FreshMan »

ограничен ли размер массива ?
вот что у меня выдает
http://www.imgup.ru/image-wpgx101141220.html
Tell Me The Truth
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Вопросы по С/С++ (СИ)

Сообщение ibiza11 »

Не ограничен. Вы объявили массив содержащий 50 значений, а пытаетесь впихнуть в него больше чем 50. уберите число 50, оставьте только скобки []
Ставим плюсы: )
Аватара пользователя
baron_P
Нашел транзистор. Понюхал.
Сообщения: 183
Зарегистрирован: Вт сен 14, 2010 23:07:10
Откуда: Ростов

Re: Вопросы по С/С++ (СИ)

Сообщение baron_P »

Чтоб закрыть вопрос по этой программе:
Спойлер

Код: Выделить всё

#include<avr/io.h>
#define F_CPU 1200000UL
#include<util/delay.h>
int main(void)
{
 unsigned long lfsr = 1;
 unsigned char temp;
 DDRB = 0xff;
 while(1)
 {
  lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u);
  temp = (unsigned char) lfsr;
  DDRB = ~temp;
  PORTB = temp;
  temp = (unsigned char) (lfsr >> 24);
  _delay_loop_2(temp<<7);
 }
}

В итоге получилось, что если заменить это

Код: Выделить всё

lfsr = (lfsr >> 1) ^ (-(lfsr & 1u) & 0xd0000001u);
на это

Код: Выделить всё

lfsr = (lfsr >> 1) ^ ((lfsr & 1u) ? 0x80000057u : 0u);
, то генерируется примерно то же самое. На глаз на осциллограмме по крайней мере. Второе выражение - цитата из вики для конфигурации Галуа регистра сдвига с линейной обратной связью. В плане однозначности понимания, думаю, лучше вышло.
We do what we must because we can (c) GLaDOS
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

baron_P писал(а):В плане однозначности понимания, думаю, лучше вышло.
С моей точки зрения - намного лучше. И логика понятна (ушли шарады вроде беззнаковых чисел со знаком "минус"), и машиннозависимых выкрутасов нет.

Я бы еще заменил типы переменных на те, имена которых явно подчеркивают разрядность, например, uint32_t. Для битовых операций нагляднее.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Ха.....
Эта библиотечка, которую я последнее время леплю, выдала мне столько сюрпризов в Си, что аж смешно уже.....
Очередной тупняк..... Нужно сравнить 2 элемента массива. Если так то все нормально.....

Код: Выделить всё

#include <avr/io.h>
char massiv [2] = {0,0};

int main (void)
{
    if (massiv[0] == massiv[1])
        PORTB = 0xff;
    else
        PORTB 
= 0x00;
}
 


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

Код: Выделить всё

#include <avr/io.h>
char massiv [2] = {0x00, 0xff};

int main (void)
{
    if (~massiv[0] == massiv[1])
        PORTB = 0xff;
    else
        PORTB 
= 0x00;
}]
 


Оказывается компиль на этот раз, байтовые данные массива - превращает в двубайтовые :shock:
Естественно что при инверсии считанного байта инвертируется и добавленный компилятором 0 (хотя в другом числе он остается 0-м), в результате сравнение всегда имеет отрицательный результат :dont_know:

Код: Выделить всё

+00000027:   91200060    LDS       R18,0x0060     Load direct from data space
+00000029:   E030        LDI       R19,0x00       Load immediate
+0000002A:   9520        LAT       R18            Load and Toggle
+0000002B:   9530        LAT       R19            Load and Toggle
+0000002C:   91800061    LDS       R24,0x0061     Load direct from data space
+0000002E:   E090        LDI       R25,0x00       Load immediate
+0000002F:   1728        CP        R18,R24        Compare
+00000030:   0739        CPC       R19,R25        Compare with carry
+00000031:   F419        BRNE      PC+0x04        Branch if not equal
7:                PORTB = 0xff;
+00000032:   EF8F        SER       R24            Set Register
+00000033:   BB88        OUT       0x18,R24       Out to I/O location
+00000034:   C001        RJMP      PC+0x0002      Relative jump
9:                PORTB = 0x00;
+00000035:   BA18        OUT       0x18,R1        Out to I/O location
10:       }
+00000036:   E080        LDI       R24,0x00       Load immediate
+00000037:   E090        LDI       R25,0x00       Load immediate
+00000038:   9508        RET                      Subroutine return 
ВОПРОС..... КАКОЙ СТАНДАРТ Я НА ЭТОТ РАЗ НАРУШИЛ :oops:


PS решается опять с помощью доп переменной.....

Код: Выделить всё

#include <avr/io.h>
char massiv [2] = {0x00, 0xff};

int main (void)
{
    char temp = ~massiv[0];
    if (temp == massiv[1])
        PORTB = 0xff;
    else
        PORTB 
= 0x00;
}
 

Код: Выделить всё

+00000027:   91800060    LDS       R24,0x0060     Load direct from data space
+00000029:   9580        LAT       R24            Load and Toggle
+0000002A:   91900061    LDS       R25,0x0061     Load direct from data space
+0000002C:   1789        CP        R24,R25        Compare
+0000002D:   F419        BRNE      PC+0x04        Branch if not equal
8:              PORTB = 0xff;
+0000002E:   EF8F        SER       R24            Set Register
+0000002F:   BB88        OUT       0x18,R24       Out to I/O location
+00000030:   C001        RJMP      PC+0x0002      Relative jump
10:             PORTB = 0x00;
+00000031:   BA18        OUT       0x18,R1        Out to I/O location
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

shads писал(а):ВОПРОС..... КАКОЙ СТАНДАРТ Я НА ЭТОТ РАЗ НАРУШИЛ :oops:
Например, ISO/IEC 9899:1999, п. 6.3.1.1 Boolean, characters, and integers:

2 The following may be used in an expression wherever an int or unsigned int may be used:

— An object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int.
— A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.
Перед инвертированием значение элемента массива "продвигается" до int, а затем инвертируется. Само собой, результат не совпадает с тем, который ожидали увидеть.

Добавьте явное преобразование типов:

Код: Выделить всё

    if ((unsigned char)~massiv[0] == massiv[1])
, и не придется добавлять лишнюю переменную.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

thank you very much :)
Аватара пользователя
Alkarax
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт мар 21, 2013 16:22:09

Вопросы по С/С++ (СИ)

Сообщение Alkarax »

Здравствуйте! Я недавно заинтересовался микроконтроллерами и появилось желание сделать ик приемник и передатчик, схему-то я сделал, а вот с прошивкой возникли проблемы, пытаясь понять алгоритм передачи и приема ик сигнала перелопатил кучу инфы, но все было не то, но вот наткнулся на очень доступное объяснение, но команды тут мне не очень понятны. СИ я знаю так себе и привык к коду вида как в codevision. Не могли бы вы перевести данную програмку в вид попроще, например: TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11); - TCCR1A=0b11000010 или хотя бы объяснить каждую строчку предельно упрощенно
//36kHz Trager
TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11);
TCCR1B = (1<<WGM12) | (1<<WGM13) | (1<<CS10);
OCR1A = 111;
ICR1 = 222;

//Прерывание таймера каждые 2,048 ms для генерации сигнала --> 1/(8MHz/256/64)
TCCR0 = (1<<CS01) | (1<<CS00);
TIMSK |= (1<<TOIE0);

//Реализация сканирования
//Прерывание таймера каждые 0,256ms для приема сигнала --> 1/(8MHz/256/8)
TCCR0 |= (1<<CS01);
TIMSK |= (1<<TOIE0);

ISR передатчика должен на определенное время подавать несущую на передатчик. Длительность определяется переменной pulse. Переменная empty служит функции передачи в качестве индикатора того, продолжается ли процесс передачи или уже завершен. Таким образом предотвращается изменение переменной pulse во время процесса передачи.
volatile unsigned char empty = 0;
volatile unsigned char pulse = 0;


SIGNAL (SIG_OVERFLOW0) {
if (pulse) {
DDRB |= (1<<PB1);
empty = 1;
pulse--;
}
if (!pulse) {
empty = 0;
DDRB &= ~(1<<PB1);
}
}


void ir_send (unsigned char byte) {
if (!empty)
pulse = byte;
}

ISR приемника должна ожидать, пока на выходе TSOP не появится сигна низкого уровня. Если это произошло, то можно начинать процесс сканирования длины импульсов. В зависимости от длины импульса сигнал может интерпретироваться как та или иная команда. Количество команд может быть увеличено в любой момент за счет применения импульсов другой длины, здесь же для наглядности используется набор из двух команд.
volatile unsigned short timecount = 0;
volatile unsigned char empty = 0;
volatile unsigned char rec_byte = 0;


SIGNAL (SIG_OVERFLOW0) {
//----------
if (!(PINB & (1<<PB0))) { //Low-Pegel = log. 1 am Sender
timecount++;
empty = 1;
}
else
empty = 0;
if ((!empty) && (timecount)) {
//---------- //8fache Abtastung
if ((timecount > 70) && (timecount < 90)) { //pulse war 10
rec_byte = 10;
}
if ((timecount > 150) && (timecount < 170)) { //pulse war 20
rec_byte = 20;
}
timecount = 0;
}
}


unsigned char ir_receive (void) {
//Empfangsroutine
return rec_byte;
}

особенно интересую строчки типа: TIMSK |= (1<<TOIE0); как будет выглядеть весь байт целивом
DDRB &= ~(1<<PB1); "&= ~"- что это значит? как байт порта B будет выглядеть после этой манипуляции?
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Alkarax писал(а):Здравствуйте!
появилось желание сделать ик приемник и передатчик

Привет.
Прикол в том, что предыдущие пару страниц, я мучил народ тоже по поводу библиотечки обработки ИК канала.....
Решил свою смастерить, стандарта NEC, все уже работает, мелочи остались..... поделюсь если что.

А так по теме:
Alkarax писал(а):Не могли бы вы перевести данную програмку в вид попроще, например: TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11)
var = (1<<X) oзначает загрузку в var числа с установленным в 1 битом под номером X (X может быть от 0 до 7)
Например, выражение var = (1<<5)|(1<<7) - будет эквивалентно выражению var = 0b10100000.
В твоем случае выражение типа TCCR1A = (1<<COM1A1) | (1<<COM1A0) | (1<<WGM11) означает что в регистр TCCR1A будет загружено число с установленными битами COM1A1, СOM1A0, WGM11. Эти названия битов, где то задефайнены во включаемых библиотеках.

Alkarax писал(а):особенно интересую строчки типа: TIMSK |= (1<<TOIE0); как будет выглядеть весь байт целивом
Это выражение равнозначно TIMSK = TIMSK | (1<<TOIE0); т.е. установить (знак |) в регистре TIMSK бит с названием TOIE0, а остальные не трогать.

Alkarax писал(а):DDRB &= ~(1<<PB1);
Это выражение равнозначно TIMSK = TIMSK & ~(1<<PB1)
такая комбинация (& и ~) означает, что надо сбросить в регистре TIMSK бит с названием PB1, а остальные не трогать.....

Вообще то это описывается в любом пособии по Си, надо вникать, ато замучишся вопросы задавать, и других замучиш.... :)
Тут если что почитай: http://www.helloworld.ru/texts/comp/lang/c/c/dir.htm
или тут: http://lib.ru/MAN/DEMOS210/c.txt
Аватара пользователя
Alkarax
Первый раз сказал Мяу!
Сообщения: 27
Зарегистрирован: Чт мар 21, 2013 16:22:09

Re: Вопросы по С/С++ (СИ)

Сообщение Alkarax »

Больше спасибо буду разбираться! Дело в том, что когда я учил си эти же операции делались совсем другими командами, то есть смысл их я написать могу, но выглядеть будет подругому, печально, но кожется придется переучивать.
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Re: Вопросы по С/С++ (СИ)

Сообщение shads »

Да вроде Си он и в африке Си, и не меняется со временем.....
Например, практически все ответы на твои вопросы, можно найти тут http://www.helloworld.ru/texts/comp/lang/c/c/h13.htm
в табличке 7 описания, а дальше примерчики идут.....
vladimersv
Встал на лапы
Сообщения: 82
Зарегистрирован: Пн апр 09, 2012 04:07:37
Откуда: Донецкая. обл.

Re: Вопросы по С/С++ (СИ)

Сообщение vladimersv »

здравствуйте .
в програмировании я неочень разбераюсь ,вот возможно помжете .
имеется кусок кода :
void RUN_HOLD(void)
{
if(ButtonsBits == UP){ pnt_gOSC_MODE->Condition = RUN; btn->Text = "RUN"; }
else if(ButtonsBits == DOWN){ pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD";
}
else if(ButtonsBits == OK){ pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD"}
}
тоесть две кнопки переключают вверх-вниз -работаю нормально и есть 3я кнопка -ОК ,тоесть она при нажатии дублирует -вниз сейчас.
подскажите как правельно написать чтобы и влево-вправо остались как есть (тоесть их функции работы ) а вот кнопкой- ОК можно было переключать их также .(тоесть при разовом нажатии срабатывало как нажатие -вниз,а при повторном -вверх )
зарание спасибо .
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

:facepalm:
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

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

то_есть две кнопки переключают вверх-вниз -работаюТ нормально и есть 3я кнопка -ОК ,то_есть она при нажатии дублирует -вниз сейчас.
подскажите как правИльно написать чтобы и влево-вправо остались как есть (то_есть их функции работы ) а вот кнопкой- ОК можно было переключать их также .(то_есть при разовом нажатии срабатывало как нажатие -вниз,а при повторном -вверх )
заранЕе спасибо .

Честно говоря глаза кровью облились от режущего обилия ошибок в тексте.
Теперь по теме.
1. Непонятно назначение кнопки ОК зачем нужно дублирование вверх и вниз.
2.Приведенный кусок можно обработать через switch визуально понятнее выглядит.

Код: Выделить всё


void RUN_HOLD
(void)
{
  
switch 
(ButtonsBits){
        case(UP):         pnt_gOSC_MODE->Condition = RUN; btn->Text = "RUN";break;  
        case
(DOWN):   pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD";break;
        case(OK):        pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD";break; 
}
 
vladimersv
Встал на лапы
Сообщения: 82
Зарегистрирован: Пн апр 09, 2012 04:07:37
Откуда: Донецкая. обл.

Re: Вопросы по С/С++ (СИ)

Сообщение vladimersv »

за ошибки извеняюсь(вобщемто клавивиатура без руских почти) .
просто стояли в схеме 2 кнопки но поставил одну на 3 положения (тоесть вверх-вниз по меню они и при нажатии замыкает внутренняя -ОК ) тоесть при наведении в меню на кнопку RUN-HOLD нет теперь надобности влючать -отключать функцию кнопками верх-вниз а достаточно просто одним нажатием кномки ОК переключать .(но и изьять из меню фунции кнопок вверх-вниз нельзя ,это лично у меня просто кнопка на 3 положения )
за ответ и пример огромное спасибо ,попробую.
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Вопросы по С/С++ (СИ)

Сообщение unalex »

Код: Выделить всё

void RUN_HOLD(void)
{
   static unsigned char Last = UP;
   unsigned char State;
   
   State = ButtonBits;
   
   switch(State)
   {
      case(OK):
      State = (Last == DOWN) ? UP : DOWN;
      Last = State;
        case(UP):
      pnt_gOSC_MODE->Condition = RUN; btn->Text = "RUN"; break; 
        case(DOWN):
      pnt_gOSC_MODE->Condition = HOLD; btn->Text = "HOLD"; break;
   }
}



как-то перекак-то так
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Вопросы по С/С++ (СИ)

Сообщение unalex »

vladimersv писал(а):за ошибки извеняюсь(вобщемто клавивиатура без руских почти)


а у меня клавиатура без русских ВООБЩЕ(интересно а как это без русских ПОЧТИ)
печатаю методом тыка, но это не мешает мне писать грамотно
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Ответить

Вернуться в «Разные вопросы по МК»