Вопросы по С/С++ (СИ)
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Давайте.
- Реклама
-
illarionovsp
- Прорезались зубы
- Сообщения: 234
- Зарегистрирован: Ср апр 29, 2009 22:22:13
- Откуда: СПб
Re: Вопросы по С/С++ (СИ)
Я опять с вопросом. МСС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 не выводит вообще.
Какого рожна ему не хватает?
#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 не выводит вообще.
Какого рожна ему не хватает?
Re: Вопросы по С/С++ (СИ)
http://www.microchip.su/showpost.php?p= ... ostcount=4illarionovsp писал(а):а f не выводит вообще.
Какого рожна ему не хватает?
http://support2.microchip.com/KBSearch/ ... UJ9A003PQX
"Я не даю готовых решений, я заставляю думать!"(С)
-
illarionovsp
- Прорезались зубы
- Сообщения: 234
- Зарегистрирован: Ср апр 29, 2009 22:22:13
- Откуда: СПб
Re: Вопросы по С/С++ (СИ)
Спасибо. Программа:
#include <stdio.h>
void main(void) {
char s[]="mcc18";
printf("s=%s", s);
while(1);
}
А он мне, по прежнему, вонинг: type qualifier mismatch in assignment
s выводит честно.
А зачем мне вонинг? Я из практики знаю, иной вонинг хуже еррора.
ЗЫ. Наконец конкретный ответ на вопрос получил.
Раз враг известен, бороться с ним можно.
#include <stdio.h>
void main(void) {
char s[]="mcc18";
printf("s=%s", s);
while(1);
}
А он мне, по прежнему, вонинг: type qualifier mismatch in assignment
s выводит честно.
А зачем мне вонинг? Я из практики знаю, иной вонинг хуже еррора.
ЗЫ. Наконец конкретный ответ на вопрос получил.
Раз враг известен, бороться с ним можно.
Re: Вопросы по С/С++ (СИ)
Достаточно заглянуть в printf.с ...
Вызывайте так...
Вызывайте так...
Код: Выделить всё
printf((far const rom char *)"s=%s", s);
"Я не даю готовых решений, я заставляю думать!"(С)
- Реклама
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 <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) ;
}
}
выдает ошибку:
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: Вопросы по С/С++ (СИ)
Ругается на несовпадение типов в одном из аргументов функции 'f_open'. Попробуйте догадаться в каком 
Re: Вопросы по С/С++ (СИ)
Я сам понял про несовпадение типов, и видимо это "lol.txt",че делать то?) И чем flash unsigned char отличается от unsigned char
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Странно, что слово flash Вам ни о чём не говорит.
В одном случае строка находится в области программной памяти(flash), в другом случае - в ОЗУ.
В одном случае строка находится в области программной памяти(flash), в другом случае - в ОЗУ.
Re: Вопросы по С/С++ (СИ)
Так как исправить что неправильно ,может косяк в Коде висион? ведь я с рабочего примера то взял.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Частенько примеры сознательно делают с ошибками, дабы хоть чучуть народ мозгами шевелил
Если в функцию нужно передавать unsigned char, то и передавайте именно его. Неужели логики не хватает додуматься что необходимо сделать ?
Если в функцию нужно передавать unsigned char, то и передавайте именно его. Неужели логики не хватает додуматься что необходимо сделать ?
-
illarionovsp
- Прорезались зубы
- Сообщения: 234
- Зарегистрирован: Ср апр 29, 2009 22:22:13
- Откуда: СПб
Re: Вопросы по С/С++ (СИ)
Про far'ы спасибо. Работает.
Был один вопрос, стало 2:
1 Я слышал, можно в шапке модель установить самую огромную, типа все far'ы, и не думать дальше.
2. Ковырял функцию itoa(int val, char *s, char z), она в mcc18 другая:
itoa(int val, char *s). В инете нашёл. А где бы о библиотеках mcc18 почитать? Пусть на английском.
Был один вопрос, стало 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: Вопросы по С/С++ (СИ)
«как неудобно вышло»™
Такой крупный специалист по теории правильного писания программ и правильного объяснения новичкам — и вдруг даёт линк на код, который… От которого мне крепко икнулось. Ну, короче, вот код:
Спойлер
Код: Выделить всё
// 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 = 1003) При округлении к нулю, точнее, при приведении к 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;Спойлер
документацию на ATmega48P, освежить кое-что.Ойкнул. Полез за свежей (вдруг исправили). В файле за август этого года то же самое. Страница 52:
Код: Выделить всё
; Clear WDRF in MCUSR
in r16, MCUSR
andi r16, (0xff & (0<<WDRF)) ; Это все... «Капец». «Где они такую траву берут». «Остановите Землю, я сойду»
out MCUSR, r16Кстати, что-то я давно его тут не читал. Вслед за neiver-ом на easyelectronics ушел? Или ещё раньше?
Последний раз редактировалось avreal Сб окт 13, 2012 22:53:16, всего редактировалось 1 раз.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
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'
параметр №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 */
);
Какой тип нужен в вашем описании функции мы можем только догадаться по ошибкам.
PS Может вы списывая ошибку вручную судя по
пропустили звездочку??wiht type
Re: Вопросы по С/С++ (СИ)
Это ты про рекомендации ARV двухлетней давности,avreal писал(а):Такой крупный специалист по теории правильного писания программ и правильного объяснения новичкам — и вдруг даёт линк на код, который… От которого мне крепко икнулось.
http://radiokot.ru/forum/viewtopic.php?p=400128#p400128
которые ты не смог осуществить в своей теме???
http://radiokot.ru/forum/viewtopic.php?f=20&t=77142
Продолжай икать...
Виктор (testerplus) ушёл из эмбэдда... Временно, или насовсем, не знаю...p.s. testerplus-а на них нет...
Кстати, что-то я давно его тут не читал. Вслед за neiver-ом на easyelectronics ушел? Или ещё раньше?
"Я не даю готовых решений, я заставляю думать!"(С)
Re: Вопросы по С/С++ (СИ)
Для тех, кто в танке и в водолазном костюме...avreal писал(а): Для тех, кто глядя на этот код не видит, что он неправильный:
формат double C18 не поддерживает.
что самое грустное - в printf он не поддерживает и float
"Я не даю готовых решений, я заставляю думать!"(С)
-
illarionovsp
- Прорезались зубы
- Сообщения: 234
- Зарегистрирован: Ср апр 29, 2009 22:22:13
- Откуда: СПб
Re: Вопросы по С/С++ (СИ)
Коллеги, дорогие. Я в программировании давно. Люди так долго не живут. Но я не профессионал. Программирую по необходимости. С 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*) работает отлично. Вот.
Как плавующее к двум целым привести, за 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: Вопросы по С/С++ (СИ)
Краткое содержание предыдущей серии:
В микрочиповском примере с положительным числами была одна мелочь с отсутствием округления, впрочем, об этом было написано на сайте.
И большая плюха с нулями после десятичной точки, приводящая к их убиранию. Напрмер, будет напечатано 3.9 вместо 3.09.
С отрицательными числами было всё настолько печально, что об округлениях и говорить нечего. Если уж правят в своей «базе знаний» отсутствие в своей библиотеке поддержки всех возможностей функции стандартной библиотеки С, то могли бы это сделать лучше.
Вот подправленный микрочиповский код (все PIC-специфические штучки выброшены, частично оставлена только их любовь к глобальным переменным).
В принципе, можно почти сразу перейти к целым, если у процессора есть операция целочисленного деления, но нет операции плавающего умножения, то так может быть компактнее и/или быстрее. Если целочисленного деления нет, то может оказаться хуже, так как «soft» плавающее умножение быстрее «soft» целочисленного деления.
Перевести сразу в целое с умножением на вплоть до миллиона нет проблем, так как в long (на 8-16-32-битниках) сидят числа до грубо ±2e9, а во float до ±3e38, так что запас разрядности есть.
В микрочиповском примере с положительным числами была одна мелочь с отсутствием округления, впрочем, об этом было написано на сайте.
И большая плюха с нулями после десятичной точки, приводящая к их убиранию. Напрмер, будет напечатано 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);
} Перевести сразу в целое с умножением на вплоть до миллиона нет проблем, так как в 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: Вопросы по С/С++ (СИ)
Да я, вообще говоря, тоже.illarionovsp писал(а):Но я не профессионал.
Профессионалы дают линки на профессиональный код, который проверен с одним числом +344.9876 и с этим числом работает профессионально.
Приведенный мной код округляет достаточно нормально. По крайней мере так же, как нормальный формат %f (он тоже не делает размазывания округления последней цифры 5 в разные стороны в зависимости от чётности предыдущей цифрыillarionovsp писал(а):Вот с округлением...
Такая функция должнаillarionovsp писал(а):Хотел такую функцию написать:
char *ftos(float val)
А) Выделять память под строку по malloc()/free() -- но её некому будет удалять в записи printf("%s", ftos(val))
Да и вообще динамическое выделение памяти без особой нужды лучше не применать.
или
Б) Иметь внутри себя статический буфер, который и возвращать.
Код: Выделить всё
char *ftos(float val)
{
static char buf[20];
// преобразовываем
return buf;
} Код: Выделить всё
printf("Val = %s +- %s\n", ftos(average), ftos(rms)); // Так не выйдет! Буфер-то один Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Re: Вопросы по С/С++ (СИ)
Песши ысчо, сказочник-непрофессионал!!!avreal писал(а):частично оставлена только их любовь к глобальным переменным
Доказывай, что ТЫ умнее Микрочипа, повесели всех!!!
"Я не даю готовых решений, я заставляю думать!"(С)


