реклама на сайте
подробности

 
 
> Обращение к элементу двухмерного массива используя адрес массива
LEVENVORF
сообщение Dec 24 2010, 14:13
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
5 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 60)
rezident
сообщение Dec 25 2010, 17:53
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(LEVENVORF @ Dec 24 2010, 22:13) *
IAR ARM 5.50 выдает ошибку expression must have pointer type
Все верно. Значением указателя на указатель является адрес указателя. При попытке напрямую присвоить обычной переменной значение указателя (адрес) и возникает ошибка. Если вам непременно необходимо такое присваивание, то сделайте явное приведение типа к типу переменной. Только предварительно удостоверьтесь, что тип int в вашей системе имеет размерность не меньше, чем адрес переменной.
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 25 2010, 18:33
Сообщение #3


Участник
*

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



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

Так как же мне все-таки вычитать значение элемента структуры?
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 25 2010, 19:05
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(LEVENVORF @ Dec 26 2010, 02:33) *
Так как же мне все-таки вычитать значение элемента структуры?
Используя указатель. Значение из массива указателей нужно присваивать переменной имеющий такой же тип указателя и затем использовать обращение через этот указатель к массиву элементов.
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 25 2010, 19:51
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 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;

Не помогло. Ошибка такая же.
Что неправильно?
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 25 2010, 20:35
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



На какую именно строку ругается?
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 25 2010, 20:35
Сообщение #7


I WANT TO BELIEVE
******

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



ну так чтобы из указателя на указатель получить указатель - разыменовать то надо бы по идее ))
Код
temp = *PROFILE[1];
как-то так, чтоли..


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 25 2010, 20:37
Сообщение #8


Участник
*

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



Цитата(rezident @ Dec 26 2010, 01:35) *
На какую именно строку ругается?

Код
temp2 = (temp[0])->type;

Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 25 2010, 21:06
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



А если так?
Код
temp2 = temp[0].type;

temp[0] уже получает значение адреса структуры, а чтобы извлечь элемент структуры нужно применить "." (оператор "точка"). Вы же пытаетесь адрес самой структуры применить как указатель на элемент структуры, но он им не является.
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 25 2010, 21:30
Сообщение #10


Участник
*

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



Цитата(rezident @ Dec 26 2010, 02:06) *
А если так?
Код
temp2 = temp[0].type;

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


Откомпилировалось rolleyes.gif , но работает неправильно crying.gif
temp2 приняло значение первых двух байт temp[0], а это не значение элемента структуры, а кусок (потому что temp2 типа short) адреса структуры.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 26 2010, 01:11
Сообщение #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...
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 26 2010, 16:05
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 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"
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 26 2010, 17:38
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Ну вот так точно уж должно работать
Код
#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; //извлекаем элемент структуры

Тут все по-отдельности, но типизация соответствует.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 26 2010, 17:54
Сообщение #14


I WANT TO BELIEVE
******

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



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


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 26 2010, 18:17
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Вот так тоже работает, но лично меня сложность такой конструкции несколько угнетает sm.gif
Код
temp = ((sub_profile *)(*(sub_profile **)PROFILE[1]))[1].type;
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 26 2010, 18:36
Сообщение #16


I WANT TO BELIEVE
******

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



Топикстартер, а нам вообще точно нужен указатель на указатель?
Предлагаю избавиться от этого изврата ещё в самом начале
может быть пусть #define PROFILE будет void * а потом, где надо его можно будет преобразовать во что надо..

И вообще мне интересо, почему Ваш этот ИАР не хавает предложенный мною вариант... вроде там всё по Сишному правильно....какого он, извиняюсь, икса....


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 26 2010, 18:52
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



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

правда и не работает как хотелось бы ТС rolleyes.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 26 2010, 19:36
Сообщение #18


I WANT TO BELIEVE
******

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



я то проверял и у меня реально работало же. могу хоть щас полный проект выложить(правда под авр). Но в эмуляторе всё проверил - работает как надо.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 26 2010, 19:59
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sigmaN @ Dec 27 2010, 03:36) *
я то проверял и у меня реально работало же. могу хоть щас полный проект выложить(правда под авр). Но в эмуляторе всё проверил - работает как надо.
Если вас IAR не впечатляет, но быть может убедит авторитет Keil? Так вот Keil выдает такую же ошибку на вашу строку, что и IAR. В то время как мои 4-х и 1-но строчные варианты компилируются и работают без ошибок и там и там. Проверял в IAR EWARM 5.50.5 и Keil 4.12.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 26 2010, 20:25
Сообщение #20


