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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Pink-Pank
Опытный кот
Сообщения: 721
Зарегистрирован: Ср июн 11, 2014 09:43:13
Откуда: США
Контактная информация:

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

Сообщение Pink-Pank »

ругается потому, что Вы объявляете массив целых чисел, а запихиваете туда указатели.
А в Code Vision, если не ошибаюсь, const = flash
Fucking static initialization order fiasco
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

Это я понимаю, что имеется несоответствие типов данных, оттого и ругается.
Просто я не могу понять, как привести тип функции void к константному значению, понятному для flash uint16_t.

Как я рассуждаю:
(1)Функция func1() находится во флеш по физическому 16-битному адресу N.
(2)Этот адрес мы заносим(точнее заносит компилятор) в ячейку flash массива func_adress[].
(3)Далее в самой программе в переменную uint16_t adr читается адрес из массива adr = func_adress[x];
(4)Приводитя к типу указателя на функцию:
void (*p_func)(void);
p_func = (void(*)(void))adr;
(5)Переход:
p_func();

Как раз на этапе (2) у меня проблема.

ЗЫ. В codevision const=flash если включить соответсвующую опцию компилятора. А так кладет в RAM.
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

для сложных типов данных я всегда применяю описание собственных типов, тогда получается гораздо проще описать именно то, что желаешь, и не запутаться

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

typedef void (*menu_finc_ptr)(void); // определили тип днных "указатель на функцию"

flash menu_func_ptr func_array[] = {func1, func2, func3, ...}; // определили массив во flash этих самых указателей
потом, кстати, и приведение типов легче делать - не многоэтажная запись, а одноэтажная :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

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

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

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

Просто я не могу понять, как привести тип функции void к константному значению, понятному для flash uint16_t
А для чего все эти извращения-приведения ? Почему сразу не сделать массив указателей ?
Реклама
Эиком - электронные компоненты и радиодетали
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

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

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

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

uk8amk писал(а):Указатель - есть по сути переменная.
Я имел ввиду тип массива - указатель на функцию (void (*ptr)(void)), а не целое (uint16_t). Для чего все эти лишние приведения типов :dont_know:
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

Ха!
То, что описал ARV разместилось в Flash, как раз что надо, спасибо.

