Страница 150 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 16:36:48
HF_Cat
Есть вопрос по поводу локальных переменных. Освобождается ли ячейка ОЗУ, в которой была такая переменная, после завершения работы функции, в которой она была объявлена? Не разрастается ли объём ОЗУ при использовании большого количества лок. переменных?
И ещё, нужно ли при объявлении глоб. переменных в хедерах писать "typedef" в AVR Studio? Всё работает и без "typedef", но мало ли, решил переспросить.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 16:39:19
Аlex
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 18:02:56
ibiza11
Если объявить таким образом массив, то для каждого объявления переменной типа screen_t придется объявлять свой массив, причем каждый раз с новым именем. Так не пойдет. И я спрашивал про инициализацию, а не просто объявление.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 18:08:55
FreshMan
чувстивителен ли язык Си к регистру ?
temp и TEMP - это разные переменные ?
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 18:13:30
Аlex
И я спрашивал про инициализацию, а не просто объявление
Дак у Вас не получится таким образом проинициализировать, не указав размер массива. Компилятору нужно знать размер типа.
Спойлер
Код: Выделить всё
typedef struct{
const uint8_t *a;
const uint8_t b;
const void *c;
} screen_item_t;
typedef struct{
const uint8_t *a;
const void *b;
const uint8_t c;
const screen_item_t *x[4];
} screen_t;
const uint8_t a,b;
screen_item_t Item0 = {&a, 0, &b};
screen_item_t Item1 = {&a, 0, &b};
screen_item_t Item2 = {&a, 0, &b};
screen_item_t Item3 = {&a, 0, &b};
screen_t Screen0 = { &a,
&b,
4,
{&Item0, &Item1, &Item2, &Item3},
};
temp и TEMP - это разные переменные ?
Разные.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 18:16:36
urry
Так не пойдет
По другому - никак - компилятор не знает, сколько выделить памяти. Еще в плюсах можно извернуться, в си - никак.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 19:40:59
ploop
HF_Cat писал(а):Есть вопрос по поводу локальных переменных. Освобождается ли ячейка ОЗУ, в которой была такая переменная, после завершения работы функции, в которой она была объявлена? Не разрастается ли объём ОЗУ при использовании большого количества лок. переменных?
Освобождается. Это задача компилятора.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 21:13:21
ibiza11
по задумке каждая переменная типа screen_t должна содержать свое количество указателей на переменные типа screen_item_t. может тогда как-то отделить определение структуры от определения размера массива? может подскажете как вместо массива указателей использовать указатель на массив указателей?
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 21:42:26
vitalik_1984
FreshMan писал(а):чувстивителен ли язык Си к регистру ?
temp и TEMP - это разные переменные ?

