Но, по хорошему, подобные вопросы относятся к разделу "Обучалка"->"Теория", а здесь было бы уместней обсуждать вопросы особенностей программирования именно под МК.
Я бы так предположил.
Оказывается я был не прав.
vitalik_1984 писал(а):
или есть более разумные варианты?
достаточно в нужном месте указатель привести к нужному типу:
//////
flash uchar *string1="String";
//////
char *string2;
string2=(char*)string1;
In theory, theory and practice are the same. In practice, they're not.
Конечно, "обучалка". Но мысль у меня была совершенно прагматичная: выводить в mcc18 на консоль SIM Uart плавающие числа. Причём выводить так:
printf((far const rom char*)"f_val=%s\n", ftos(f_val));
и с этой задачей мы справились. Я бы, без вашей помощи, дорогие коты, неделю кувыркался, а так в сумме день потратил, да научился кой-чему.
ЗЫ. Друзья, стоит всю функцию ftos выкладывать? 6 строк. Со знаком, выбором кол-ва знаков после запятой и округлением? Или каждый сам специалист?
Tolmi писал(а):достаточно в нужном месте указатель привести к нужному типу:
//////
flash uchar *string1="String";
//////
char *string2;
string2=(char*)string1;
Этого не достаточно.
Строку нужно переместить из флеши в РАМ, т.к. функция ждёт указатель на область РАМа. А приведение типа всего-лишь поможет присвоить одному указателю(string2) значение другого(string1) без варнингов и ошибок. Но указывать он будет всё равно на область флеши.
Или нет ?
В большинстве случаев достаточно...
Но здесь другое... строки типа "lol.txt" в WINAVR сохраняются дважды... в DATA и PROGRAM...
Первоначально строка находится в PROGRAM (иначе - откуда ей взяться), потом она загружается в DATA... И дальше уже идёт работа с копией в DATA...
А вот как с этим делом в Кодэвижэне... ХЗ...
Если нет никаких опций в настройках СV, то Ченовский исходник придётся основательно перелопачивать... или определять все нужные строки с последующим приведением типов... vitalik_1984 высказывал там здравые мысли...
Может проще в студии все сделать?Пример то для нее и много #IF #ELSE под нее в библиотеке заточено.
Если эта строка во флешь, то так и будет считать, что указатель на флешь.
Но лучше сразу забить на этот КодэВздроч... раз и навсегда...
"Я не даю готовых решений, я заставляю думать!"(С)
В любом случае, нужно иметь копию в области данных и указатель на него. Иначе - "БытьБеда" Функция думает, что указатель на дату, а ему суют на флешь...
В том то и дело...
Как копировать строку "lol.txt"... или делать приведение типов, если "lol.txt" нигде и никак не определена??? К чему привязываться???
Ченовский исходник придётся основательно перелопачивать...
или определять все нужные строки с последующим приведением типов...
Последний раз редактировалось HHIMERA Чт окт 18, 2012 18:48:15, всего редактировалось 1 раз.
"Я не даю готовых решений, я заставляю думать!"(С)
illarionovsp писал(а):Но мысль у меня была совершенно прагматичная: выводить в mcc18 на консоль SIM Uart плавающие числа. Причём выводить так:
printf((far const rom char*)"f_val=%s\n", ftos(f_val));
...
стоит всю функцию ftos выкладывать? 6 строк.
Почему бы и нет? Для завершённости подтемы.
Хотя у большинства компиляторов библиотечная printf() умеет работать с %f (или есть несколько версий, урезанные по разному и полная с %f), но printf фактически интерпретатор некого языка управления выводом, поэтому размер у него больше, чем просто для преобразования разных чисел в строку.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Ребята, всплыл вопрос, на который не могу найти нормального решения!
Вот допустим, есть массив {10,35,60,100}
Как программно взять ближайшее число из массива, например к числу 33, или 50!
тоесть мне нужно в результате получить номер члена, к которому ближе всего это число!
Кто подскажет, как это организовать ?
Я бы сделал перебором и вычитанием. Искомым элементом будет тот, у которого результат вычитания будет меньшим. Отрицательные результаты вычитания, перед сравнением, переводим в положительные.
Sceam73 писал(а):...всплыл вопрос, на который не могу найти нормального решения! Вот допустим ...
.. в любом случае многое зависит от "допустим", а именно от размера массива и его характеристик ( наверное массив упорядочен ?). Если массив мал, то как написал Аlex - простой перебор, если массив большой - наверное лучше бинарный поиск...
массив содержит 270 элементов! Самые большие числа 5тизначные , самое малое - 0 ! массив упорядочен, тоесть от большего к нулю! И еще нужно минимум вычислительных операций! Так как это будит система зажигания мотоцикла, и вычисляться все будит в плоть до 14 тыс раз в минуту! Так же контроллер будит отображать информацию на лсд, и я боюсь перегрузить контроллер, что б он не тормозил и не тупил! Контроллер атмега8а, кварц 10мгц, как думаете не сильно ли ему накладно будит ?
Sceam73 писал(а):массив содержит 270 элементов ... и вычисляться все будит в плоть до 14 тыс раз в минуту!
Ваш параметр будет изменяться достаточно медленно - как я понимаю, Вы таким образом хотите получить угол опережения.
Из этого следует такой вариант решения.
#define TABLE_SIZE 270 // Размер массива table.
// На самом деле массив содержит на один элемент больше.
// Последний элемент - ограничитель для предовращения
// зацикливания и выхода за границы массива.
unsigned int table [TABLE_SIZE + 1]={
0, 10, 33,
65535}; // Ограничитель - максимально возможное число.
// Функция возврашает число I, удовлетворяющее условию
// table[I] < X <= table[I+1]
unsigned int convert(unsigned int X)
{
static int index=0;
static unsigned int top=0, bottom=0;
while ((index >= 0) && (index < TABLE_SIZE))
{
if (X > top)
{
index++;
bottom=top;
top=table[index];
continue;
}
if (X < bottom)
{
index--;
top=bottom;
bottom=table[index];
continue;
}
break;
}
return (unsigned int) index;
}
UPD. Алгоритм рассчитан на возрастание чисел в массиве.
А из наших труб идет необычный дым. Стой! Опасная зона! Работа мозга!...
Sceam73 писал(а):массив содержит 270 элементов ... и вычисляться все будит в плоть до 14 тыс раз в минуту!
Ваш параметр будет изменяться достаточно медленно - как я понимаю, Вы таким образом хотите получить угол опережения.
Из этого следует такой вариант решения.
В моей программе avreal обнаружил ошибку. Прошу модератора заменить мой пост на этот.
char* ftos(float ff) {
int g, l, z=1, n=3; static char s[20]; float ft, fp=pow(10.0, n);
if(ff<0) { z=-1; ff=-ff; } g=ff; ft=fp*(ff-g)+0.5;
l=ft; if(ft>=fp) { g++; l-=fp; } g=z*g;
sprintf(s, (far const rom char*)"%i.%0*i", g, n, l);
return s;
}
здесь n - кол-во знаков после запятой.
Прога проверена на DevC++ и mcc18. Ошибок, вроде, нет.
illarionovsp писал(а):здесь n - кол-во знаков после запятой.
Ну так подпрограмма уже совсем готова принимать число знаков после запятой вторым аргументом.
Интересно -- обычно printf-ы без float и хитрые форматривования с переменной шириной поля не поддерживают. А тут с float обленились, а %0* сделали.
А что оно напечатает, если вывести
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.