Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обращение к элементу двухмерного массива используя адрес массива
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Страницы: 1, 2
ViKo
Цитата(GetSmart @ Dec 29 2010, 00:03) *
Не надо все системы команд ARM-ов обобщать. Это система кортекса-М3. Для ARM v4 32 бита одинаковое кол-во слов, команд и тактов.
А во-вторых, алгоритмы в примерах разные. В первом инкремент указателя, во втором взятие элементов с конца массива.
В-третьих нафига козе баян в виде скобок *(pDig++) ?
Попробуйте без них *pDig++

Насчет скобок - согласен, можно без них. Просто тяжелее воспринимать. Убрал. В книжках их, кстати, пишут. По той же причине.
Насчет взятия элементов с конца массива - упустил из виду. Не сомневаюсь, что результат не изменится. Зря не сомневался sm.gif Начинать-то нужно с нуля, потом инкрементировать счетчик и сравнивать с 10. Стало на 2 байта больше.
А система команд - Thumb-2 называется. Виноват. Имел в виду систему команд от фирмы ARM. Опять же, это чисто качественный пример. Для ARMv4 команды для двух арифметик тоже будут разные.
singlskv
Цитата(ViKo @ Dec 29 2010, 00:58) *
Похоже, разработчики ARM специально "подрихтовали" процессор под C.
Все с точностью до наоборот... sm.gif
Большая часть кода С(когда-то написанного) используют адресную арифметику т.к. на
большинстве процессоров/компиляторов это дает выигрыш.
А Ваш пример действительно интересен, надо будет не забыть поиграться с этим
при переносе проекта на кортекс.
Сергей Борщ
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
XVR
Цитата(Сергей Борщ @ Dec 29 2010, 11:26) *
Не верю. Покажите ее.
Посыпаю голову пеплом - разницы действительно нет (за исключением того, что конструкция **[] отказывается компилится). Разница проявляется в другом контексте


2 GetSmart: ТС - это 'Топик Стартер'
ViKo
Цитата(Сергей Борщ @ Dec 29 2010, 10:26) *
Да что ж вы сравниваете два алгоритма и удивляетесь разнице? Еще раз говорю, сравните в одинаковом цикле обращение pDig[j] и Digit[j], сравните *(pDig + j) и *(Digit + j... не видя объявления pDig и Digit вы только глядя на их использование сможете сказать, который из них массив, а который указатель? Нет, не сможете. Вот это я и пытаюсь объяснить на протяжении двух страниц.

Так я ж не спорю о том, что Digit[j] и *(Digit + j) - это одно и то же. Наоборот, подтверждал. sm.gif А удивляюсь я тому, что известное правило отказываться от индексной арифметики в пользу адресной для ARM не работает. Может быть, для многомерных массивов все "вернется на круги своя"...

Цитата(XVR @ Dec 29 2010, 10:50) *
за исключением того, что конструкция **[] отказывается компилится

Должна компилироваться!:) Скорее всего, что-то не так определено.
XVR
Цитата(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** []'
Для С аналогично (текст сообщения об ошибке немного другой, но смысл тот же)
ViKo
Цитата(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|
sigmaN
ага, только эти a b c тоже как-бээ массивы указателей должны быть ) у ТС профиль - это массив указателей на подпрофили, а дефайн этот указывает на массив профилей...
demiurg_spb
В тему указатели-массивы (накидал примерчик за 5 минут):
Код
uint8_t* get_first_middle_of_tripple(uint8_t* p, size_t qty)
{
   if (qty>=3)
   {  
      while (qty--)
      {
         p++;

         if ((p[0] == p[-1]) && (p[0] == p[1]))
         {
            return (p);
         }
      }
   }
   return (NULL);
}
GetSmart
36?
ViKo
Цитата(sigmaN @ Dec 30 2010, 12:58) *
ага, только эти a b c тоже как-бээ массивы указателей должны быть ) у ТС профиль - это массив указателей на подпрофили, а дефайн этот указывает на массив профилей...

Я отвечал XVR, показал, что компилируется. Что там у TC, не вникал. Не сомневаюсь, что тоже реализуемо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.