Пропиши, скомпилируй и
узнаешь. Такие мелочи еще в начале книжки по Си написано, даже если и не написано можно легко проверить самому.
Re: Вопросы по С/С++ (СИ)
Добавлено: Чт апр 18, 2013 22:23:40
Аlex
ibiza11 писал(а):по задумке каждая переменная типа screen_t должна содержать свое количество указателей на переменные типа screen_item_t. может тогда как-то отделить определение структуры от определения размера массива? может подскажете как вместо массива указателей использовать указатель на массив указателей?
Можно хранить не массив указателей, а указатель на первый элемент и размер.
Спойлер
Код: Выделить всё
typedef struct{
uint8_t *a;
uint8_t b;
void *c;
}screen_item_t;
typedef struct{
screen_item_t *p;
uint8_t size;
}screen_t;
uint8_t a, b, c, d, e, f, g, h;
screen_item_t Items[] ={
{&a, 0, &b},
{&c, 0, &d},
{&e, 0, &f},
{&g, 0, &h},
};
screen_t Screen0 = {
Items,
sizeof(Items)/sizeof(Items[0])
};
//*******************************************************//
void main (void){
uint8_t i;
screen_item_t *p_scr;
for(i=0; i<Screen0.size; i++){ // Обращаемся ко всем элементам Items[]
p_scr=(Screen0.p)+i;
*(uint8_t*)(p_scr->a)=i+1; // Через указатели, находящиеся в Items
*(uint8_t*)(p_scr->c)=i+11; // меняем значения переменных a...h
}
while(1);
}
//*******************************************************//
Спойлер
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт апр 19, 2013 08:24:33
ibiza11
Спасибо за советы. Попробую применить.
PS
Сделал вот так:
Спойлер
Код: Выделить всё
#define com1(a,b) a##b
#define com(a,b) com1(a,b)
typedef struct{ /* Тип "Пункт меню" */
const uint8_t *pText; /* Текст пункта */
const action_t Action; /* Код действия, выполняемого при нажатии ОК на этом пункте меню*/
const void *pChildScreen; /* Указатель на следующий "Экран меню" при нажатии ОК*/
} item_t;
typedef struct{ /* Тип "Экран меню" */
const uint8_t *pHeader; /* Заголовок экрана */
const void *pParentScreen; /* Указатель на предыдущий "Экран меню" при нажатии "Назад" */
const uint8_t ItemsOnScreen; /* Кол-во элементов "Пункт меню" на экране */
const item_t **pItemsArray; /* Указатель на указатель на первый элемент массива */
} screen_t;
/* Определение нового пункта меню */
#define NEW_ITEM(Name, Text, Action, Child) \
extern screen_t Child;
item_t Name = {(const uint8_t*)&Text, Action, &Child}
/* Определение нового эрана меню */
#define NEW_SCR(Name, Header, Parent, Items) \
extern screen_t Parent;
screen_t Name = { (const uint8_t *)&Header,
&Parent,
sizeof(Items)/sizeof(com(Items,[0])),
Items
}
/* Определение пустого указателя на экран */
#define NULL_SCR Null_Screen
screen_t Null_Screen = {(const uint8_t *)0, (const void*)0, (const uint8_t)0, (const item_t **)0};
NEW_ITEM(Item0, "First item", 0, NULL_SCR); /* Объявления новых пунктов меню */
NEW_ITEM(Item1, "Second item", 0, NULL_SCR);
NEW_ITEM(Item2, "Third item", 0, NULL_SCR);
NEW_ITEM(Item3, "Fourth item", 0, NULL_SCR);
item_t * Screen0Items[] = {&Item0, &Item1, &Item2, &Item3}; /* Объявление массива пунктов меню */
NEW_SCR(Screen0, "First screen", NULL_SCR, Screen0Items); /* Объявление нового экрана меню */
static screen_t * CurrScreen; /* текущий экран и номер активного пункта меню */
static uint8_t CurrItem;
Применение:
Спойлер
#define ITEM_TEXT(ITEM_NUMBER) (uint8_t*)((CurrScreen->pItemsArray)[ITEM_NUMBER])->pText
// Получение текста любого пункта меню
#define ITEM_ACTION(ITEM_NUMBER) (action_t)((CurrScreen->pItemsArray)[ITEM_NUMBER])->Action
// Получение выполняемого действия любого пункта меню
#define NEXT_SCREEN (screen_t*)((CurrScreen->pItemsArray)[CurrItem])->pChildScreen
// Получение указателя на следующий экран
#define PREVIOUS_SCREEN (screen_t*)CurrScreen->pParentScreen
// Получение указателя на предыдущий экран
#define CUR_HEADER (uint8_t*)CurrScreen->pHeader
// Получение заголовка текущего экрана
#define ITEMS_QUANTITY (uint8_t)CurrScreen->ItemsOnScreen
// Получение количества пунктов текущего экрана
Итог: простое создание многомерных меню, с одновременным доступом к каждому свойству всех пунктов меню, находящихся на экране.
- При перемещении вверх или вниз просто инкрементируется или декрементируется
CurrItem
- При выборе пункта проверяется действие, которое ассоциировано с пунктом, если оно не равно нулю, то выполняется действие (вызов функции), иначе происходит переход в дочернее меню NEXT_SCREEN (pChildScreen в item_t). Производится это простым присваиванием CurrScreen=NEXT_SCREEN
- При нажатии "Назад", аналогично CurrScreen = PREVIOUS_SCREEN, если он не равен NULL_SCR
Спасибо за помощь!

Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 15:49:11
Real lev
Добрый день. Разбираюсь как прикрутить потдержку карт памяти и FAT32 от Чена, возник вопрос по синтаксису функций. Функция disk_ioctl в файле mmc.c(disko.c)
Спойлер
#if _USE_IOCTL
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
BYTE n, csd[16], *ptr = buff;
DWORD *dp, st, ed, csize;
if (pdrv) return RES_PARERR;
res = RES_ERROR;
if (cmd == CTRL_POWER) {
switch (ptr[0]) {
case 0: /* Sub control code (POWER_OFF) */
power_off(); /* Power off */
res = RES_OK;
break;
case 1: /* Sub control code (POWER_GET) */
ptr[1] = (BYTE)power_status();
res = RES_OK;
break;
default :
res = RES_PARERR;
}
}
......
}
return res;
}
#endif
указатель ptr типа BYTE(unsigned char) принимает значение указателя на воид buff. Компилятор от такой операции в шоке выдает ошибку. далее в функции case ptr выступает уже в роли массива. Как сделать такую конструкцию по правилам Си.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 19:24:04
ibiza11
У Вас в коде лишняя закрывающая скобка.
а вообще в таких случаях используется приведение к типу.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 21:29:04
shads
Вроде песня на Си льется мелодично, но иногда некоторый диссонанс вызывают варнинги, которые я еще не осознал......
Есть массив
с которым работаю в фоне и в прерывании, объявил его как
в прерывании обращаюсь к нему так:
при этом, на эту строчку вылазит предупреждение
Код: Выделить всё
warning: initialisation discards qualifiers from pointer target type
Если volatile убрать, то варнинга нет, но обработка не правильно идет, что надо делать по другому, чтобы и волки сыты былы и овцы целы?????
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 21:42:30
Apparatchik
указатель тоже нужно объявить как volatile.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 22:27:04
shads
Ух ты... так просто... Варнинг исчез.....
Только вот чето непонятно, какой смысл локальному указателю назначать volatile ?
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 22:29:41
Apparatchik
Если указатель указывает на объект, который "volatile", то и сам указатель нужно объявлять так же, компилятор же не совсем телепат, тоесть если вы уверены что ошибок в исполнении не будет, то необращайте внимания на варнинг.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 22:29:52
ibiza11
в объявлении
не указатель volatile, а переменная, на которую он указывает.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 22:43:03
Apparatchik
ibiza11 писал(а):не указатель volatile, а переменная, на которую он указывает.
ну я это имел ввиду

выразился неправильно

Re: Вопросы по С/С++ (СИ)
Добавлено: Пн апр 22, 2013 22:45:49
shads
Apparatchik писал(а):если вы уверены что ошибок в исполнении не будет, то необращайте внимания на варнинг.
Да нет уж.....
лучше поставлю лишнее слово, чем будет мазолить глаза.....