I WANT TO BELIEVE
******

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



тогда наверное дело в размере указателя.... щас найду кеил.. точно был


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 26 2010, 20:58
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 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) *
Вот так тоже работает, но лично меня сложность такой конструкции несколько угнетает sm.gif
Код
temp = ((sub_profile *)(*(sub_profile **)PROFILE[1]))[1].type;


ОГРОМНОЕ СПАСИБО!!!
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 26 2010, 21:18
Сообщение #22


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...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 27 2010, 05:01
Сообщение #23


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
LEVENVORF
сообщение Dec 27 2010, 07:39
Сообщение #24


Участник
*

Группа: Участник
Сообщений: 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;

Спасибо. Очень красивый вариант. Почти точно такой предложили сотрудники на работе.
Еще раз спасибо!!!!
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 27 2010, 07:44
Сообщение #25


I WANT TO BELIEVE
******

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



temp = PROFILE[1][0]->type;
даа, а ведь и правда так и должно было быть.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 27 2010, 07:55
Сообщение #26


Гуру
******

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



QUOTE (LEVENVORF @ Dec 27 2010, 12:39) *
Почти точно такой предложили сотрудники на работе.
Так он у вас и был изначально. Вы просто в #define забыли добавить еще один указатель, ведь ваш переопределенный PROFILE есть указатель на массив указателей на массивы указателей на субпрофили.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 27 2010, 10:52
Сообщение #27


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Есть очень хорошее правило, прочитанное мной где-то давным-давно:
"По возможности не использовать более 2 степеней вложенности указателей".
Максимум - это указатель на указатель.
И жизнь будет намного проще:-)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 27 2010, 13:58
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 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;

Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 27 2010, 15:48
Сообщение #29


I WANT TO BELIEVE
******

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



Цитата
Есть очень хорошее правило, прочитанное мной где-то давным-давно:
"По возможности не использовать более 2 степеней вложенности указателей".
Ну мне эта конструкция тоже сразу не очень понравилась... но раз уж там все эти профайлы так закручены by design - то не известно что проще...переделывать дизайн или такой вот "костыль"(конечно с натяжкой) вставить.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 27 2010, 18:58
Сообщение #30


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 07:26
Сообщение #31


Универсальный солдатик
******

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



Цитата(Сергей Борщ @ Dec 27 2010, 23:58) *
В Си массивы и указатели почти эквивалентные понятия. Используется одна и та же адресная арифметика

Только для массивов имеется две переменные - адрес начала массива и индекс, которые складываются согласно типу переменных массива. А для указателей имеется всего одна переменная - адрес, соответствующий типу переменной, на которую указывает указатель.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 28 2010, 08:00
Сообщение #32


Гуру
******

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



QUOTE (ViKo @ Dec 28 2010, 12:26) *
Только для массивов имеется две переменные - адрес начала массива и индекс, которые складываются согласно типу переменных массива. А для указателей имеется всего одна переменная - адрес, соответствующий типу переменной, на которую указывает указатель.
Для массива имеется одна переменная - адрес начала. И он фактически имеет тип "указатель на тип элемента массива". Индекс появляется при обращении к элементу. При обращении по указателю точно так же можно использовать нотацию обращения к элементу массива как и при обращении к элементу массива можно использовать нотацию указателей. Пример подобных обращений в предыдущем сообщении. Вы можете написать как *b, так и b[0], эти записи совершенно эквивалентны в C. Массив и константный указатель отличаются только на этапе объявления/инициализации. http://www.fredosaurus.com/notes-cpp/array...aspointers.html


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 08:47
Сообщение #33


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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 команд потребуется несколько.
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 28 2010, 11:43
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Сергей Борщ @ Dec 28 2010, 02:58) *
В Си массивы и указатели почти эквивалентные понятия. Используется одна и та же адресная арифметика
Это справедливо только для случая массива и указателя на элемент массива. Различие заключается в том, что массив состоит из элементов одинаковой размерности, а указатель можно использовать для обращения и к элементам объектов с более сложным устройством - структуры, например. Элементы структуры могут иметь совершенно разную размерность и в т.ч. включать в себя те же массивы. Для обращения к структуре недостаточно знать только лишь ее базовый адрес, нужно знать и ее внутреннее устройство, чтобы правильно вычислять значение указателя.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 28 2010, 12:56
Сообщение #35


