|
Обращение к элементу двухмерного массива используя адрес массива |
|
|
|
Dec 24 2010, 14:13
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
Код //Структура описывающая подпрофиль 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
|
|
|
|
|
 |
Ответов
(1 - 60)
|
Dec 25 2010, 18:33
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
int для stm32f 4-х байтный.
Так как же мне все-таки вычитать значение элемента структуры?
|
|
|
|
|
Dec 25 2010, 19:51
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
Попробовал вот так: Код #define PROFILE ((sub_profile **)(0x0801F000))
sub_profile* temp; unsigned short temp2; temp = PROFILE[1]; temp2 = (temp[0])->type; Не помогло. Ошибка такая же. Что неправильно?
|
|
|
|
|
Dec 25 2010, 20:37
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
Цитата(rezident @ Dec 26 2010, 01:35)  На какую именно строку ругается? Код temp2 = (temp[0])->type;
|
|
|
|
|
Dec 25 2010, 21:30
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
Цитата(rezident @ Dec 26 2010, 02:06)  А если так? Код temp2 = temp[0].type; temp[0] уже получает значение адреса структуры, а чтобы извлечь элемент структуры нужно применить "." (оператор "точка"). Вы же пытаетесь адрес самой структуры применить как указатель на элемент структуры, но он им не является. Откомпилировалось  , но работает неправильно temp2 приняло значение первых двух байт temp[0], а это не значение элемента структуры, а кусок (потому что temp2 типа short) адреса структуры.
|
|
|
|
|
Dec 26 2010, 01:11
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Разыменовывать, разыменовывать же) вот это даже проверил(правда на 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 }
--------------------
The truth is out there...
|
|
|
|
|
Dec 26 2010, 16:05
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
не компилируется. ругается на строку: Цитата(sigmaN @ Dec 26 2010, 06:11)  Код temp = (sub_profile *)(*PROFILE)[0].type; a value of type "sub_profile*" cannot be assigned to an entity of type "unsigned short"
|
|
|
|
|
Dec 26 2010, 18:52
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(sigmaN @ Dec 27 2010, 02:36)  И вообще мне интересо, почему Ваш этот ИАР не хавает предложенный мною вариант... вроде там всё по Сишному правильно....какого он, извиняюсь, икса.... Дык там скобочек не хватает. Вот так не ругается Код temp = ((sub_profile *)(*PROFILE))[0].type; //temp == 330 правда и не работает как хотелось бы ТС
|
|
|
|
|
Dec 26 2010, 20:58
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
компилируется и работает. Цитата(rezident @ Dec 26 2010, 22:38)  Ну вот так точно уж должно работать Код #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; //извлекаем элемент структуры Тут все по-отдельности, но типизация соответствует. компилируется и тоже работает. Цитата(rezident @ Dec 26 2010, 23:17)  Вот так тоже работает, но лично меня сложность такой конструкции несколько угнетает  Код temp = ((sub_profile *)(*(sub_profile **)PROFILE[1]))[1].type; ОГРОМНОЕ СПАСИБО!!!
|
|
|
|
|
Dec 26 2010, 21:18
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
скобок действительно не хватало и похоже, что на любом компиляторе, кроме AVR GCC мой код не компилился. Но я сделал вот так Код temp = ((sub_profile *)(*PROFILE))[0].type; //temp == 330 temp = ((sub_profile *)(*PROFILE))[1].type; //temp == 100 и дело пошло. Даже в микрософтовской визуал студии всё работает правильно. added кажется надо больше спать. ТС говорил о том, что массив содержит массив указателей на профили, да... понял. молчу. ))
--------------------
The truth is out there...
|
|
|
|
|
Dec 27 2010, 05:01
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (sigmaN @ Dec 27 2010, 02:18)  Но я сделал вот так CODE temp = ((sub_profile *)(*PROFILE))[0].type; //temp == 330 temp = ((sub_profile *)(*PROFILE))[1].type; //temp == 100 и дело пошло. Даже в микрософтовской визуал студии всё работает правильно. Что-то вас всех куда-то понесло в дебри CODE #define PROFILE ((sub_profile ***)(0x0801F000)) unsigned int temp;
temp = PROFILE[1][0]->type;
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 27 2010, 07:39
|
Участник

