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

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

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

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

Давайте.
Реклама
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

Я опять с вопросом. МСС18. Прога:
#include <stdio.h>
void main(void) {
char s[]="mcc18"; int i=1; float f=3.14;
printf("s=%s i=%i f=%f", s, i, f);
while(1);
}
А он мне вонинг: type qualifier mismatch in assignment
Но s и i выводит честно, а f не выводит вообще.
Какого рожна ему не хватает?
Реклама
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

illarionovsp писал(а):а f не выводит вообще.
Какого рожна ему не хватает?
http://www.microchip.su/showpost.php?p= ... ostcount=4

http://support2.microchip.com/KBSearch/ ... UJ9A003PQX
"Я не даю готовых решений, я заставляю думать!"(С)
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

Спасибо. Программа:
#include <stdio.h>
void main(void) {
char s[]="mcc18";
printf("s=%s", s);
while(1);
}
А он мне, по прежнему, вонинг: type qualifier mismatch in assignment
s выводит честно.
А зачем мне вонинг? Я из практики знаю, иной вонинг хуже еррора.
ЗЫ. Наконец конкретный ответ на вопрос получил.
Раз враг известен, бороться с ним можно.
Реклама
Эиком - электронные компоненты и радиодетали
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

Достаточно заглянуть в printf.с ...
Вызывайте так...

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

printf((far const rom char *)"s=%s", s);
"Я не даю готовых решений, я заставляю думать!"(С)
Реклама
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

Дайте совет что за косяк,я даже с примера содрал)
выдает ошибку:
parameter #2 of type 'flash unsigned char' is incompatible wiht type 'unsigned char' specified in the function 'f_open' declaration.
параметр№2 тип 'flash unsigned char' невозможен с типом ' unsigned char' спецификация функции 'f_open'

Спойлер#include <stdio.h>
#include <mega48.h>
#include <delay.h>
#include <string.h>
#include <io.h>



#include "integer.h"
#include "diskio.h"
#include "ff.h"



#define SD_DI 3
#define SD_DO 4
#define SD_CLK 5
#define SD_CS 2


BYTE Buff[128];

void main() {

FRESULT f_err_code;
FATFS FATFS_Obj;
FIL fil_obj;

DDRB=0b11101111;



// 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x33;

//????????? SPI
SPCR=0b01010011;
SPSR=1;


disk_initialize(0); // Init drive


printf("mounting FAT ");
f_err_code=f_mount(0,&FATFS_Obj); //
if (f_err_code==0x00) { //
printf("OK\r\n");



f_err_code=f_open(&fil_obj,"lol.txt",FA_READ); //Open newfile for reading
if (f_err_code==0x00) { printf("OK\r\n"};
printf("XREN!!");
f_err_code=f_read(&fil_obj,Buff,128,128) ;

}


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

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

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

Ругается на несовпадение типов в одном из аргументов функции 'f_open'. Попробуйте догадаться в каком :)
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

Я сам понял про несовпадение типов, и видимо это "lol.txt",че делать то?) И чем flash unsigned char отличается от unsigned char
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Странно, что слово flash Вам ни о чём не говорит.
В одном случае строка находится в области программной памяти(flash), в другом случае - в ОЗУ.
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

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

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

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

Частенько примеры сознательно делают с ошибками, дабы хоть чучуть народ мозгами шевелил :)
Если в функцию нужно передавать unsigned char, то и передавайте именно его. Неужели логики не хватает додуматься что необходимо сделать ? :)
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

Про far'ы спасибо. Работает.
Был один вопрос, стало 2:
1 Я слышал, можно в шапке модель установить самую огромную, типа все far'ы, и не думать дальше.
2. Ковырял функцию itoa(int val, char *s, char z), она в mcc18 другая:
itoa(int val, char *s). В инете нашёл. А где бы о библиотеках mcc18 почитать? Пусть на английском.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

«как неудобно вышло»™
Такой крупный специалист по теории правильного писания программ и правильного объяснения новичкам — и вдруг даёт линк на код, который… От которого мне крепко икнулось. Ну, короче, вот код:
Спойлер

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

