|
Вопрос по размеру массива |
|
|
|
Mar 17 2009, 16:53
|
Знающий
   
Группа: Свой
Сообщений: 517
Регистрация: 7-02-06
Пользователь №: 14 073

|
Здравствуйте, уважаемые коллеги, помогите пожалуйста. В функции мне нужно знать количество элементов массива, делаю это с помощью макроса SizeObj, а он в данной функции не работает. Компилятор - Кейл. Можно было бы передавать размер массива в саму функцию, но это не то. Вызывается эта функция часто и для массивов разной длины, потому хотелось лаконичнее, да еще бы с передачей в функцию указателя на массив, но по указателю на массив я не могу определить размер. Как бы решить эту задачку. Код typedef struct { int X; int Y; char dX; char dY; } TG_Buttons;
TG_Buttons G_But [] = { Bt_Menu_X, Bt_Menu_Y, Bt_Menu_L, Bt_Menu_H, Bt_Prn_X, Bt_Prn_Y, Bt_Prn_L, Bt_Prn_H, Bt_Rec_X, Bt_Rec_Y, Bt_Rec_L, Bt_Rec_H };
#define SizeObj(a) (sizeof(a) / sizeof(a[0]))
void Set_Arr_But (TG_Buttons G_Bt []) { INT16U i; TG_Buttons *pG_But = &G_Bt [0]; float k_Y; k_Y = (float)Max_TSC_Y / LCD_YSIZE;
for (i=0; i < SizeObj(G_Bt); i++) { pG_But->Y = ceil ((pG_But->Y + pG_But->dY/2) * k_Y); // pG_But ++; } } // Set_Arr_Buttons (void)
|
|
|
|
|
Mar 17 2009, 18:44
|

Местный
  
Группа: Участник
Сообщений: 219
Регистрация: 20-11-07
Пользователь №: 32 484

|
Цитата(Vladimir_T @ Mar 17 2009, 20:53)  Как бы решить эту задачку. Код template <class T, unsigned N> void kisa(T (&a)[N]) { printf("%p %u\n", a, N); }
int main(int argc, char* argv[]) { int a[7]; char q[11];
kisa(a); kisa(q);
return 0; }
|
|
|
|
|
Mar 18 2009, 02:07
|
self made
   
Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795

|
Цитата(sergeeff @ Mar 17 2009, 15:38)  Да, действительно, в VS2008 - без проблем. Изящно! Это не изящно, это уродство. Вы представляете как темплайт реализован в компиляторе? Для каждой длины массива с которой киса вызывается, будет сгенерирована *отдельная* функция. Если киса большая, как-то неразумно.
Сообщение отредактировал ar__systems - Mar 18 2009, 02:12
|
|
|
|
|
Mar 18 2009, 04:50
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 120
Регистрация: 17-06-04
Пользователь №: 37

|
Добавьте в "TG_Buttons G_But []" признак конца - ещё 1 элемент со значением Х = -1 (ну или Y). тогда цикл у Вас будет выглядеть так: Код for (i=0; pG_But->X >= 0; i++) { pG_But->Y = ceil ((pG_But->Y + pG_But->dY/2) * k_Y); // pG_But ++; } Ведь Вас не смущает, что строка заканчивается символом '\0'?
--------------------
Если зайца бить, его можно и спички научить зажигать Сколько дурака не бей - умнее не будет. Зато опытнее
|
|
|
|
|
Mar 18 2009, 05:14
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(Vladimir_T @ Mar 17 2009, 21:53)  Можно было бы передавать размер массива в саму функцию, но это не то. Да кто Вам такое сказал? Как раз то самое. Самое простое и самое широкоиспользуемое явление -- передавать в функцию указатель вместе с размерностью массива. Посмотрите на библтотечные функции и убедитесь, что это так и делается. Цитата Вызывается эта функция часто и для массивов разной длины, потому хотелось лаконичнее, да еще бы с передачей в функцию указателя на массив А эта "хотелка" (требование) еще раз подтверждает, что Вам надо делать именно так, как сказано выше -- передавть в функцию два параметра. Вы видели как дети рисуют картины? Чем детские картины отличаются от картин взрослых? -- Дети стремятся выразить себя не в точности отображения, а в насыщеености и яркости красок. Ни один художник не станет писать свою картину флуоресцентными маркерам. Хотя, в жизни иногда встречваются типа Малевичей... Не важно. Вы понимаете о чем я толкую? Выпендрежный стиль программирования говорит не крутости программиста, а скорее о его кудрявости. Чем больше всяких трюков, тем сложнее (== дольше) отлаживать прогу и сопровождать ее после выхода в свет. Если Вы "играетесь", и результат Вашей работы не имеет никакого значени, то можете делать все что Вам заблагорассудится. Если же Вы намерены делать "по-взрослому", забудьте про витееватость. Делайте как можно проще и понятнее. А свои секреты ппрограммирования защищайте другими способами. Возвращаясь к вашему коду, скажу, что sizeof -- это оператор, а не функция. Т.е. после компиляции на его месте Вы не найдете вызова какой-то функции, там будет готовая константа, число. sizeof вычисляется на этапе компиляции. Поэтому, если в Вашей программе размеры передаваемых в функцию массивов одинаковые, то использовать вычисления размера не имеет смысла. Если же размеры массивов разные, то вычисление размера следует производит пере вызовом функции и передвать его как еще один параметр. Конечно, если Вам Ваша религия запрещает использовать дополнительные параметры при вызове функции, то, в принципе, у Вас еще есть две возможности сказать функции о размере массива. 1. Создать глобальную переменную (или локальную файловую перемменную, если все действие у Вас производится в одном и том же файле) и через нее сообщать вызываемой функции размерность массива. 2. Создать еще одну структуру из двух элементов: 1) указателя на массив и 2) числа -- размерности этого массива. И затем передавать в свою функцию эту структуру. Замечу, что эти два способа работать будут. Но это не есть "кошерно", хотя смотртся круто. Делайте как можно проще и понятнее. Такой подход выгоднее со всех точек зрения. И это подтверждается практикой. Мы все когда были на Вашем месте, и тоже не знали как правилно делать. Почитайте K&R, почитайте Страуструпа. И удачи Вам в освоении языка!
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 18 2009, 08:49
|

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

|
Цитата(zhevak @ Mar 18 2009, 07:14)  Если же размеры массивов разные, то вычисление размера следует производит пере вызовом функции и передвать его как еще один параметр. А еще можно объединить этот способ с вариантом имени meistera: сделать шаблон "киса" встраиваемой функцией-оберткой, задача которой - подставить количество элементов вторым параметром при вызове реальной функции: Код template <class T, unsigned N> inline void kisa(T (&a)[N]) { Set_Arr_But (a, N); } В этом случае накладных расходов не будет - уникальное тело kisa для каждого набора параметров будет идентично ручному указанию двух параметров.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 18 2009, 08:50
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(zhevak @ Mar 18 2009, 08:14)  Самое простое и самое широкоиспользуемое явление -- передавать в функцию указатель вместе с размерностью массива. +10^10 Он не там макрос организовал: Код void somefunc_code( sometype *ptr, size_t obj_size, size_t elem_size);
#define somefunc (obj) somefunc_code(&obj,sizeof(obj),sizeof(obj[0])) Теперь результат выпендрежа детерминирован, т.к. работает только с объектами статической компиляции. Для кучи уже надо не лениться и указывать тип объекта. Тут не лаконично
|
|
|
|
|
Mar 18 2009, 09:40
|

Знающий
   
Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065

|
Цитата(richie @ Mar 18 2009, 13:34)  Поэтому, просто присоединюсь! Не возражаю. Welcome! Цитата(Сергей Борщ) А еще можно объединить этот способ с вариантом имени meistera: сделать шаблон ... Да, но... У Vladimir_T ничего не сказано про язык программирования. Судя по исходнику, он пишет под счистым С, а не в С++. Поэтому решение с использованием шаблонов тут как-то не совсем верное получается. А, вообще, где сам топикстартер? А то мы как всегда между собой бурно обсуждаем тему "от кого там Клавка родила" (С), а реальное-то состояние дел совсем другое.
--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
|
|
|
|
|
Mar 18 2009, 11:39
|
self made
   
Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795

|
Цитата(zhevak @ Mar 18 2009, 00:14)  Делайте как можно проще и понятнее. Такой подход выгоднее со всех точек зрения. И это подтверждается практикой. Yep, это называлось KISS-принцип в одной книжке --- Keep It Simple, Silly  Еще один + к вашему посту. ps/ Я вообще в шоке от того, что начинающего программера пустили программировать на ембеддед девайс....
Сообщение отредактировал ar__systems - Mar 18 2009, 11:42
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|