Гуру
******

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



QUOTE (rezident @ Dec 28 2010, 16:43) *
Различие заключается в том, что массив состоит из элементов одинаковой размерности, а указатель можно использовать для обращения и к элементам объектов с более сложным устройством - структуры, например.
Какая разница? Массив тоже может состоять из структур. Теперь я беру константный указатель на эту структуру и присваиваю ему адрес начала этого массива (пишу mystruct * const ptr = array;). Найдите мне теперь любое действие, которое я могу выполнить с ptr и не могу выполнить с array. Или наоборот.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 28 2010, 13:10
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Сергей Борщ @ Dec 28 2010, 20:56) *
Какая разница? Массив тоже может состоять из структур.
Разница проявляется при вычислении значения указателя. Массив структур формально ничем не отличается от массива байт или слов - в массиве все элементы одинаковые по размеру. Если бы массивы и структуры были суть одно и то же, но какой смысл было вводить новые абстракции? wink.gif
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 28 2010, 14:43
Сообщение #37


.
******

Группа: Участник
Сообщений: 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


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 15:08
Сообщение #38


Универсальный солдатик
******

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



Цитата(GetSmart @ Dec 28 2010, 19:43) *
однако компилятор ругается и требует так

Теоретически, компилятор ругаться не должен. Потому что в книжках написано, что имя массива есть адрес его первого элемента. Так же, как имя функции есть адрес входа в эту функцию.
Сергей Борщ прав, когда говорит, что операции с ptr и array одинаково допустимы. Разница в том, как это будет реализовано при обработке всего массива.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 28 2010, 15:21
Сообщение #39


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



В книжках так же пишут, что детей находят в капусте sm.gif


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 16:26
Сообщение #40


Универсальный солдатик
******

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



Цитата(GetSmart @ Dec 28 2010, 20:21) *
В книжках так же пишут, что детей находят в капусте sm.gif

Ну, вот пример специально для вас. 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|

Я удивляюсь, что вы подвергаете сомнению азбучные истины sm.gif О, заметил, вы уже исправились sm.gif
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 28 2010, 16:51
Сообщение #41


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



По поводу массив/указатель уже где то тут выясняли. Для компилятора они НЕ ЯВЛЯЮТСЯ одинаковыми сущностями. Пример:
1й С файл
Код
char msg[]="Hello, world!";

1й С файл
Код
extern char* msg;
main()
{
  puts(msg);
}
Скомпилите, слинкуйте, запустите и наслаждайтесь sm.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 28 2010, 17:14
Сообщение #42


Гуру
******

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



QUOTE (rezident @ Dec 28 2010, 18:10) *
Разница проявляется при вычислении значения указателя. Массив структур формально ничем не отличается от массива байт или слов - в массиве все элементы одинаковые по размеру. Если бы массивы и структуры были суть одно и то же, но какой смысл было вводить новые абстракции? wink.gif
Я вас не понимаю. В массиве все элементы одинаковые по размеру. Бесспорно. Но точно также одинаковы по размеру и *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)
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 28 2010, 17:23
Сообщение #43


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Если подходить строго, то с массивом в С определены всего 2 операции - sizeof от него, и автоматическое преобразование имени массива в указатель на его нулевой элемент. ВСЕ ОСТАЛЬНЫЕ операции на самом деле производятся именно с этим указателем.


Цитата(Сергей Борщ @ Dec 28 2010, 23:14) *
По поводу объявления/инициализации была оговорка.
В случает ТС разница между *** и **[] будет катастрофическая

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 28 2010, 17:25
Сообщение #44


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 17:55
Сообщение #45


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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.
В любом случае, эти два способа работают по-разному.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 28 2010, 18:06
Сообщение #46


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(ViKo @ Dec 28 2010, 23:55) *
Решил сравнить адресную и индексную арифметику на приведенном выше своем примере.
Результат слегка обескуражил. Обращение к элементу массива с помощью индекса занимает меньше байтов.
Особенность системы команд ARM.
Включите оптимизацию при компиляции, результат должен стать похожим в обоих случаях. Компиляторы обычно довольно умные, что бы автоматически конвертировать индексацию в разъименование указателей и обратно, в зависимости от архитектуры и контекста применения

Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 18:30
Сообщение #47


