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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Roman Venom
Сверлит текстолит когтями
Сообщения: 1135
Зарегистрирован: Сб июл 11, 2009 18:42:21
Откуда: Украина, г.Николаев

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

Сообщение Roman Venom »

Sudar69
Ты предлагаешь просто сделать массив на 375 значений (375 мм. рт. ст. предел для моего датчика давления) и все.

Если идёт речь о оцифрованых данных после закрытия клапана, то 375 значений это ОЧЕНЬ мало. Усреднять-то из чего-то надо. Тем более мега легко позволяет много больше снять за это время.

Еще есть идея сделать так, что бы после каждого нового измерения обрабатывать данные и находить производные и когда они перестанут изменяться то выводить значения на экран и открывать клапан (это должно происходить как только определим нижнее давление).

Первое. Производная начального значения будет равна нулю, следует это учесть. Второе, дрейф АЦП меги будет в самом лучшем случае 1-2МЗР. Т.е. производная в ноль не установится, если не "округлить" полезное значение.
Успех - императив!
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7356
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

Не затруднит ли кого еще раз вразумить по поводу перечислимого типа данных.
Вот определил:

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

typedef enum {
  show_clock,
  set_hr,
  set_min,
  res_sec} states;

states state;
Присваивания, сравнения идут без проблем. Но надо сделать переход на "следующее" состояние. Если пишу state++ - вперед проходит нормально и... уходит куда-то дальше. Т.е. не ходит по-кругу.
Пробую написать

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

state = (state == res_sec) ? show_clock : ++state;
- ругается на Warning[Pa079]: undefined behavior: variable "state" (declared at line 72) (or a value reached by some form of indirection.
хм, не писать же switch для всех переходов?

p.s. пока обошелся ifом.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

а свитч чем не угодил ? Наоборот, удобно

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


cState=fnSelect(cState);
//

unsigned char fnSelect(unsigned char cState)
{
unsigned char cNewState;
switch(state)
{
case show_clock:
////////////////
// bla bla bla
cNewState =set_hr;
break;
// i tak dalee

}
return cNewState;
}

ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

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

Сообщение ut1wpr »

uldemir писал(а):Но надо сделать переход на "следующее" состояние. Если пишу state++ - вперед проходит нормально и... уходит куда-то дальше. Т.е. не ходит по-кругу.
Пробую написать

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

state = (state == res_sec) ? show_clock : ++state;
- ругается на Warning[Pa079]: undefined behavior: variable "state" (declared at line 72) (or a value reached by some form of indirection.
хм, не писать же switch для всех переходов?

p.s. пока обошелся ifом.
Вдумайтесь. Вы создали перечисляемый тип. В составе которого есть перечисленные вами элементы. Вы можете при объявлении добавить или удалить сами элементы. Но для вас есть тайна великая, какие значения скрываются под перечисляемыми именами. Вам должно быть известно, что вы можете присвоить имени свое собственное значение. Тогда следующему элементу будет присвоена величина на 1 больше вашей, т.е. следующая. Что значит "по кругу"? Чем и где вы определили размерность объявленного вами типа ("замкнули круг"). Попробуйте присвоить первому перечисляемому величину 255. Потестируйте, какие будут следующие значения при автоперечислении. Поиграйте с размерностью на этот раз уже переменной с созданным вами типом. Увидите неожиданные результаты. Особенно на различных по разрядности платформах. Всегда помните, что байт не есть единственная по разрядности величина, применяемая при объявлении перечисляемых типов.
С уважением,
Виктор.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7356
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

ну я примерно вдумался. вот почему ++state; корректно, а state=++state; нет? Оно возвращает данные другого типа? я то полагал, что возвратит следующий элемент списка.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

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

Сообщение ut1wpr »

uldemir писал(а):ну я примерно вдумался. вот почему ++state; корректно, а state=++state; нет? Оно возвращает данные другого типа? я то полагал, что возвратит следующий элемент списка.
А кто сказал, что ++state корректно? Компилятор не ругнулся? Это ничего еще не значит. Не путайте элементы перечисляемого списка с указателем.

Должен принести свои извинения. Ради любопытства решил потестировать ваши примеры. И сам бул удивлен. Беру свои слова обратно и радость игрищ с перечисляемыми типами оставляю вам. Я никогда не сталкивался с необходимостью писать в таком стиле. Еще раз извините.
С уважением,
Виктор.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

uldemir писал(а):ну я примерно вдумался. вот почему ++state; корректно, а state=++state; нет?
Компилятор насторожили две записи в одну переменную в промежутке между точками следования, он и выдал предупреждение об UB (порядок записей неопределён). Тут две записи: в операторе ++ и в операторе =.

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

int i;
void foo() { i = ++i; }
должно дать то же самое предупреждение, если дало с enum.
Хотя конкретно тут результат будет одинаковый, это в i = i++; будут проблемы порядка записей.
Возможно, компилятор ворчит на то, что он при оптимизации оставил одну запись в переменную из двух имеющихся в выражении (кстати, при volatile state он обязан будет обе записи оставить — оно Вам нужен лишний код?). Возможно, просто обиделся на наличие двух записей и не стал даже анализировать корректность результата.

А кто не даёт написать

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

state = (state == res_sec) ? show_clock : state + 1;
и избавиться от предупреждения?
(в С, так как в С++ тут таки будет ошибка несовпадения типов, нужно будет явно написать приведение (states)(state+1) )

p.s.
(тут был неправильный p.s., правильный был бы с постинкрементом, но он тяжело читается и не нужен такой)
Последний раз редактировалось avreal Сб май 12, 2012 12:54:30, всего редактировалось 1 раз.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7356
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

Да, про конфликт порядка записи я и позабыл. А на конструкцию state+1 получал предупреждение, но не стал вникать какого типа будет результат и не додумался, что можно воспользоваться приведением типа. Спасибо за внятное разъяснение.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

какая разница написать

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


state 
= (state == res_sec) ? show_clock : state + 1;
 

или

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


state 
= (state == res_sec) ? show_clock : set_hour;  

все равно при перестройке енум списка в этом случае придется переделывать всю программу.в отличие от определенной константы.
В поисках истины человек развивается.
Аватара пользователя
VannO)))
Открыл глаза
Сообщения: 49
Зарегистрирован: Вс дек 05, 2010 00:53:17
Откуда: Киев

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

