На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> sizeof к массиву
    вопрос
    ExpandedWrap disabled
      void do_(int d[4] = {}) {
       
          printf("%d",sizeof d);
       
      }


    тут выводит 8 независимо от размера.

    но
    ExpandedWrap disabled
      main(){
      int df[40];
      printf("%d", sizeof df);
          }

    а вот тут 160 почему?
      Потому что массивы по значению никогда не передаются. Всегда по указателю на первый элемент. Это сбивает с толку, да, потому как размер массива просто игнорируется, как будто бы там пусто:
      ExpandedWrap disabled
        void do_(int d[] = {})
      или даже
      ExpandedWrap disabled
        void do_(int *d = {})

      Но ты можешь передать ссылку на массив:
      ExpandedWrap disabled
        int init_d[] = {1,2,3,4};
        void do_(int (&d)[4] = init_d)
      Заодно это ярко проявит два страшенных бага в твоём коде:
      • do_() желает работать к четырёхэлементным массивом, но значение по умолчанию не имеет элементов;
      • значение по умолчанию формируется в точке вызова и потому является rvalue, однако передаётся в неконстантное lvalue;
      Я конечно понимаю, что пример синтетический, но не с потолка ж взят.
        в первом случае размер указателя

        но во втором массива.


        а в чем смысл передавать ссылку на массив если массив передается по указателю?

        или
        получается это единственный способ узнать размер стат массива
        ExpandedWrap disabled
          template<size_t n=4>
          void do_(int (&d)[n])
        Сообщение отредактировано: maxutov -
          Смысл в отсутствии сведения массива к указателю. Обычно такое сведение не мешает, но если мешает, то да, передать по ссылке можно, при этом размер массива выводится в точке вызова и сохраняется в типе параметра. Затем можно передать в обобщённую функцию:
          ExpandedWrap disabled
            void do_impl(int *d, size_t n);
             
            template<size_t N>
            void do_(int (&d)[N])
            {
              do_impl(d, N);
            }


          Добавлено
          P.S. Ссылки на массивы не сводятся, сводятся только непосредственно массивы. И это не будет работать с динамическими, для которых размер при компиляции не известен.

          Добавлено
          P.P.S. Также имеет смысл посмотреть в сторону стандартного контейнера std::array<>:
          ExpandedWrap disabled
            void do_(std::array<int, 4> d)
            {
              /* ... */
            }
          Его и по значению передать можно, как в примере

          Добавлено
          А вместо динамических массивов std::vector<>, его тоже можно по значению, если приспичит. Оба контейнера имеют метод size(), владеют своими элементами, знают, когда их копировать/разрушать, сами управляют памятью под них, могут при желании следить за корректностью индексации, т.е. никаких ошибок с памятью. Настоятельно не рекомендую в Плюсах использовать Cшные привычки.
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0287 ]   [ 16 queries used ]   [ Generated: 28.04.24, 06:26 GMT ]