Только не могу понять, почему объявление
flash void(*mnu_func_ptr[11])(void) ={ // menu functions pointer
menu_main,
menu_time,
menu_date,
у меня вызывало ошибку Storage modifier not allowed in this context.
Вроде аналогичное объявление.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

С предыдущим вопросом кое-как разобрался. Теперь возник следующий и тоже про указатели.
Значит есть в моей менюшке строки:

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

flash uint8_t str_time[]  ="ВРЕМЯ";
flash uint8_t str_date[]  ="ДАТА";
и т.д.
Если я создам массив указателей

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

flash uint8_t *mnu_main_str_ptr[]={ str_time, str_date, ...
То они(указатели) опять попадают в SRAM, строк много, памяти жалко.
Тогда я делаю такой массив:

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

flash uint16_t mnu_ptr[] = { // массив адресов строк меню во флеш
(uint16_t) &str_time, // вычисление адреса строки и приведение к 16-бит 
(uint16_t) &str_date,
... };
Использование:

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

copymem_load_fstr( (flash uint8_t*)mnu_ptr[mnu_item_index], str_buf_RAM ); //загрузить flash строку в RAM
Прототип функции копирования:

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

copymem_load_fstr( flash uint8_t *str, uint8_t *dest ); // *источник flash, *буфер RAM 
В принципе всё нормально работает, но выглядит как-то монстрообразно.
Можно ли привести это в нормальный, человеческий вид?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Во-первых, зачем постоянно преобразовывать указатель к uint16_t и обратно? Глупо же.
Во-вторых, сделайте, как в прошлый раз через новые типы. Только не забудьте, что у вас указатель во флэш на символ во флэш...
В-третьих, зачем копировать строку в ОЗУ? Не проще ли выводить её сразу из флэш?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

(1) Так иначе компилятор матерится.
Или вы о чём то другом. Если да то можно пример?
(3) Там небольшая прослойка API, принимает строку из ОЗУ. Дело в том, что показ строк меню - это далеко не самая главная задача устройства.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

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

typedef void(*func_ptr)(void);

static void func1(void){
}

static void func2(void){
}

flash func_ptr func_array[] = {func1, func2};

func_ptr exec;

exec = func_array[1];
exec();
разве в таком коде будет ругня компилятора? в нем нет никаких преобразований типов.

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

flash char str1[] = "привет!"
flash char str2[] = "пока!";

typedef flash char * flash_str;

flash flash_str str_array[] = {str1, str2};

char ram_str[20];

copymem_load_fstr(str_array[1], ram_str);
а в этом коде? тоже без всяких преобразований...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

Так работает нормально, спасибо.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

если поддержка flash компилятром сделана качественно, то промежуточные переменные могут вообще не понадобиться:

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

typedef void(*func_ptr)(void);

flash func_ptr func_array[] = {func1, func2};

func_array[1](); // просто выполняем функцию из массива
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

Если распутать данное определение, то получается

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

flash flash char* str_array[] = {str1, str2};
Я правильно понял?
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Лично я не настолько влюблен в Си, чтобы колупаться в его ребусах. Я делаю, как мне проще, а как оно разворачивается, мне не интересно.

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

Мой уютный бложик... заходите!
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

И тем не немее, вы написали код, который корректно работает.

Мне же пока до конца не ясны некоторые нюансы вроде этого. Книга K&R и ряд статей интернета не дали ответа по данному направлению. Может посоветуете что почитать, чтобы окончательно разобраться в указателе на указатели и в каких случаях в какую память они помещаются.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

Написать корректный код мне помог здравый смысл. K&R я читал бегло и понял, что там слишком много лишнего написано. В частности там описан миллион способов сделать непонятными простые вещи...например, записать в "развернутом" виде указатель на функцию, возвращающую указатель на структуру и имеющую в качестве параметра указатель на функцию с тремя параметрами и возвратом указателя...

Хотя гуру это пишут и читают походя, меня это не привлекает, и я делаю то же самое простыми способами.

Нужно, чтобы стандартный тип попал во флэш? Вводу новый тип. Надо на этот тип указатель? Снова новый тип. Надо этот указатель занести снова во флэш? Опять новый тип. Вот и все: на каждом этапе все просто и понятно, а в итоге - отличный и лёгкий код.

Я никогда не объявляю переменные-структуры без предварительного определения соответствующего типа-структуры... и так во всем: если можно написать проще - я так и делаю.

Си разрешает слишком многое, но,имхо, можно не означает нужно...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

кто-либо осведомлен, почему элементы массива нумеруются с нуля а не с единицы ? :)
Tell Me The Truth
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

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

Сообщение WiseLord »

Потому что это естественно. 0b00000000 - минимальное число, которое можно представить в двоичном виде. И как-то логично, чтобы считать 0b00000000 нулём, а не единицей.

(естественно, 0b10000000 (char), 0b10000000 00000000 (int), 0b10000000 00000000 00000000 00000000 (long) - эти минимальные в своих границах (байт, два байта, четыре байта) числа как бы много меньше нуля, но это в некоторой мере искусственная условность).

А с единицы массивы нумеруются в каком-нибудь Паскале, т.к. в большей мере этот язык для обучения программированию, нежели что-то действительно серьёзное. Ну вроде как малых детей учат считать с единицы, т.к. ноль - это более недоступная их пониманию категория.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18673
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

WiseLord писал(а):А с единицы массивы нумеруются в каком-нибудь Паскале, т.к. в большей мере этот язык для обучения программированию, нежели что-то действительно серьёзное. Ну вроде как малых детей учат считать с единицы, т.к. ноль - это более недоступная их пониманию категория.
в паскале массивы индексируются в пределах, какие заданы программистом - хоть с нуля, хоть с 312, хоть с -257 - в зависимости от того, как более удобно описать имитируемые объекты реального мира. в реальном мире никто никогда нигде не считает, например, автомобили с нуля :)))
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Ответить

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