Перейти к содержанию
    

Обращение к элементу двухмерного массива используя адрес массива

//Структура описывающая подпрофиль
typedef struct {
  unsigned short type;
  unsigned short signal;
} sub_profile;

//Массив подпрофиля 1
const sub_profile SUB_PROFILE_1 = {
330,
400
};

//Массив подпрофиля 2
const sub_profile SUB_PROFILE_2 = {
100,
1200
};

......

//Массив подпрофиля n
const sub_profile SUB_PROFILE_n = {
1,
2
};

Массив профиля состоящий из указателей на подпрофили

const sub_profile * PROFILE_1[] = {&SUB_PROFILE_1, &SUB_PROFILE_2, ... , &SUB_PROFILE_n, 0};

И еще один массив содержащий указатели на профили

const sub_profile ** PROFILE[] = {PROFILE_1, ... , PROFILE_n, 0};

Массив PROFILE[] не объявлен, но известно что он начинается с адреса 0x0801F000 (по этому адресу он записывается при помощи другого проекта).

Каким образом я могу обратиться к элементу структуры определенного подпрофиля, определенного профиля.

При попытке:

#define PROFILE                ((sub_profile **)(0x0801F000))

unsigned int temp;
  
temp = PROFILE[1][0]->type;

IAR ARM 5.50 выдает ошибку expression must have pointer type

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IAR ARM 5.50 выдает ошибку expression must have pointer type
Все верно. Значением указателя на указатель является адрес указателя. При попытке напрямую присвоить обычной переменной значение указателя (адрес) и возникает ошибка. Если вам непременно необходимо такое присваивание, то сделайте явное приведение типа к типу переменной. Только предварительно удостоверьтесь, что тип int в вашей системе имеет размерность не меньше, чем адрес переменной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

int для stm32f 4-х байтный.

 

Так как же мне все-таки вычитать значение элемента структуры?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробовал вот так:

#define PROFILE                ((sub_profile **)(0x0801F000))

sub_profile*  temp;
unsigned short temp2;
  
temp = PROFILE[1];
temp2 = (temp[0])->type;

Не помогло. Ошибка такая же.

Что неправильно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну так чтобы из указателя на указатель получить указатель - разыменовать то надо бы по идее ))

temp = *PROFILE[1];

как-то так, чтоли..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если так?

temp2 = temp[0].type;

temp[0] уже получает значение адреса структуры, а чтобы извлечь элемент структуры нужно применить "." (оператор "точка"). Вы же пытаетесь адрес самой структуры применить как указатель на элемент структуры, но он им не является.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если так?

temp2 = temp[0].type;

temp[0] уже получает значение адреса структуры, а чтобы извлечь элемент структуры нужно применить "." (оператор "точка"). Вы же пытаетесь адрес самой структуры применить как указатель на элемент структуры, но он им не является.

 

Откомпилировалось :rolleyes: , но работает неправильно :crying:

temp2 приняло значение первых двух байт temp[0], а это не значение элемента структуры, а кусок (потому что temp2 типа short) адреса структуры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разыменовывать, разыменовывать же)

вот это даже проверил(правда на gcc)

//Структура описывающая подпрофиль
typedef struct {
  unsigned short type;
  unsigned short signal;
} sub_profile;

//Массив подпрофиля 1
const sub_profile SUB_PROFILE_1 = {
330,
400
};

//Массив подпрофиля 2
const sub_profile SUB_PROFILE_2 = {
100,
1200
};

const sub_profile *PROFILE_1[] = {&SUB_PROFILE_1, &SUB_PROFILE_2, 0};


//сюда во время своего эксперимента я подставлял свой адрес. Но сути дела это не меняет ))
#define PROFILE                ((sub_profile **)(0x0801F000))

//у Вас тут был int, а не  short...
unsigned short temp;

void main(void){
//тут мыслил так:
//сперва разыменовываем PROFILE, чтобы указатель на указатель превратился просто в указатель (*PROFILE)
//далее, этот разименованый указатель приводим к типу (sub_profile *), чтобы компилятор трактовал новоиспеченный указатель 
//как указывающий на тип sub_profile *
//далее уже(после приведения типа) к этому указателю можно обратиться как к массиву используя известную фишку Си [0]
//также известно, что после применения этой фишки нам уже нужно использовать не ->, а . 
//вот, собственно и имеем результат
    temp = (sub_profile *)(*PROFILE)[0].type; //temp == 330
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не компилируется. ругается на строку:

temp = (sub_profile *)(*PROFILE)[0].type;

a value of type "sub_profile*" cannot be assigned to an entity of type "unsigned short"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну вот так точно уж должно работать

#define PROFILE                ((sub_profile **)(0x0801F000))

unsigned short temp;
sub_profile **pptr, *pntr;

  pptr = PROFILE; // инициализируем указатель
  pptr = (sub_profile **)(pptr[1]); // извлекаем из массива указатель на требуемый массив указателей
  pntr = (sub_profile *)(*pptr); // извлекаем из массива указателей требуемый указатель на структуру
  temp = pntr[1].type; //извлекаем элемент структуры

Тут все по-отдельности, но типизация соответствует.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не компилируется. ругается на строку:
компилятору незачёт )) проверить всё не получится ибо IARa нет у меня.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот так тоже работает, но лично меня сложность такой конструкции несколько угнетает :)

temp = ((sub_profile *)(*(sub_profile **)PROFILE[1]))[1].type;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...