Сообщение VannO))) »

Вопрос к знатокам DFT
В вики по этому поводу написано:
Прямое преобразование:
Изображение
Обратное преобразование:
Изображение
Обозначения:
N — количество значений сигнала, измеренных за период, а также количество компонент разложения;
xn, n=0...N-1 — измеренные значения сигнала (в дискретных временных точках с номерами n), которые являются входными данными для прямого преобразования и выходными для обратного;
Xk, k=0...N-1 — комплексные амплитуды синусоидальных сигналов, слагающих исходный сигнал; являются выходными данными для прямого преобразования и входными для обратного; поскольку амплитуды комплексные, то по ним можно вычислить одновременно и амплитуду, и фазу;
|Xk|/N — обычная (вещественная) амплитуда k-го синусоидального сигнала;
arg(Xk) — фаза k-го синусоидального сигнала (аргумент комплексного числа);
k — индекс частоты. Частота k-го сигнала равна k/T, где T — период времени, в течение которого брались входные данные.

А теперь собственно вопрос. Если n=0...N-1 и k=0...N-1(причем значения изменяются синхронно) то почему они выделяются как отдельные переменные? Т.е. скажем не n^2 вместо произведения n*k
Не втыкать.
Аватара пользователя
AI_Disable
Сверлит текстолит когтями
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб
Контактная информация:

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

Сообщение AI_Disable »

VannO))), с чего вдруг они изменяются синхронно. Приглядитесь, в первой формуле n - это индекс суммирования, а k - внутри этой суммы константа. В нижней формуле n и k поменяны ролями.
Аватара пользователя
VannO)))
Открыл глаза
Сообщения: 49
Зарегистрирован: Вс дек 05, 2010 00:53:17
Откуда: Киев

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

Сообщение VannO))) »

Спасибо, вы правы. Не заметил, закопался.
Иногда крепкий сон лучше всяких мудрствований)
Не втыкать.
Аватара пользователя
bfgroup
Родился
Сообщения: 10
Зарегистрирован: Чт ноя 17, 2011 11:06:55
Откуда: Novosibirsk

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