Универсальный солдатик
******

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



Цитата(XVR @ Dec 28 2010, 23:06) *
Включите оптимизацию при компиляции, результат должен стать похожим в обоих случаях. Компиляторы обычно довольно умные, что бы автоматически конвертировать индексацию в разъименование указателей и обратно, в зависимости от архитектуры и контекста применения

То, что показал - лучшее. Прошелся по всем вариантам оптимизации. На мой взгляд, компилятор не должен быть настолько умным, как вы говорите. sm.gif
Еще попробовал заменить тип переменных в массиве на uint16_t и uint32_t. В первом случае коды для адресной и индексной арифметик сравнялись, а во втором индексная арифметика опять вырвалась вперед.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 28 2010, 18:49
Сообщение #48


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 18:58
Сообщение #49


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 28 2010, 19:03
Сообщение #50


.
******

Группа: Участник
Сообщений: 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) *
В случает ТС разница между *** и **[] будет катастрофическая

Что такое ТС? "В случает ТС"


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 28 2010, 19:11
Сообщение #51


Универсальный солдатик
******

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



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

Насчет скобок - согласен, можно без них. Просто тяжелее воспринимать. Убрал. В книжках их, кстати, пишут. По той же причине.
Насчет взятия элементов с конца массива - упустил из виду. Не сомневаюсь, что результат не изменится. Зря не сомневался sm.gif Начинать-то нужно с нуля, потом инкрементировать счетчик и сравнивать с 10. Стало на 2 байта больше.
А система команд - Thumb-2 называется. Виноват. Имел в виду систему команд от фирмы ARM. Опять же, это чисто качественный пример. Для ARMv4 команды для двух арифметик тоже будут разные.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Dec 28 2010, 19:40
Сообщение #52


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(ViKo @ Dec 29 2010, 00:58) *
Похоже, разработчики ARM специально "подрихтовали" процессор под C.
Все с точностью до наоборот... sm.gif
Большая часть кода С(когда-то написанного) используют адресную арифметику т.к. на
большинстве процессоров/компиляторов это дает выигрыш.
А Ваш пример действительно интересен, надо будет не забыть поиграться с этим
при переносе проекта на кортекс.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 29 2010, 05:26
Сообщение #53


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 29 2010, 05:50
Сообщение #54


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(Сергей Борщ @ Dec 29 2010, 11:26) *
Не верю. Покажите ее.
Посыпаю голову пеплом - разницы действительно нет (за исключением того, что конструкция **[] отказывается компилится). Разница проявляется в другом контексте


2 GetSmart: ТС - это 'Топик Стартер'
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 29 2010, 06:59
Сообщение #55


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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) - это одно и то же. Наоборот, подтверждал. sm.gif А удивляюсь я тому, что известное правило отказываться от индексной арифметики в пользу адресной для ARM не работает. Может быть, для многомерных массивов все "вернется на круги своя"...

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

Должна компилироваться!:) Скорее всего, что-то не так определено.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 29 2010, 16:54
Сообщение #56


Гуру
******

Группа: Свой
Сообщений: 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** []'
Для С аналогично (текст сообщения об ошибке немного другой, но смысл тот же)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 30 2010, 07:21
Сообщение #57


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 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|
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Dec 30 2010, 07:58
Сообщение #58


I WANT TO BELIEVE
******

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



ага, только эти a b c тоже как-бээ массивы указателей должны быть ) у ТС профиль - это массив указателей на подпрофили, а дефайн этот указывает на массив профилей...


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 30 2010, 08:09
Сообщение #59


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



В тему указатели-массивы (накидал примерчик за 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);
}


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Dec 30 2010, 12:04
Сообщение #60


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



36?


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Dec 30 2010, 13:31
Сообщение #61


Универсальный солдатик
******

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



Цитата(sigmaN @ Dec 30 2010, 12:58) *
ага, только эти a b c тоже как-бээ массивы указателей должны быть ) у ТС профиль - это массив указателей на подпрофили, а дефайн этот указывает на массив профилей...

Я отвечал XVR, показал, что компилируется. Что там у TC, не вникал. Не сомневаюсь, что тоже реализуемо.
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th September 2025 - 01:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.02356 секунд с 7
ELECTRONIX ©2004-2016