Страница 88 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 11, 2012 09:29:15
Roman Venom
Sudar69
Ты предлагаешь просто сделать массив на 375 значений (375 мм. рт. ст. предел для моего датчика давления) и все.
Если идёт речь о оцифрованых данных после закрытия клапана, то 375 значений это ОЧЕНЬ мало. Усреднять-то из чего-то надо. Тем более мега легко позволяет много больше снять за это время.
Еще есть идея сделать так, что бы после каждого нового измерения обрабатывать данные и находить производные и когда они перестанут изменяться то выводить значения на экран и открывать клапан (это должно происходить как только определим нижнее давление).
Первое. Производная начального значения будет равна нулю, следует это учесть. Второе, дрейф АЦП меги будет в самом лучшем случае 1-2МЗР. Т.е. производная в ноль не установится, если не "округлить" полезное значение.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 11, 2012 11:48:36
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ом.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 11, 2012 13:42:52
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;
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 11, 2012 14:33:23
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. Потестируйте, какие будут следующие значения при автоперечислении. Поиграйте с размерностью на этот раз уже переменной с созданным вами типом. Увидите неожиданные результаты. Особенно на различных по разрядности платформах. Всегда помните, что байт не есть единственная по разрядности величина, применяемая при объявлении перечисляемых типов.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 11, 2012 14:47:47
uldemir
ну я примерно вдумался. вот почему ++state; корректно, а state=++state; нет? Оно возвращает данные другого типа? я то полагал, что возвратит следующий элемент списка.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 11, 2012 14:51:32
ut1wpr
uldemir писал(а):ну я примерно вдумался. вот почему ++state; корректно, а state=++state; нет? Оно возвращает данные другого типа? я то полагал, что возвратит следующий элемент списка.
А кто сказал, что ++state корректно? Компилятор не ругнулся? Это ничего еще не значит. Не путайте элементы перечисляемого списка с указателем.
Должен принести свои извинения. Ради любопытства решил потестировать ваши примеры. И сам бул удивлен. Беру свои слова обратно и радость игрищ с перечисляемыми типами оставляю вам. Я никогда не сталкивался с необходимостью писать в таком стиле. Еще раз извините.
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб май 12, 2012 12:45:07
avreal
uldemir писал(а):ну я примерно вдумался. вот почему ++state; корректно, а state=++state; нет?
Компилятор насторожили две записи в одну переменную в промежутке между точками следования, он и выдал предупреждение об UB (порядок записей неопределён). Тут две записи: в операторе ++ и в операторе =.
должно дать то же самое предупреждение, если дало с enum.
Хотя конкретно тут результат будет одинаковый, это в
i = i++; будут проблемы порядка записей.
Возможно, компилятор ворчит на то, что он при оптимизации оставил одну запись в переменную из двух имеющихся в выражении (кстати, при volatile state он обязан будет обе записи оставить — оно Вам нужен лишний код?). Возможно, просто обиделся на наличие двух записей и не стал даже анализировать корректность результата.
А кто не даёт написать
Код: Выделить всё
state = (state == res_sec) ? show_clock : state + 1;
и избавиться от предупреждения?
(в С, так как в С++ тут таки будет
ошибка несовпадения типов, нужно будет явно написать приведение
(states)(state+1) )
p.s.
(тут был неправильный p.s., правильный был бы с постинкрементом, но он тяжело читается и не нужен такой)
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб май 12, 2012 12:52:55
uldemir
Да, про конфликт порядка записи я и позабыл. А на конструкцию state+1 получал предупреждение, но не стал вникать какого типа будет результат и не додумался, что можно воспользоваться приведением типа. Спасибо за внятное разъяснение.
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб май 12, 2012 15:38:24
vitalik_1984
какая разница написать
Код: Выделить всё
state = (state == res_sec) ? show_clock : state + 1;
или
Код: Выделить всё
state = (state == res_sec) ? show_clock : set_hour;
все равно при перестройке енум списка в этом случае придется переделывать всю программу.в отличие от определенной константы.
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб май 12, 2012 22:14:01
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
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб май 12, 2012 23:50:33
AI_Disable
VannO))), с чего вдруг они изменяются синхронно. Приглядитесь, в первой формуле n - это индекс суммирования, а k - внутри этой суммы константа. В нижней формуле n и k поменяны ролями.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вс май 13, 2012 10:37:31
VannO)))
Спасибо, вы правы. Не заметил, закопался.
Иногда крепкий сон лучше всяких мудрствований)
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн май 14, 2012 10:44:06
bfgroup
ребята, подскажите нубу. возможно ли, средствами языка С написать функцию, которая возвращала бы массив??
и если да, то набросайте примерный шаблон программы.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн май 14, 2012 11:41:08
Аlex
А чем не подходит возврат указателя ? Зачем весь массив перекошачивать множество раз ?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн май 14, 2012 11:43:42
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
...
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн май 14, 2012 11:47:48
ChipKiller
bfgroup писал(а):ребята, подскажите нубу. возможно ли, средствами языка С написать функцию, которая возвращала бы массив??
... функция может возвращать
"указатель на ..." массив, структуру и т.д. Скорее всего Вы еще не решили зачем это нужно....
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн май 14, 2012 12:17:24
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-уровневым стеком

Re: Вопросы по С/С++ (СИ)
Добавлено: Ср май 16, 2012 17:13:50
Chip115
Всем привет! Наткнулся на такую проблему...
Имеется переменная типа
и массив
. Мне надо выбрать младшие два байта из ulMsgID и запихнуть их младшими в массив. Как мне выделить два байта из ulMsgID? Простите за тупость, но я сегодня торможу по полной (((
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср май 16, 2012 17:35:17
vitalik_1984
а маска не прокатит?
что значит младшими в массив запихать?с первыми номерами?
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср май 16, 2012 17:42:25
ut1wpr
Chip115 писал(а):Мне надо выбрать младшие два байта из ulMsgID и запихнуть их младшими в массив.
А как вы определяете младший байт в двухбайтовом числе? Правильно. Берете остаток от деления этого числа на 256. А как определяете старший байт? Правильно. Берете целое от деления этого числа на 256.
Теперь определитесь с размерностью вашего лонг-числа и вычислите на какую величину надо его делить. Тут уж сами...
И еще. В массиве нет младших и старших ячеек. Они нумеруются от нулевой до максимальной. Услышав фразу "младшими в массив" хочется спросить - а с какой стороны у вас старшие? Типа "А где лево? Дак с другой стороны от право".