// Code to demonstrate displaying floats on the USART using printf
// Note, the float is converted to two variables, a part to the
// left of the decimal, and a part to the right of the decimal.
// Unused digits are simply dropped, add the kind of rounding you like.

float fInput         = 344.9876; // Pick a number
long lWhole          = 0;        // Stores digits left of decimal
unsigned long ulPart = 0;        // Stores digits right of decimal

#define MULTIPLIER 100 //(use 1 for no decimals, 10 for 1 place,
                       // 100 for 2 places, etc)

#include<stdio.h>
#include<p18f242.h> // choose your device as needed

void main(void)
{
    // Set up the USART for output (not required, but since printf sends to the USART,
    // it makes the output readable in the output window)
    SPBRG=15;
    TXSTA=0x24;
    RCSTA=0x90;

    //Convert number from float to fixed point for display.
    //The number is converted to two parts.
    lWhole=(long)((float)fInput);
    ulPart=(long)((float)fInput*MULTIPLIER)-lWhole*MULTIPLIER;

    printf((far char *)"The floating point number is: %li.%li\n",lWhole,ulPart);
    while(1); // wait forever
} 
Для тех, кто глядя на этот код не видит, что он неправильный:
СпойлерЭтот код только выглядит как рабочий. Но именно в том виде, в каком есть, на смеси случайных чисел будет для 10% положительных чисел случаев давать очень неправильный результат...
А с отрицательными так и вообще весело. Что с round toward zero, что с round down -- нельзя даже сказать, что результаты неправильные. Это просто не результаты.
Для тех, кто и со сказанным выше не понял, что будет:
СпойлерТам стоит MULTIPLIER 100, т.е. должно быть два знака после запятой.

1) Для числа 344.9875 из кода результат будет напечатан почти правильный, 344.98 (надо бы 344.99, как нормальный printf напечатает по формату %.2f)

2) Для числа 344.0987 будет напечатано 344.9

3) Для числа -344.9875 будет напечатано -344.-98 (для обычного round toward zero)
Для тех, кто не понял, почему так будет:
Спойлер1) Приведение к целочисленному типу отбрасывает дробную часть, для сносного округления надо добавить половину веса отбрасываемого разряда:

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

	lWhole=(long)((float)fInput + 0.005); // для MULTIPLIER = 100
2) Имеющийся код для ulPart оставит 9, по второй части формата %li.%li так и будет напечатано .9. Для множителя 100, т.е. для двух знаков после точки, формат должен быть %li.%02li. Для 1000, т.е. трёх знаков %li.%03li

3) При округлении к нулю, точнее, при приведении к int -- отбрасыванию того, что правее точки, из -344.9876 получится -344. В результате в ulPart, хоть оно и unsigned long, получится двоичный код, соответствующий -98. Поскольку во второй части формата тоже стоит спецификатор преобразования знакового long, printf проинтерпретирует переданное как long int и так и напечатает -344.-98. Было бы там %li.%lu, получился бы ужас в виде -344.4294967198. Надо Part сделать знаковым и перед printf

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

 if (lPart < 0) lPart = -lPart;
Да, кстати, зачем Part сделано long -- непонятно, но это к правильности результата не имеет отношения, только слегка код и время выполнения увеличит.
p.s. Для одного дня это слишком много. Я сегодня днём ещё заглянул в
Спойлердокументацию на ATmega48P, освежить кое-что.
Ойкнул. Полез за свежей (вдруг исправили). В файле за август этого года то же самое. Страница 52:

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

	; Clear WDRF in MCUSR
	in	r16, MCUSR
	andi	r16, (0xff & (0<<WDRF))	;  Это все... «Капец». «Где они такую траву берут». «Остановите Землю, я сойду»
	out	MCUSR, r16
Сечас полезу в подержку жаловаться за перерасход денег на корвалол. Попробую на них списать и микрочиповско-кноледж-бейзяную долю.
p.s. testerplus-а на них нет...
Кстати, что-то я давно его тут не читал. Вслед за neiver-ом на easyelectronics ушел? Или ещё раньше?
Последний раз редактировалось avreal Сб окт 13, 2012 22:53:16, всего редактировалось 1 раз.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