Группа: Участник
Сообщений: 18
Регистрация: 14-03-10
Из: BELARUS
Пользователь №: 55 953

|
Цитата(Сергей Борщ @ Dec 27 2010, 10:01)  Что-то вас всех куда-то понесло в дебри Код #define PROFILE ((sub_profile ***)(0x0801F000)) unsigned int temp; temp = PROFILE[1][0]->type; Спасибо. Очень красивый вариант. Почти точно такой предложили сотрудники на работе. Еще раз спасибо!!!!
|
|
|
|
|
Dec 27 2010, 13:58
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Сергей Борщ @ Dec 27 2010, 11:01)  Что-то вас всех куда-то понесло в дебри Код #define PROFILE ((sub_profile ***)(0x0801F000)) unsigned int temp; temp = PROFILE[1][0]->type; Почти так, но не совсем. Последняя размерность - это массив, а не указатель. Должно быть как то так: Код #define PROFILE ((sub_profile **[])(0x0801F000)) unsigned int temp; temp = PROFILE[1][0]->type; Если компилятор не прожует, то так: Код typedef sub_profile **ProfileType[]; #define PROFILE ((ProfileType)(0x0801F000)) unsigned int temp; temp = PROFILE[1][0]->type;
|
|
|
|
|
Dec 27 2010, 18:58
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (XVR @ Dec 27 2010, 18:58)  Почти так, но не совсем. Последняя размерность - это массив, а не указатель. Должно быть как то так: В Си массивы и указатели почти эквивалентные понятия. Используется одна и та же адресная арифметика CODE int a[5]; int *b = a;
*(a + 3) = 5; b[3] = 5; 3[a] = 5;
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 28 2010, 08:47
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(Сергей Борщ @ Dec 28 2010, 13:00)  Для массива имеется одна переменная - адрес начала. И он фактически имеет тип "указатель на тип элемента массива". Индекс появляется при обращении к элементу. При обращении по указателю точно так же можно использовать нотацию обращения к элементу массива как и при обращении к элементу массива можно использовать нотацию указателей. Пример подобных обращений в предыдущем сообщении. Вы можете написать как *b, так и b[0], эти записи совершенно эквивалентны в C. Массив и константный указатель отличаются только на этапе объявления/инициализации. http://www.fredosaurus.com/notes-cpp/array...aspointers.htmlЯ согласен с вашими словами, однако, массив обрабатывается обычно именно по его адресу и индексу. Т.е., например, в каждом шаге цикла, обрабатывающего массив, вычисляется адрес элемента массива, с использованием адреса начала массива и индекса. Если указатель можно просто перемещать по элементам массива (адресная арифметика), то при индексной арифметике адрес элемента массива нужно вычислить по адресу начала массива и индексу элемента, для этого задействовать некую временную переменную (регистр микропроцессора). Для ARM, к примеру, эта операция выполняется в одной команде, а для PIC16 команд потребуется несколько.
|
|
|
|
|
Dec 28 2010, 14:43
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Dec 28 2010, 20:56)  Найдите мне теперь любое действие, которое я могу выполнить с ptr и не могу выполнить с array. Или наоборот. Если бы имя массива было эквивалентно адресу на его первый элемент, то компилятор не ругался бы на это Код u08 massiv[100]; u08 *ptr = massiv; однако компилятор ругается и требует так Код u08 massiv[100]; u08 *ptr = &massiv[0]; ======== upd Проверил, ИАР не ругается.
Сообщение отредактировал GetSmart - Dec 28 2010, 15:19
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Dec 28 2010, 16:26
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(GetSmart @ Dec 28 2010, 20:21)  В книжках так же пишут, что детей находят в капусте  Ну, вот пример специально для вас. Keil, STM32. Код static const uint8_t Digit[10] = {'0','1','2','3','4','5','6','7','8','9'}; const uint8_t *pDig = Digit; for (uint32_t i=10; i--; ) GPIOA->ODR = *(pDig++); вот часть листинга после компиляции Код ;;;202 static const uint8_t Digit[10] = {'0','1','2','3','4','5','6','7','8','9'}; ;;;203 const uint8_t *pDig = Digit; 000092 486d LDR r0,|L1.584| ;;;204 for (uint32_t i=10; i--; ) GPIOA->ODR = *(pDig++); 000094 210a MOVS r1,#0xa 000096 4b6d LDR r3,|L1.588| 000098 e003 B |L1.162| |L1.154| 00009a f8102b01 LDRB r2,[r0],#1 00009e f8c3280c STR r2,[r3,#0x80c] |L1.162| 0000a2 1e49 SUBS r1,r1,#1 0000a4 d2f9 BCS |L1.154| Я удивляюсь, что вы подвергаете сомнению азбучные истины  О, заметил, вы уже исправились
|
|
|
|
|
Dec 28 2010, 16:51
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
По поводу массив/указатель уже где то тут выясняли. Для компилятора они НЕ ЯВЛЯЮТСЯ одинаковыми сущностями. Пример: 1й С файл Код char msg[]="Hello, world!"; 1й С файл Код extern char* msg; main() { puts(msg); } Скомпилите, слинкуйте, запустите и наслаждайтесь
|
|
|
|
|
Dec 28 2010, 17:14
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (rezident @ Dec 28 2010, 18:10)  Разница проявляется при вычислении значения указателя. Массив структур формально ничем не отличается от массива байт или слов - в массиве все элементы одинаковые по размеру. Если бы массивы и структуры были суть одно и то же, но какой смысл было вводить новые абстракции?  Я вас не понимаю. В массиве все элементы одинаковые по размеру. Бесспорно. Но точно также одинаковы по размеру и *ptr и *(ptr + 1) и *(ptr + n). Указатель указывает на данные совершенно определенного и всегда одного и того же типа типа независимо от того, куда именно он указывает. Более того, увеличивая указатель на 1 содержащийся в нем адрес увеличивается ровно на столько же, насколько отличаются адреса соседних элементов массива из данных того же типа. И в обоих случаях с учетом выравнивания. Нету разницы в вычислении адреса. Или приведите пример. QUOTE (XVR @ Dec 28 2010, 21:51)  Для компилятора они НЕ ЯВЛЯЮТСЯ одинаковыми сущностями. Пример: По поводу объявления/инициализации была оговорка.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 28 2010, 17:25
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (XVR @ Dec 28 2010, 22:22)  ВСЕ ОСТАЛЬНЫЕ операции на самом деле производятся именно с этим указателем. Совершенно верно. Вот цитата из стандарта, желающие могут поспорить с ним: QUOTE 6.3.2.1 Lvalues, arrays, and function designators 3. Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 28 2010, 17:55
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Решил сравнить адресную и индексную арифметику на приведенном выше своем примере. Код ;;;202 static const uint8_t Digit[10] = {'0','1','2','3','4','5','6','7','8','9'}; ;;;203 const uint8_t *pDig = Digit; 000092 4870 LDR r0,|L1.596| ;;;204 for (uint32_t i=10; i; i--) GPIOA->ODR = *(pDig++); 000094 4a70 LDR r2,|L1.600| 000096 210a MOVS r1,#0xa |L1.152| 000098 f8103b01 LDRB r3,[r0],#1 00009c f8c2380c STR r3,[r2,#0x80c] 0000a0 1e49 SUBS r1,r1,#1 0000a2 d1f9 BNE |L1.152| 0000a4 496b LDR r1,|L1.596| ;;;205 for (int32_t j=9; j>=0; j--) GPIOA->ODR = Digit[j]; 0000a6 2009 MOVS r0,#9 |L1.168| 0000a8 5c0b LDRB r3,[r1,r0] 0000aa f8c2380c STR r3,[r2,#0x80c] 0000ae 1e40 SUBS r0,r0,#1 0000b0 d5fa BPL |L1.168| Результат слегка обескуражил. Обращение к элементу массива с помощью индекса занимает меньше байтов. Особенность системы команд ARM. Сравните строки 98 и a8. В любом случае, эти два способа работают по-разному.
|
|
|
|
|
Dec 28 2010, 18:49
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (ViKo @ Dec 28 2010, 22:55)  В любом случае, эти два способа работают по-разному. А вы сравните for (int32_t j=9; j>=0; j--) GPIOA->ODR = pDig[j]; и for (int32_t j=9; j>=0; j--) GPIOA->ODR = Digit[j];
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 28 2010, 18:58
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(Сергей Борщ @ Dec 28 2010, 23:49)  А вы сравните... Код ;;;202 static const uint8_t Digit[10] = {'0','1','2','3','4','5','6','7','8','9'}; ;;;203 const uint8_t *pDig = Digit; 000092 4870 LDR r0,|L1.596| ;;;204 for (int32_t j=9; j>=0; j--) GPIOA->ODR = *(pDig++); 000094 4970 LDR r1,|L1.600| 000096 2209 MOVS r2,#9 |L1.152| 000098 f8103b01 LDRB r3,[r0],#1 00009c f8c1380c STR r3,[r1,#0x80c] 0000a0 1e52 SUBS r2,r2,#1 0000a2 d5f9 BPL |L1.152| 0000a4 4a6b LDR r2,|L1.596| ;;;205 for (int32_t j=9; j>=0; j--) GPIOA->ODR = Digit[j]; 0000a6 2009 MOVS r0,#9 |L1.168| 0000a8 5c13 LDRB r3,[r2,r0] 0000aa f8c1380c STR r3,[r1,#0x80c] 0000ae 1e40 SUBS r0,r0,#1 0000b0 d5fa BPL |L1.168| Это ничего не меняет. Отличия именно в адресации элементов массива. Похоже, разработчики ARM специально "подрихтовали" процессор под C.
|
|
|
|
|
Dec 28 2010, 19:03
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(ViKo @ Dec 29 2010, 01:55)  Результат слегка обескуражил. Обращение к элементу массива с помощью индекса занимает меньше байтов. Особенность системы команд ARM. Не надо все системы команд ARM-ов обобщать. Это система кортекса-М3. Для ARM v4 32 бита одинаковое кол-во слов, команд и тактов. А во-вторых, алгоритмы в примерах разные. В первом инкремент указателя, во втором взятие элементов с конца массива. В-третьих нафига козе баян в виде скобок *(pDig++) ? Попробуйте без них *pDig++ Цитата(XVR @ Dec 29 2010, 01:23)  В случает ТС разница между *** и **[] будет катастрофическая Что такое ТС? "В случает ТС"
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Dec 28 2010, 19:11
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(GetSmart @ Dec 29 2010, 00:03)  Не надо все системы команд ARM-ов обобщать. Это система кортекса-М3. Для ARM v4 32 бита одинаковое кол-во слов, команд и тактов. А во-вторых, алгоритмы в примерах разные. В первом инкремент указателя, во втором взятие элементов с конца массива. В-третьих нафига козе баян в виде скобок *(pDig++) ? Попробуйте без них *pDig++ Насчет скобок - согласен, можно без них. Просто тяжелее воспринимать. Убрал. В книжках их, кстати, пишут. По той же причине. Насчет взятия элементов с конца массива - упустил из виду. Не сомневаюсь, что результат не изменится. Зря не сомневался  Начинать-то нужно с нуля, потом инкрементировать счетчик и сравнивать с 10. Стало на 2 байта больше. А система команд - Thumb-2 называется. Виноват. Имел в виду систему команд от фирмы ARM. Опять же, это чисто качественный пример. Для ARMv4 команды для двух арифметик тоже будут разные.
|
|
|
|
|
Dec 28 2010, 19:40
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(ViKo @ Dec 29 2010, 00:58)  Похоже, разработчики ARM специально "подрихтовали" процессор под C. Все с точностью до наоборот...  Большая часть кода С(когда-то написанного) используют адресную арифметику т.к. на большинстве процессоров/компиляторов это дает выигрыш. А Ваш пример действительно интересен, надо будет не забыть поиграться с этим при переносе проекта на кортекс.
|
|
|
|
|
Dec 29 2010, 05:26
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (ViKo @ Dec 28 2010, 23:58)  Это ничего не меняет. Отличия именно в адресации элементов массива. Да что ж вы сравниваете два алгоритма и удивляетесь разнице? Еще раз говорю, сравните в одинаковом цикле обращение pDig[j] и Digit[j], сравните *(pDig + j) и *(Digit + j), а потом посмотрите на оба варианта исходного текста CODE (int32_t j=9; j>=0; j--) GPIOA->ODR = *(pDig + j); и (int32_t j=9; j>=0; j--) GPIOA->ODR = *(Digit + j); или CODE (int32_t j=9; j>=0; j--) GPIOA->ODR = pDig[j]; и (int32_t j=9; j>=0; j--) GPIOA->ODR = Digit[j]; и подумайте: не видя объявления pDig и Digit вы только глядя на их использование сможете сказать, который из них массив, а который указатель? Нет, не сможете. Вот это я и пытаюсь объяснить на протяжении двух страниц. QUOTE (XVR @ Dec 28 2010, 22:23)  В случает ТС разница между *** и **[] будет катастрофическая Не верю. Покажите ее. Аргументируйте утверждение. С указателем получается так: CODE #define PROFILE ((sub_profile ***)(0x0801F000))
void test() { unsigned int volatile temp; temp = PROFILE[1][0]->type; }
166 0000 18309FE5 ldr r3, .L7 @ tmp137, 167 0004 043093E5 ldr r3, [r3, #4] @ tmp138, 168 0008 003093E5 ldr r3, [r3, #0] @ tmp139, 169 000c B030D3E1 ldrh r3, [r3, #0] @ temp.29, D.3609_3->type
186 .L7: 187 0020 00F00108 .word 134344704
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 29 2010, 06:59
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(Сергей Борщ @ Dec 29 2010, 10:26)  Да что ж вы сравниваете два алгоритма и удивляетесь разнице? Еще раз говорю, сравните в одинаковом цикле обращение pDig[j] и Digit[j], сравните *(pDig + j) и *(Digit + j... не видя объявления pDig и Digit вы только глядя на их использование сможете сказать, который из них массив, а который указатель? Нет, не сможете. Вот это я и пытаюсь объяснить на протяжении двух страниц. Так я ж не спорю о том, что Digit[j] и *(Digit + j) - это одно и то же. Наоборот, подтверждал.  А удивляюсь я тому, что известное правило отказываться от индексной арифметики в пользу адресной для ARM не работает. Может быть, для многомерных массивов все "вернется на круги своя"... Цитата(XVR @ Dec 29 2010, 10:50)  за исключением того, что конструкция **[] отказывается компилится Должна компилироваться!:) Скорее всего, что-то не так определено.
|
|
|
|
|
Dec 29 2010, 16:54
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(ViKo @ Dec 29 2010, 12:59)  Должна компилироваться!:) Скорее всего, что-то не так определено. Не должно: Цитата t.cc: In function 'void test()': t.cc:10:12: error: ISO C++ forbids casting to an array type 'sub_profile** []' Для С аналогично (текст сообщения об ошибке немного другой, но смысл тот же)
|
|
|
|
|
Dec 30 2010, 07:21
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(XVR @ Dec 29 2010, 21:54)  Не должно: Такое годится? Трудно понять, но, кажется, делает, что задумано. Ни ошибок, ни предупреждений. Код static const uint8_t a = 'A', b = 'B', c = 'C', d = 'D'; static const uint8_t *pa = &a, *pb = &b, *pc = &c, *pd = &d; static const uint8_t **ptr[] = {&pa, &pb, &pc, &pd}; for (int32_t i=0; i<4; i++) GPIOA->ODR = **ptr[i]; Результат компиляции: Код ;;;210 static const uint8_t a = 'A', b = 'B', c = 'C', d = 'D'; ;;;211 static const uint8_t *pa = &a, *pb = &b, *pc = &c, *pd = &d; ;;;212 static const uint8_t **ptr[] = {&pa, &pb, &pc, &pd}; ;;;213 for (int32_t i=0; i<4; i++) GPIOA->ODR = **ptr[i]; 0000b4 4965 LDR r1,|L1.588| 0000b6 2000 MOVS r0,#0 0000b8 3120 ADDS r1,r1,#0x20 |L1.186| 0000ba f8513020 LDR r3,[r1,r0,LSL #2] 0000be 681b LDR r3,[r3,#0] 0000c0 781b LDRB r3,[r3,#0] 0000c2 f8c2380c STR r3,[r2,#0x80c] 0000c6 1c40 ADDS r0,r0,#1 0000c8 2804 CMP r0,#4 0000ca dbf6 BLT |L1.186|
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|