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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
HF_Cat
Первый раз сказал Мяу!
Сообщения: 37
Зарегистрирован: Ср июл 28, 2010 20:29:22
Откуда: Ukraine

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

Сообщение HF_Cat »

Есть вопрос по поводу локальных переменных. Освобождается ли ячейка ОЗУ, в которой была такая переменная, после завершения работы функции, в которой она была объявлена? Не разрастается ли объём ОЗУ при использовании большого количества лок. переменных?

И ещё, нужно ли при объявлении глоб. переменных в хедерах писать "typedef" в AVR Studio? Всё работает и без "typedef", но мало ли, решил переспросить.
Последний раз редактировалось HF_Cat Чт апр 18, 2013 16:40:59, всего редактировалось 1 раз.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

2 ibiza11

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

const screen_item_t *x[4];
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

Если объявить таким образом массив, то для каждого объявления переменной типа screen_t придется объявлять свой массив, причем каждый раз с новым именем. Так не пойдет. И я спрашивал про инициализацию, а не просто объявление.
Ставим плюсы: )
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

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

Сообщение FreshMan »

чувстивителен ли язык Си к регистру ?
temp и TEMP - это разные переменные ?
Tell Me The Truth
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение А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 - это разные переменные ?
Разные.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

Так не пойдет

По другому - никак - компилятор не знает, сколько выделить памяти. Еще в плюсах можно извернуться, в си - никак.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

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

Сообщение ploop »

HF_Cat писал(а):Есть вопрос по поводу локальных переменных. Освобождается ли ячейка ОЗУ, в которой была такая переменная, после завершения работы функции, в которой она была объявлена? Не разрастается ли объём ОЗУ при использовании большого количества лок. переменных?

Освобождается. Это задача компилятора.
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

по задумке каждая переменная типа screen_t должна содержать свое количество указателей на переменные типа screen_item_t. может тогда как-то отделить определение структуры от определения размера массива? может подскажете как вместо массива указателей использовать указатель на массив указателей?
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

FreshMan писал(а):чувстивителен ли язык Си к регистру ?
temp и TEMP - это разные переменные ?

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

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

Сообщение А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);
}
//*******************************************************//

СпойлерИзображение
scr.JPG
(274.23 КБ) 292 скачивания
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

Спасибо за советы. Попробую применить. :beer:

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

Спасибо за помощь! :beer:
Ставим плюсы: )
Аватара пользователя
Real lev
Родился
Сообщения: 15
Зарегистрирован: Вс дек 25, 2011 12:15:48
Откуда: Владимир

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

Сообщение 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 выступает уже в роли массива. Как сделать такую конструкцию по правилам Си.
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

У Вас в коде лишняя закрывающая скобка.
а вообще в таких случаях используется приведение к типу.

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

BYTE n, csd[16], *ptr;
ptr = (BYTE *)buff;
Ставим плюсы: )
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Вроде песня на Си льется мелодично, но иногда некоторый диссонанс вызывают варнинги, которые я еще не осознал......

Есть массив

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

char DataOutBuf[4]; 
с которым работаю в фоне и в прерывании, объявил его как

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

volatile char DataOutBuf[4];
в прерывании обращаюсь к нему так:

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

char* pDataOutBuf = DataOutBuf;
при этом, на эту строчку вылазит предупреждение

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

warning: initialisation discards qualifiers from pointer target type
Если volatile убрать, то варнинга нет, но обработка не правильно идет, что надо делать по другому, чтобы и волки сыты былы и овцы целы?????
Аватара пользователя
Apparatchik
Держит паяльник хвостом
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

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

Сообщение Apparatchik »

указатель тоже нужно объявить как volatile.
«И всё-таки она вертится!»
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Ух ты... так просто... Варнинг исчез.....
Только вот чето непонятно, какой смысл локальному указателю назначать volatile ?
Аватара пользователя
Apparatchik
Держит паяльник хвостом
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

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

Сообщение Apparatchik »

Если указатель указывает на объект, который "volatile", то и сам указатель нужно объявлять так же, компилятор же не совсем телепат, тоесть если вы уверены что ошибок в исполнении не будет, то необращайте внимания на варнинг.
«И всё-таки она вертится!»
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

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

Сообщение ibiza11 »

в объявлении

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

volatile char* pDataOutBuf
не указатель volatile, а переменная, на которую он указывает.
Ставим плюсы: )
Аватара пользователя
Apparatchik
Держит паяльник хвостом
Сообщения: 908
Зарегистрирован: Вс май 23, 2010 13:55:42
Откуда: Украина, Александрия

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

Сообщение Apparatchik »

ibiza11 писал(а):не указатель volatile, а переменная, на которую он указывает.

ну я это имел ввиду :roll: выразился неправильно :wink:
«И всё-таки она вертится!»
Аватара пользователя
shads
Опытный кот
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

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

Сообщение shads »

Apparatchik писал(а):если вы уверены что ошибок в исполнении не будет, то необращайте внимания на варнинг.
Да нет уж.....
лучше поставлю лишнее слово, чем будет мазолить глаза.....
Ответить

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