спящий писал(а):Дайте совет что за косяк,я даже с примера содрал)
выдает ошибку:
parameter #2 of type 'flash unsigned char' is incompatible wiht type 'unsigned char' specified in the function 'f_open' declaration.
параметр№2 тип 'flash unsigned char' невозможен с типом ' unsigned char' спецификация функции 'f_open'
Переводите правильно:
параметр №2 с типом 'flash unsigned char' несовместим с типом ' unsigned char' определенный в описании функции 'f_open'.
Таким образом нужно либо подать этой функции что она требует, либо пробовать привести переменную к нужному типу

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

f_err_code=f_open(&fil_obj,(unsigned char)"lol.txt",FA_READ); //Open newfile for reading       
Хотя нет, первый же поиск функции показывает:

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

FRESULT f_open (
  FIL* FileObject,       /* Pointer to the blank file object structure */
  const TCHAR* FileName, /* Pointer to the file name */
  BYTE ModeFlags         /* Mode flags */
);
 
Смотрим на второй параметр в данном описании получается нужно вообще отправлять указатель.
Какой тип нужен в вашем описании функции мы можем только догадаться по ошибкам. :dont_know: смотрите как пользоваться функцией.
PS Может вы списывая ошибку вручную судя по
wiht type
пропустили звездочку??
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

avreal писал(а):Такой крупный специалист по теории правильного писания программ и правильного объяснения новичкам — и вдруг даёт линк на код, который… От которого мне крепко икнулось.
Это ты про рекомендации ARV двухлетней давности,
http://radiokot.ru/forum/viewtopic.php?p=400128#p400128
которые ты не смог осуществить в своей теме???
http://radiokot.ru/forum/viewtopic.php?f=20&t=77142
:))) :)))
Продолжай икать... :)))
p.s. testerplus-а на них нет...
Кстати, что-то я давно его тут не читал. Вслед за neiver-ом на easyelectronics ушел? Или ещё раньше?
Виктор (testerplus) ушёл из эмбэдда... Временно, или насовсем, не знаю...
"Я не даю готовых решений, я заставляю думать!"(С)
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

avreal писал(а): Для тех, кто глядя на этот код не видит, что он неправильный:
Для тех, кто в танке и в водолазном костюме... :)))
формат double C18 не поддерживает.

что самое грустное - в printf он не поддерживает и float
"Я не даю готовых решений, я заставляю думать!"(С)
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

Коллеги, дорогие. Я в программировании давно. Люди так долго не живут. Но я не профессионал. Программирую по необходимости. С mcc18 не знаком.
Как плавующее к двум целым привести, за 10 мин написал. Даже точно запись такую придумал:
if(f<0) l=-l;
Вот с округлением лоханулся. Младшие спокойно округляются, а вот когда больше 0,9 (0.99, 0.999), просмотрел. Надоть к целой единицу присуммировать.
Хотел такую функцию написать:
char *ftos(float val)
не получилось пока. Получилась:
void ftos(char *s, float val)
что мне не нравится. Хотел так на гипертерминал плавующую посылать:
printf((far const rom char*)"f=%s", ftos(val));
Никогда строки в названиях функций не использовал. Присоветуйте правду
ЗЫ. (far char*) на работает. А (far const rom char*) работает отлично. Вот.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Краткое содержание предыдущей серии:

В микрочиповском примере с положительным числами была одна мелочь с отсутствием округления, впрочем, об этом было написано на сайте.
И большая плюха с нулями после десятичной точки, приводящая к их убиранию. Напрмер, будет напечатано 3.9 вместо 3.09.
С отрицательными числами было всё настолько печально, что об округлениях и говорить нечего. Если уж правят в своей «базе знаний» отсутствие в своей библиотеке поддержки всех возможностей функции стандартной библиотеки С, то могли бы это сделать лучше.

Вот подправленный микрочиповский код (все PIC-специфические штучки выброшены, частично оставлена только их любовь к глобальным переменным).
Спойлер

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

#include<stdio.h>

// Может определяться снаружи в каком-то config.h
// или в ключах компилятора в опциях проекта или Makefile
#define MULTIPLIER 100

