вы упорно не хотите написать, как именно вам ругается компилятор. Считаете это неважным? Рискну предположить, что в его ругани все описано достаточно исчерпывающе.
все верно, компилятор ругается на неизвестный тип...в том то и парадокс вроде как определил(но не правильно, как ща понимаю) ,передал, а он все равно ругается...
вроде как определил(но не правильно, как ща понимаю) ,передал, а он все равно ругается...
Если этот заголовочник вставлен в начале основного файла, то правильно ругается, потому что функция со структурой компилируется до того как встретится определение этой структуры.
ROMan2947 писал(а):
я так понял тип нужно объявить внешне, чтобы видеть ее в модулях, а struct struct_1 или typedef не фатально думаю....или я ошибаюсь?
Если этот заголовочник будет вставлен в несколько модулей, то фатально. Без typedef будет ругаться на то, что переменная уже определена, с typedef не будет.
ROMan2947 писал(а):
какая роль условной компиляции в данном коде?
Гарантировать что код будет скомпилирован только один раз, даже если он будет вставлен в несколько модулей.
Нет никаких парадоксов - есть три программы - препроцессор, компилятор и линкер. Препроцессор применяется к каждому С-файлу в проекте - вставляет #include, подставляет #define и исполняет остальные #-директивы. Результат его работы передаётся компилятору для превращения в объектный файл с кодом функций и местом под глобальные переменные. Объектные файлы полученные из всех С-модулей проекта [и библиотеки] передаются линкеру для установления связей данных, вызовов функций и создания окончательной программы. Если компилятор ругается на неизвестный тип - значит до данной конкретной строчки определение этого типа ему не встретилось - он работает только с тем текстом, который создан для него препроцессором - ни о других С-файлах ни о H-файлах знаний у него нет. Этот текст можно найти в папке с промежуточными файлами компиляции, иногда его требуется включить в настройках проекта, иногда это выглядит как переключатель "preprocess only" - не пожалейте времени на ознакомление с результатом работы препроцессора и поймёте, что никакой магии там нет - а идёт тупая работа с текстом.
_________________ Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR!
пока буковку в буковку не написал компиляция не шла...в итоге победа! еще понять бы как это работает, было бы вообще самолет) Учить и учить еще этот Си.
если в какой-нибудь книжке про Си прочитаете что-то типа "в Си можно делать так...." - дальше не читайте. начинающему надо читать те книжки, в которых написано "в Си нужно делать так..." после того, как освоите, как НУЖНО, тогда можете читать и делать, как МОЖНО.
в частности, инклюдить Сишные файлы МОЖНО, включать в заголовочные *.h-файлы тело функции МОЖНО, и еще много чего МОЖНО, но именно на этом вы и погорели...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Товарищи добрый день. имеется МК ATmega 128 написал для него простенькую прогу для теста. Сразу же и приведу: 0x15 - адрес PORTC, 0x1B - адрес PORTA по отладчику все в порядке, а когда смотрю осциллографом то выполняется только функция Drrb()! В чём проблема? /* * DC_Voltmetr_Prog.cpp * * Created: 28.02.2018 11:19:19 * Author : LAN_Admin */ #include <avr/io.h> void Prb() { asm("sbi 0x1B,2"); asm("nop"); asm("cbi 0x1B,2"); asm("nop"); }; void Drrb() { asm("sbi 0x15,0"); asm("nop"); asm("cbi 0x15,0"); asm("nop"); } int main(void) { DDRA=0xFF; DDRC=0xFF; /* Replace with your application code */ while (1) { Drrb(); Prb(); }; }
Доброго времени суток. Когда-то на асме был написан кусок кода, собирающий из 4 байт (принятых последовательно по SPI, то есть представляющие собой по сути один 32 битный регистр) состояние нужных кнопок в 1 байт. Потому что в этих 4 байтах не все биты - это значения кнопок, есть много незначащих бит. Всего содержится инфа о 8 кнопках (по 2 кнопки в каждом байте). И вот я с помощью следующего кода собирал их в 1 байт: Осторожно, 8051 асм Спойлер
Код:
mov A, KeyByte+1 ; А теперь склеим все 4 байта в 1 и получим байт с состоянием всех 8 кнопок rl A orl KeyByte,A mov A, KeyByte+2 rl A rl A orl KeyByte,A mov A, KeyByte+3 rl A rl A rl A orl KeyByte,A ; Склейка всех байтов в 1 закончена, теперь у нас в KeyByte состояние всех 8 кнопок
Как это правильнее всего всего сделать на Си: 1. Переписать 1 к 1. 2. Переписать через массив. 3. Переписать через структуру. 4. Загнать все в одну 32 битную переменную еще на этапе приема по SPI, и уже ее ужимать до 8 бит.
Карма: 38
Рейтинг сообщений: 621
Зарегистрирован: Пн апр 06, 2015 11:01:53 Сообщений: 3092 Откуда: москва, уфа
Рейтинг сообщения:0
а словами написать, какие биты используются, для не желающих восстанавливать их по асму? "правильнее" зависит от того, как вы потом обрабатываете кнопки.
0 и 4 бит каждого принятого байта. В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?
0 и 4 бит каждого принятого байта. В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?
0 и 4 бит каждого принятого байта. В итоге в этом байте установленный бит - это нажатая кнопка. Все биты установлены - все кнопки нажаты. Какая разница, как потом его обрабатывать ?
РЕШАЮЩАЯ разница. Архетипичнейший сюжет кстати - когда общественность начинает "умничать" уточнениями "а вообще вы что сделать пытаетесь?" на конкретный вроде-бы вопрос. И соискателю кажется что над ним издеваются и рейтинг зарабатывают. Но дело в том, что первична задача, а не конкретные шаги по её исполнению. У ассемблерщика свои подходцы, у С-шника свои, у плюсиста - свои. Там где первый морочится упаковкой в байт - второй с третьим наложат на принятые данные структуру с битовыми полями и будут пользоваться этими полями напрямую - оставив всё побитное кунг-фу со сдвигами и масками на долю компилятора.
Зарегистрирован: Пт мар 02, 2018 16:31:19 Сообщений: 7
Рейтинг сообщения:0
Всем мяу! Помогите новичку разобраться с синтаксисом си для stm32. Среда разработки Keil, отладочная плата stm32f4discovery. Хочу сделать библиотеку для отображения на дисплее векторных шрифтов, в дальнейшем добавить сглаживание. Столкнулся с проблемой, что как таковых текстовых типов данных нет... А ведь хотел координаты полилиний записывать в текстовом виде:
А ведь хотел координаты полилиний записывать в текстовом виде
я, конечно, понимаю: ARM, 32 бита, много памяти и мегагерц, но храниить шрифт в текстовом виде?! до этого даже в Майкрософте не додумались!
шрифт, как очень активно используемый ресурс, должен быть предельно оптимальным, иначе рендеринг его на экране, да еще и со сглаживанием (вы уверены, что задачу себе по "зубам" выбрали? строку не умеете считать, а антиалиасинг - легко?)
имхо, шрифт должен быть в двоичном виде. Если векторный из отрезков прямых линий (если иначе - сразу TTF загружайте - чего там мелочиться), то в виде обычного массива стреуктур типа такого
Код:
typedef struct{ short int dx; shoet int dy; }vect_t;
typedef struct{ short int cnt; // количество векторов vect_t nodes[]; // массив векторов }symbol_t;
массив векторов описывает на сколько пикселей и в какую сторону смещается "перо", если оба поля структуры равны нулю, это означает, что перо переносится в следующую точку без рисования линии... как-то так...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Зарегистрирован: Пт мар 02, 2018 16:31:19 Сообщений: 7
Рейтинг сообщения:0
Да, текстовый вариант очень плох, это я понимаю. Пришел к нему, т.к. ооочень уж туго дается мне си после delphi... С точки зрения алгоритмизации - задача по зубам, причем исходники wuline сишные есть в интернете, библиотеку для своего дисплея переписал для вывода графики через буфер (благо RAM хватает) + реализация альфа канала, обновления нужного участка экрана... С периферией разобрался благодаря CubeMX. А вот синтаксис языка си ну вообще никак не лезет...
Да, я записываю действительно массив, только не векторов, а координат полилиний, где их нужно разорвать и начать рисовать новую полилинию - ставил символ "|". Прекрасно понимаю, что эта чушь будет и медленно работать и жрать много памяти. Поэтому и решил спросить совета в каком виде хранить массив типа uint16_t чисел, в которых по 4 бита будут записаны координаты отрезка (x1,y1,x2,y2) преобразованных по формуле ( X1 shl 12 ) or ( Y1 shl 8 ) or ( X2 shl 4 ) or Y2 Экономней вижу вариант писать в массив uint8_t пару координат, а разрыв полилинии - заранее определенная (невозможная или неиспользуемая) пара координат...
Ваш вариант возьму за основу, только вместо short int буду использовать uint8_t - всё таки на байт меньше )))
Благодарю, за помощь!!!
Добавлено after 41 minute 59 seconds: Это абзац... я не могу создать массив, структура которого содержит динамический массив...
Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4599 Откуда: Планета Земля
Рейтинг сообщения:0 Медали: 1
Си - не делфи, в нём нет никаких динамический массивов. Есть, конечно, стандартные функции для выделения/удаления памяти в куче, но об этом долго писать. Погуглите...
Зарегистрирован: Пт мар 02, 2018 16:31:19 Сообщений: 7
Рейтинг сообщения:0
Ок. Разбираться со стеком, выделением памяти и т.д. для меня слишком муторно, поэтому возвращаюсь к варианту с типом char *Lines. Текст буду обновлять все равно редко, так что сойдет хранение координат в тексте... Как же все-таки получить char от i-го элемента Lines структуры TFont?
Код:
struct TFont { char *Lines; } Font[255] ;
... Font[48].Lines="010516364541301001|0541";
Font[48].Lines[i] - ругается
в коде программы загоняю примерно 25 строк в Font - все выполняется без ошибок. Теперь бы с этим научиться работать...
Добавлено after 8 minutes 12 seconds: хотяб судя по содержимому, там полная каша...
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения