Перейти к содержанию
    

Научите как правильно передавать массив в функцию

20 минут назад, ДЕЙЛ сказал:

my_array может восприняться как указатель на начало массива.

В операции sizeof()? Ну нет:wink:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, ДЕЙЛ сказал:

my_array может восприняться как указатель на начало массива.

Цитата

Пока только 6 лет непрерывного кодинга на Си, но обязательно изучу язык!

Как-то эти два высказывания не коррелируют друг с другом. :biggrin:

Да и с вздором о:

3 часа назад, ДЕЙЛ сказал:

Передача нескольких параметров в функцию - это дурной тон.

тоже. :unknw:

2 часа назад, ДЕЙЛ сказал:

Параметр передаётся обычно через регистр процессора, число которых ограничено. Если параметров будет слишком много

3 - это "слишком много"? :shok: Может лучше почитать "соглашения о вызовах" вашего компилятора?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хотя в делфях по 2 и 3 параметра есть в готовых функциях. Я морально устарел со своими представлениями.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, ДЕЙЛ сказал:

Лучше перебдеть и накодить под самый тупой компилятор. my_array может восприняться как указатель на начало массива.

Ну вы, блин, даёте) Новый Год уже начали праздновать?))))

2 часа назад, ДЕЙЛ сказал:

Упрощение жизни компилятору кашу не испортит.

Проблема в том, как упрощать? Вы же не думаете, что ваши примеры - это единственные примеры упрощения? Вы знаете, они ещё хитро умеют сворачивать условные операторы с кучей сравнений (заменять на операции сдвига вместо арифметики и логики), разворачивать циклы, инлайнить функции и делать кучу другой умной работы.

25 минут назад, ДЕЙЛ сказал:

Хотя в делфях по 2 и 3 параметра есть в готовых функциях.

А при чём здесь дельфи? Её под армы нет, а в тем армы обсуждаются...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если у кого-то много параметров передавать нужно- то можно и про стуктуры подумать.

Очень удобно и универсально. И в функцию легко передавать(указатель), и в очередь многозадачки легко засовывать (хоть целиком, хоть только указатель на). Еще и отлаживать просто, и модифицировать такую программу одно удовольствие. Ну и очень понятно выглядит в исходниках.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 минут назад, Ruslan1 сказал:

Ну и очень понятно выглядит в исходниках.

Ага. Два экрана запихивания в структуру, за которыми теряется собственно вызов функции.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если на плюсах, то можно использовать шаблонную функцию:

template<std::size_t N> void f(int (&arr)[N]) 
{
    cout << "size: " << N << endl;
    for(int i = 0; i < N; ++i)
    {
        cout << arr[i] << endl;
        
    }
}

int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 };

int main()
{
    f(a);
    return(0);
}

Out log:

size: 8
1
2
3
4
5
6
7
8

Но объявление массива должно быть в области видимости, иначе компилятор не сможет вычислить его размер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, dxp сказал:

Если на плюсах, то можно использовать шаблонную функцию:

Я делаю две функции, чтобы не раздувать код для каждого размера массива:

void f(int * arr, size_t size)  
{
    cout << "size: " << size << endl;
    for(int i = 0; i < size; ++i)
    {
        cout << arr[i] << endl;
        
    }
}

template<std::size_t N> inline void f(int (&arr)[N])
{
    f(&arr, N);
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 hours ago, Сергей Борщ said:

Ага. Два экрана запихивания в структуру, за которыми теряется собственно вызов функции.

А что, еще кто-то хранит много взаимосвзязанных (используемых вместе) данных не в структурах?

 

Если данные связаны между собой (например, массив и указатели записи-чтения в нем) - то они и до вызова функции храняться всегда в структуре, а не как отдельные переменные. Компилятору все равно, работать с wrpnt и buf[] или с transmit.wrpnt и transmit.buf[].

 

А если данные несвязаны и поэтому не собраны в структуру- то нужно подумать, почему они в одну функцию передаются, может нужно разбить функцию на несколько?  Да и не проблема передать в функцию два или пять указателей на разные используемые структуры, если уж нужно. Но если эти пять структур используются вместе более одного раза- я бы собрал указатели на них в одну новую структуру :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно пойти ещё дальше, в этой же структуре хранить указатель на функции, которые с ней работают.

Ещё немного, и C++ заново изобретем.

А идеология структурного программирования на C предполагает, что грамотно структурированная программа так разделена на функции, что каждая из них делает какое-то одно осмысленное действие, и соответственно, не требует на входе множества разнородных параметров.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

25 minutes ago, gerber said:

Можно пойти ещё дальше, в этой же структуре хранить указатель на функции, которые с ней работают.

Ещё немного, и C++ заново изобретем.

Кстати да, и указатели на функции обработки тоже часто храню в структурах. Получается быстро работающий код, в котором все "экраны запихивания в структуры" делаются однажды на этапе инициализации.

К своему стыду, так и не перешел к использованию С++ как языка с его идеологией. Сначала это были объективные причины, а теперь просто нет желания что-то менять в этой жизни, не вижу профита от таких потрясений. Наверное пенсия скоро- не хотят нейроны на новые орбиты выходить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29.12.2020 в 10:50, ДЕЙЛ сказал:

void func1(uint8_t *buf_1);
void func2(uint8_t *buf_2);

 

#define SIZE_BUF 50

 

uint8_t my_array[SIZE_BUF];

 

void main()
{
  func1(my_array);
}

 

void func1(uint8_t *buf_1)
{
  memset(buf_1, 0x00, sizeof(uint8_t) * SIZE_BUF);
  func2(buf_1);
}

 

void func2(uint8_t *buf_2)
{
  memset(buf_2, 0xFF, sizeof(uint8_t) * SIZE_BUF);
}

Формально вышеописанный код соответствует коду ниже, если рассматривается только программа целиком, так как есть цепочка вызовов: main() -> func() -> func2 (), где передается  my_array


void func1(void);
void func2(void);

 

#define SIZE_BUF 50

 

uint8_t my_array[SIZE_BUF];

 

void main(void)
{
  func1();
}

 

void func1(void)
{
  memset(my_array, 0x00, sizeof(my_array));
  func2();
}

 

void func2(void)
{
  memset(my_array, 0xFF, sizeof(my_array));
}

Изменено пользователем uk_denis

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

16 минут назад, uk_denis сказал:

2) При работе с не глобальными объектами вернет размер указателя на элемент массива...

 Серьезно? Код

void func(void)
{
  uint8_t arr[10];
  printf("%u", sizeof(arr));
}

почему-то печатает 10, а не 4:bye:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

42 минуты назад, Arlleex сказал:

 Серьезно? Код


void func(void)
{
  uint8_t arr[10];
  printf("%u", sizeof(arr));
}

почему-то печатает 10, а не 4:bye:

sizeof применен к локальному массиву на стеке. Это не глобальный объект. Локальные объекты функции не являются глобальными объектами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, uk_denis сказал:

Это не глобальный объект.

Я правильно вас понимаю, что если вынести объявление массива arr[10] из функции func() и сделать его глобальным, то sizeof(arr) вернёт уже размер указателя?

6 минут назад, uk_denis сказал:

sizeof применен к локальному массиву на стеке. Это не глобальный объект.

А разве вы не то же самое говорили, цитирую ниже:

1 час назад, uk_denis сказал:

При работе с не глобальными объектами вернет размер указателя на элемент массива,

Так почему же пример уважаемого @Arlleex вернул 10, а не 4?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...