// Настраиваем нужную часть форматной строки
#if   MULTIPLIER == 10
# define PART_FMT_DIGITS ""
#elif MULTIPLIER == 100
# define PART_FMT_DIGITS "02"
#elif MULTIPLIER == 1000
# define PART_FMT_DIGITS "03"
#else
# error "Floating point printing: invalid MULTIPLIER value"
#endif

float fInput  = -344.09876;
long lWhole, lPart;

void main(void)
{
        // Нам нужно округление к ближайшему, а в C при приведении float->int
        // производится к нулю, т.е. отбрасывание. Поэтому для положительных
        // добавляем 0.5 (с учетом множителя), для отрицательных вычитаем.
        if (fInput >= 0) fInput += 0.5f/MULTIPLIER;
        else             fInput -= 0.5f/MULTIPLIER;
        lWhole = fInput;
        lPart  = MULTIPLIER * (fInput - lWhole);
        if (lPart < 0) lPart = -lPart;
        printf( "%li.%" PART_FMT_DIGITS "li\n", lWhole, lPart);
} 
В принципе, можно почти сразу перейти к целым, если у процессора есть операция целочисленного деления, но нет операции плавающего умножения, то так может быть компактнее и/или быстрее. Если целочисленного деления нет, то может оказаться хуже, так как «soft» плавающее умножение быстрее «soft» целочисленного деления.
Перевести сразу в целое с умножением на вплоть до миллиона нет проблем, так как в long (на 8-16-32-битниках) сидят числа до грубо ±2e9, а во float до ±3e38, так что запас разрядности есть.
Спойлер

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

#include<stdio.h>

#define MULTIPLIER 100

#if   MULTIPLIER == 10
# define PART_FMT_DIGITS ""
#elif MULTIPLIER == 100
# define PART_FMT_DIGITS "02"
#elif MULTIPLIER == 1000
# define PART_FMT_DIGITS "03"
#else
# error "Floating point printing: invalid MULTIPLIER value"
#endif

float fInput  = -344.09876;
long lWhole, lPart;

void main(void)
{
        long temp = fInput * (10*MULTIPLIER); // Лишнее 10 -- запас на округление.
        if (temp > 0) temp += 5; // Это 0.5 с учётом лишнего 10 выше
        else          temp -= 5;
        temp /= 10;              // Убираем лишнее 10, завершая округление
        lWhole = temp / MULTIPLIER;
        lPart  = temp - lWhole * MULTIPLIER;
        if (lPart < 0) lPart = -lPart;
        printf( "%li.%" PART_FMT_DIGITS "li\n", lWhole, lPart);
} 
Последний раз редактировалось avreal Вс окт 14, 2012 11:21:25, всего редактировалось 1 раз.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

illarionovsp писал(а):Но я не профессионал.
Да я, вообще говоря, тоже.
Профессионалы дают линки на профессиональный код, который проверен с одним числом +344.9876 и с этим числом работает профессионально.
illarionovsp писал(а):Вот с округлением...
Приведенный мной код округляет достаточно нормально. По крайней мере так же, как нормальный формат %f (он тоже не делает размазывания округления последней цифры 5 в разные стороны в зависимости от чётности предыдущей цифры :))) )
illarionovsp писал(а):Хотел такую функцию написать:
char *ftos(float val)
Такая функция должна

А) Выделять память под строку по malloc()/free() -- но её некому будет удалять в записи printf("%s", ftos(val))
Да и вообще динамическое выделение памяти без особой нужды лучше не применать.

или

Б) Иметь внутри себя статический буфер, который и возвращать.

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

char *ftos(float val)
{
    static char buf[20];
    // преобразовываем
    return buf;
} 
Но такую функцию нельзя дважды в один printf вставить:

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

    printf("Val = %s +- %s\n", ftos(average), ftos(rms)); // Так не выйдет! Буфер-то один    
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

avreal писал(а):частично оставлена только их любовь к глобальным переменным
Песши ысчо, сказочник-непрофессионал!!! :))) :)))
Доказывай, что ТЫ умнее Микрочипа, повесели всех!!! :)))
"Я не даю готовых решений, я заставляю думать!"(С)
Ответить

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