Сообщение bfgroup »

ребята, подскажите нубу. возможно ли, средствами языка С написать функцию, которая возвращала бы массив??

и если да, то набросайте примерный шаблон программы.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

А чем не подходит возврат указателя ? Зачем весь массив перекошачивать множество раз ?
Аватара пользователя
AI_Disable
Сверлит текстолит когтями
Сообщения: 1116
Зарегистрирован: Чт окт 15, 2009 14:16:18
Откуда: Екб
Контактная информация:

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

Сообщение AI_Disable »

Функции в С/С++ могут возвращать только одну переменную. Чтобы функция могла работать с массивом, нужно выделить для него память перед вызовом этой функции и передать ей указатель.
Например, эта функция заполнит три элемента массива цифрами 3, 5 и 8:

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

void fun(int * a) {
a[0] = 3;
a[1] = 5;
a[2] = 8;
return;
}

int main()  {
...
int mas[3];
fun(mas);
// теперь в массиве mas лежат 3, 5 и 8
...
}
Аватара пользователя
ChipKiller
Сверлит текстолит когтями
Сообщения: 1163
Зарегистрирован: Ср янв 05, 2011 16:25:15

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

Сообщение ChipKiller »

bfgroup писал(а):ребята, подскажите нубу. возможно ли, средствами языка С написать функцию, которая возвращала бы массив??
... функция может возвращать "указатель на ..." массив, структуру и т.д. Скорее всего Вы еще не решили зачем это нужно....
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

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

Сообщение BorisSPB »

Функция может возвращать массив. Для этого надо определить структуру в которой один член - массив нужной длинны и возвращать эту структуру.

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

typedef struct
{
   int a[100];
} SAMPLE_STRUCT;

SAMPLE_STRUCT GetSample(void)
{
   SAMPLE_STRUCT s;
   s.a[0] = 0;
   s.a[1] = 1;
   return s;
}

void main(void)
{
   SAMPLE_STRUCT s1;
   s1 = GetSample();
}

Только это неэффективно, одни и те же значения переписываются несколько раз. Первый раз при копировании в возвращаемое значение, второй раз из временного объекта в переменную в месте вызова.
Так что вопрос не в том можно ли, а надо ли? Тем более если программа пишется, скажем для контроллера с 1кБ программной памяти, 64 байта ОЗУ и 4-уровневым стеком ;)
Аватара пользователя
Chip115
Сверлит текстолит когтями
Сообщения: 1132
Зарегистрирован: Пт фев 16, 2007 14:18:20
Откуда: Новосибирск
Контактная информация:

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

Сообщение Chip115 »

Всем привет! Наткнулся на такую проблему...
Имеется переменная типа

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

unsigned long ulMsgID
и массив

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

unsigned char pucBufferRx[10]
. Мне надо выбрать младшие два байта из ulMsgID и запихнуть их младшими в массив. Как мне выделить два байта из ulMsgID? Простите за тупость, но я сегодня торможу по полной (((
Теория — это когда все известно, но ничего не работает. Практика — это когда все работает, но никто не знает почему. Мы же объединяем теорию и практику: ничего не работает… и никто не знает почему!
© Альберт Эйнштейн
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

а маска не прокатит?

что значит младшими в массив запихать?с первыми номерами?
В поисках истины человек развивается.
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

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

Сообщение ut1wpr »

Chip115 писал(а):Мне надо выбрать младшие два байта из ulMsgID и запихнуть их младшими в массив.
А как вы определяете младший байт в двухбайтовом числе? Правильно. Берете остаток от деления этого числа на 256. А как определяете старший байт? Правильно. Берете целое от деления этого числа на 256.
Теперь определитесь с размерностью вашего лонг-числа и вычислите на какую величину надо его делить. Тут уж сами...
И еще. В массиве нет младших и старших ячеек. Они нумеруются от нулевой до максимальной. Услышав фразу "младшими в массив" хочется спросить - а с какой стороны у вас старшие? Типа "А где лево? Дак с другой стороны от право". :)
С уважением,
Виктор.
Ответить

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