Циклический сдвиг массива влево с помощью указателей

Сайт не является учебником по программированию. Это только небольшой авторский сборник информации в помощь начинающим программистам.

  Увидел одно задание, сдвинуть все элементы массива влево с помощью указателей. Более менее знаком с массивами и указателями, но оказалось очень полезным (во всяком случае для меня точно) упражнением. Я сразу приведу исходник готового решения, он небольшой, а ниже распишу некоторые моменты
Код C++ Циклический сдвиг элементов массива влево через указатели

Итак.
  Первое с чем пришлось столкнутся — это обработка массива внутри функции, при этом было желание работать с массивом напрямую, а не как с его локальной копией. Решается это достаточно просто. У функции в качестве принимаемых параметров можно указывать указатель на ссылку на массив.

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

  Дальше был вопрос самого алгоритма сдвига массива на несколько позиций используя указатели. Так как имя массива — это адрес первого элемента массива, то используя арифметику указателей можно легко поменять адрес начала на адрес любого из элементов массива. В том как у меня сделано, при смещении элементов сначала одна часть массива сместится влево, затирая начальный участок массива, но так как создается циклический массив, то эти затираемые данные будут нужны, поэтому создается новый массив, в который и копируется затираемый участок. Этот массив потом просто будет добавлен в конец.

  Также полезным является то, что можно увидеть как работать с функцией memmove, с помощью которой легко копируются данные из одного массива в другой.

  Чтобы решить такую задачу нужно обязательно чуть-чуть соображать. Чтобы понять весь механизм лучше всего решить аналогичную задачу со сдвигом элементов в противоположную сторону. Это если кому-то интересно или кто-то учится однозначно будет только на пользу.

Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

11 комментариев: Циклический сдвиг массива влево с помощью указателей

  • Аноним говорит:

    😛

  • Gen говорит:

    В CODE::BLOCK для работы функции memcpy необходимо подключить

    и соответственно using namespace std; и главная функция int main().и все работает на ура.Спасибо. 😛

  • admin говорит:

    В CodeBlock

  • Gen говорит:

    Эти коды идентичны? И как лучше писать с прототипами или как у вас?

    • admin говорит:

      Да, идентичны. В маленьких программах Принципиальной разницы нет, но в больших проектах использование прототипов может сильно улучшить читаемость кода и ускорить компиляцию проекта.
      Я такие вещи не описывал, но это можно найти в любом популярном поисковике, задав вопрос: «Зачем нужны прототипы». Многие авторы книг используют прототипы, при этом не особо углубляясь в механизм их работы. Так, например, в одном из изданий Дейтелов есть интересная ошибка, связанная с прототипами (интересна с той точки зрения, что новичкам её очень сложно исправить). Там описывается пример моделирования колоды карт и этот пример описан на сайте.
      Я это к тому, что всё от ситуации зависит. Если что-то есть в языке, то не обязательно это это что-то использовать везде и повсюду, лучше это что-то уметь применять и применять только тогда когда это действительно нужно.
      Вот как-то так, наверное.

      • admin говорит:

        Пример описан не в виде ошибки и ее исправления, а просто в виде правильного примера. Издание я не помню.

  • Gen говорит:

    Угловые скобки не принимает ни при каком раскладе.инклуды iostream,mem.h,stdlib.h

  • Gen говорит:

    Спасибо!Растолковали стало понятнее.Речь об ошибках не идет, ошибок нет оба кода работают одинаково верно.

  • Максим говорит:

    передавать массив по ссылке тут нет никакой надобности, достаточно было локальной копии указателя на начало массива. если сотрёте амперсанд в описании точно также всё будет отлично работать, даже со статичными массивами. и даже можно удалить 30 строчку, так как это будет локальной копией.

    грубейшие ошибки в 28 строке
    1- это использование мемкопи для пересекающихся областей памяти, если области накладываются то нужно использовать memmove
    2- вы выходите за границу массива, копировать нужно только N-step элементов.

    «В коде видно, что в функции сдвига сначала идет смещение указателя на несколько позиций, потом идет возвращение его на исходную. Делается это для корректного удаления выделенной беглецу памяти, так как уже было описано, память за массивом не бегает.»

    тут дело не только в «утечке памяти» вы поломали внешнюю переменную, указывавшую на начало массива, и вам необходимо её починить, это одна из причин почему передавать данные по ссылке без острой на то необходимости считается плохим тоном..

    • admin говорит:

      Я достаточно часто передавал данные по ссылке, хотя иногда зазря. Не могу этого отрицать.
      Вы скорее всего тут не совсем точно выразились. Может и дурной тон с ссылками, но большинство компиляторов умеют игнорировать передачу по ссылке в тех случаях когда передача по ссылке не имеет смысла.
      То, что я говорю: «Неточно выразились» — просто выражение: «острая на то необходимость» достаточно расплывчато. А может в меня стрельнули бы и убили, если бы я не передавал данные по ссылке. Или может обещали заплатить миллион, если я передам по ссылке. А это всё — острая необходимость.
      =================
      И я с вами кое в чем не согласен.
      Здесь дурной тон не передача по ссылке, а то, что я ломаю внешнюю переменную, которую ломать не должен.
      ==================
      я это достаточно давно писал и честно говоря не врубаюсь пока, как выхожу за границу массива, пока не врублюсь, исправлять этот момент не стану.
      ==================
      по поводу того, что можно убрать 30 строчку. Эта строчка важна с той точки зрения, что должна показывать, что то, что мы вытворяем, иногда нужно откатывать. Здесь это маловажно, но зато актуально становится при работе с памятью. И вы должны хорошо понимать к чему я клоню.

      • admin говорит:

        По поводу выходов за границы. Посмотрел, подумал, но так и не увидел в чем проблема.
        В 28 строке я копирую step элементов. Просто применяю арифметику указателей, чтобы копировать не с первого элемента по индексу, а начиная с элемента по индексу (N-step). Т.е. последние step элементов.

Поиск

 
     

Яндекс.Метрика

НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Классическая ошибка, которую совершают проектировщики абсолютно надежных систем, – недооценка изобретательности клинических идиотов.

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок