Вопросы по С/С++ (СИ)
-
HF_Cat
- Первый раз сказал Мяу!
- Сообщения: 37
- Зарегистрирован: Ср июл 28, 2010 20:29:22
- Откуда: Ukraine
Re: Вопросы по С/С++ (СИ)
Есть вопрос по поводу локальных переменных. Освобождается ли ячейка ОЗУ, в которой была такая переменная, после завершения работы функции, в которой она была объявлена? Не разрастается ли объём ОЗУ при использовании большого количества лок. переменных?
И ещё, нужно ли при объявлении глоб. переменных в хедерах писать "typedef" в AVR Studio? Всё работает и без "typedef", но мало ли, решил переспросить.
И ещё, нужно ли при объявлении глоб. переменных в хедерах писать "typedef" в AVR Studio? Всё работает и без "typedef", но мало ли, решил переспросить.
Последний раз редактировалось HF_Cat Чт апр 18, 2013 16:40:59, всего редактировалось 1 раз.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
2 ibiza11
Код: Выделить всё
const screen_item_t *x[4];- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
Если объявить таким образом массив, то для каждого объявления переменной типа screen_t придется объявлять свой массив, причем каждый раз с новым именем. Так не пойдет. И я спрашивал про инициализацию, а не просто объявление.
Ставим плюсы: )
Re: Вопросы по С/С++ (СИ)
чувстивителен ли язык Си к регистру ?
temp и TEMP - это разные переменные ?
temp и TEMP - это разные переменные ?
Tell Me The Truth
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Дак у Вас не получится таким образом проинициализировать, не указав размер массива. Компилятору нужно знать размер типа.И я спрашивал про инициализацию, а не просто объявление
Спойлер
Код: Выделить всё
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 - это разные переменные ?
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Так не пойдет
По другому - никак - компилятор не знает, сколько выделить памяти. Еще в плюсах можно извернуться, в си - никак.
Re: Вопросы по С/С++ (СИ)
HF_Cat писал(а):Есть вопрос по поводу локальных переменных. Освобождается ли ячейка ОЗУ, в которой была такая переменная, после завершения работы функции, в которой она была объявлена? Не разрастается ли объём ОЗУ при использовании большого количества лок. переменных?
Освобождается. Это задача компилятора.
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
по задумке каждая переменная типа screen_t должна содержать свое количество указателей на переменные типа screen_item_t. может тогда как-то отделить определение структуры от определения размера массива? может подскажете как вместо массива указателей использовать указатель на массив указателей?
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
FreshMan писал(а):чувстивителен ли язык Си к регистру ?
temp и TEMP - это разные переменные ?
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
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);
}
//*******************************************************//
Спойлер
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
Спасибо за советы. Попробую применить. 
PS
Сделал вот так:Применение:
Итог: простое создание многомерных меню, с одновременным доступом к каждому свойству всех пунктов меню, находящихся на экране.
- При перемещении вверх или вниз просто инкрементируется или декрементируется CurrItem
- При выборе пункта проверяется действие, которое ассоциировано с пунктом, если оно не равно нулю, то выполняется действие (вызов функции), иначе происходит переход в дочернее меню NEXT_SCREEN (pChildScreen в item_t). Производится это простым присваиванием CurrScreen=NEXT_SCREEN
- При нажатии "Назад", аналогично CurrScreen = PREVIOUS_SCREEN, если он не равен NULL_SCR
Спасибо за помощь!

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: Вопросы по С/С++ (СИ)
Добрый день. Разбираюсь как прикрутить потдержку карт памяти и FAT32 от Чена, возник вопрос по синтаксису функций. Функция disk_ioctl в файле mmc.c(disko.c)
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 выступает уже в роли массива. Как сделать такую конструкцию по правилам Си.
Спойлер
#if _USE_IOCTLDRESULT 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 выступает уже в роли массива. Как сделать такую конструкцию по правилам Си.
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
У Вас в коде лишняя закрывающая скобка.
а вообще в таких случаях используется приведение к типу.
а вообще в таких случаях используется приведение к типу.
Код: Выделить всё
BYTE n, csd[16], *ptr;
ptr = (BYTE *)buff;Ставим плюсы: )
Re: Вопросы по С/С++ (СИ)
Вроде песня на Си льется мелодично, но иногда некоторый диссонанс вызывают варнинги, которые я еще не осознал......
Есть массив с которым работаю в фоне и в прерывании, объявил его как в прерывании обращаюсь к нему так: при этом, на эту строчку вылазит предупреждение Если volatile убрать, то варнинга нет, но обработка не правильно идет, что надо делать по другому, чтобы и волки сыты былы и овцы целы?????
Есть массив
Код: Выделить всё
char DataOutBuf[4]; Код: Выделить всё
volatile char DataOutBuf[4];Код: Выделить всё
char* pDataOutBuf = DataOutBuf;Код: Выделить всё
warning: initialisation discards qualifiers from pointer target type- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
Ух ты... так просто... Варнинг исчез.....
Только вот чето непонятно, какой смысл локальному указателю назначать volatile ?
Только вот чето непонятно, какой смысл локальному указателю назначать volatile ?
- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
Если указатель указывает на объект, который "volatile", то и сам указатель нужно объявлять так же, компилятор же не совсем телепат, тоесть если вы уверены что ошибок в исполнении не будет, то необращайте внимания на варнинг.
«И всё-таки она вертится!»
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
в объявлении не указатель volatile, а переменная, на которую он указывает.
Код: Выделить всё
volatile char* pDataOutBufСтавим плюсы: )
- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
ibiza11 писал(а):не указатель volatile, а переменная, на которую он указывает.
ну я это имел ввиду
«И всё-таки она вертится!»
Re: Вопросы по С/С++ (СИ)
Да нет уж.....Apparatchik писал(а):если вы уверены что ошибок в исполнении не будет, то необращайте внимания на варнинг.
лучше поставлю лишнее слово, чем будет мазолить глаза.....