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

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> Помогите советом. I2C, Мож кто сталкивался.
mrcashe
сообщение Jul 1 2007, 08:35
Сообщение #46


Участник
*

Группа: Участник
Сообщений: 17
Регистрация: 21-07-06
Из: Владивосток
Пользователь №: 18 987



Цитата
Подскажите спецы кто как работает в Си. Можно работать с массивами и указателями. Что эффективней?

Я стараюсь работать только с указателями. При программировании для МК это несколько экономит ресурсы. Допустим, есть некая структура:
Код
typedef struct { int id; void * p; } some_struct_t;


и есть некая константа, задающая размер буфера (читай: массива):
Код
enum { some_buffer_size = 20 };


Разместим сам буфер:
Код
some_struct_t some_buffer[some_buffer_size];


Теперь вариант перебора с применением индекса:
Код
int i;
for (i = 0; i < some_buffer_size; ++i) {
        printf("%i %p\n", some_buffer[i].id, some_buffer[i].p);
}


Перебор с применением указателя:
Код
some_struct_t * p;
for (p = some_buffer; p < some_buffer+some_buffer_size; ++p) {
        printf("%i %p\n", p->id, p->p);
}


Как видим, в первом случае индексирование выполняется дважды за цикл, т.е. всего 40 раз! А что есть индексирование? Это умножение(!) индекса на размер элемента массива и суммирование его с указателем на массив. Конечно, в случае массива символов размер элемента массива == 1, так что можно просто прибавлять индекс к адресу массива, но в случае массивов с размером элементов в 5 байт придётся именно умножать.
Во втором же случае размер элемента массива просто прибавляется к текущему значению указателя, что может быть на порядок (а то и 2 порядка) эффективнее.
С другой стороны, если не требуется итерация по всему буферу, а нужен именно произвольный доступ к элементу с определённым индексом, то можно с одинаковым успехом воспользоваться обоими методами, как и показал sensor_ua.

Цитата
Массив имеет длину и её можно узнать.

Это что-то новое. Размер массива в Си, вообще говоря, невозможно узнать динамически. Соответственно, код, сгенерированный компилятором, не имеет возможности детектировать выход за пределы массива. Если Вы имеете ввиду sizeof() , то он возвращает размер объекта в байтах, что обычно не то, что нужно в повседневной жизни. Более того, полагаться на этот оператор просто опасно. В различных компиляторах он может выдавать различные значения благодаря различному выравниванию элементов. Если массив размещается статически, то всегда заводите константу, содержащую его размер и пользуйтесь только ею для задания и определения размера массива. Если массив размещается динамически, то определите переменную (а ещё лучше - функцию) для определения его размера. Для изменения размера определите соотвествующую функцию.
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Jul 1 2007, 10:36
Сообщение #47


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Это что-то новое. Размер массива в Си, вообще говоря, невозможно узнать динамически. Соответственно, код, сгенерированный компилятором, не имеет возможности детектировать выход за пределы массива. Если Вы имеете ввиду sizeof() , то он возвращает размер объекта в байтах, что обычно не то, что нужно в повседневной жизни. Более того, полагаться на этот оператор просто опасно. В различных компиляторах он может выдавать различные значения благодаря различному выравниванию элементов. Если массив размещается статически, то всегда заводите константу, содержащую его размер и пользуйтесь только ею для задания и определения размера массива. Если массив размещается динамически, то определите переменную (а ещё лучше - функцию) для определения его размера. Для изменения размера определите соотвествующую функцию.

Это относится к категории вредных советов. Действительно sizeof - оператор, вычисляемый во время компиляции. Действительно может давать значение с учётом утечек памяти при выравнивании. Нормальные компиляторы позволяют указывать явно что и как выравнивать. Во время компиляции он превращается в целую константу, значение которой равно размеру типа или объекта (в байтах). Ещё - в C89 и C++ действительно не поддерживаются массивы переменной длины, но в С99 всвязи с введением массивов переменной длины применение sizeof к таковым приводит в к тому, что значение sizeof получает во время выполнения. Что касается контроля выхода за пределы - тут без наличия этих величин пределов в Си нечего делать. Что касается "нужного в повседневной жизни", то, как понимаю имеется в виду sizeof(array)/sizeof(array[0]) - ничего сдесь нет сложного - классический пример.


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
defunct
сообщение Jul 1 2007, 13:09
Сообщение #48


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(mrcashe @ Jul 1 2007, 11:35) *
В различных компиляторах он может выдавать различные значения благодаря различному выравниванию элементов. Если массив размещается статически, то всегда заводите константу, содержащую его размер и пользуйтесь только ею для задания и определения размера массива.


Как уже отметил sensor_ua, не надо заводить никаких констант.
Гораздо безопаснее применять макрос
#define COUNT( arr ) ( sizeof( arr ) / sizeof( (arr)[0] ) )


Цитата
Как видим, в первом случае индексирование выполняется дважды за цикл, т.е. всего 40 раз!

для процессоров таких как AVR, компилятор соптимизирует операции индексирования. (добавит неявный указатель на структуру)

Для процессоров с индексной адресацией, абсолютно не важно сколько раз происходит индексирование:

MOV eax, [ebx + esi * x + offset]
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 1 2007, 13:31
Сообщение #49


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(defunct @ Jul 1 2007, 16:09) *
Для процессоров с индексной адресацией, абсолютно не важно сколько раз происходит индексирование:
MOV eax, [ebx + esi * x + offset]

Справедливости ради smile.gif x может быть только степеню двойки sad.gif, ну и такты кушает такая адресация.
Ну а с оптимизацией, действительно дело обстоит в большинстве случаев действительно хорошо.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Jul 1 2007, 15:47
Сообщение #50


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Спасибо.
Доступно, внятно и чётко. Короче похоже это тот вопрос, по которому все уже определились. smile.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 05:36
Рейтинг@Mail.ru


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