Арифметика над указателями

Тема в разделе "LANGS.C", создана пользователем Ronin_, 20 апр 2017.

  1. Ronin_

    Ronin_ Active Member

    Публикаций:
    1
    Регистрация:
    24 дек 2016
    Сообщения:
    252
    Всех приветствую!

    Вопрос ради теоретического интереса.

    Допустим есть двухмерный массив указателей на строки:

    Код (C):
    1.     char *langs[][2] = {
    2.         {"C++", "C"},
    3.         {"javascript", "python"},
    4.         {"html", "css"},
    5.         {NULL, NULL}
    6.     };
    Как мне получить второй элемент вложенного массива с помощью арифметики над указателями не прибегая к оператору квадратных скобок?
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Код (C):
    1. char* value = *(*(langs + 1) + 1);
     
    Ronin_ нравится это.
  3. Ronin_

    Ronin_ Active Member

    Публикаций:
    1
    Регистрация:
    24 дек 2016
    Сообщения:
    252
    rmn, вариант. Ещё у можно с помощью двухмерной непрямой адресации обращаться к первому элементу вложенного массива.

    Код (C++):
    1. char *res = **langs
    Или чтобы получить первый символ вложенного массива первого элемента.

    Код (C++):
    1. char res = ***langs
     
  4. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    А кто-нибудь что-нибудь знает о том, обязан ли компиллер хранить многомерные массивы непрерывным куском памяти без паддингов? :acute:
     
  5. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    _DEN_,
    Да, элементы массива будут непрерывным куском и к ним можно обращаться по одномерному индексу [ z*depth + y*width + x ]. Если, конечно, добрый дядя, пишущий модный молодежный фреймворк, не перегрузит глобально операторы, чтобы логика их работы не была похожа на мерзкую сишечку :)
     
    UbIvItS нравится это.
  6. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    То, что они "будут" - это понятно. Речь не о практической стороне, а о стандарте. Смысл в том, чтобы не словить неприятный сюрприз, когда код будет скомпилен на какой-то новой (возможно экзотической) платформе.
     
  7. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    _DEN_,
    Стандарт не читал, но верую, что N-мерные массивы там определяются как одномерные, линейные и непрерывные (вся эта мерность существует только во время компиляции).
     
  8. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    Стандарт говорит: "Юзой смело, сюрпризов не будет".
     
  9. CurryHowardIsomorphism

    CurryHowardIsomorphism Member

    Публикаций:
    0
    Регистрация:
    13 май 2017
    Сообщения:
    97
    Обязан. По стандарту, sizeof массива должен быть равен произведению размера массива на sizeof элементов. Так что, места для дополнительных паддингов (кроме тех, которые есть в элементах) не остаётся.
     
  10. CurryHowardIsomorphism

    CurryHowardIsomorphism Member

    Публикаций:
    0
    Регистрация:
    13 май 2017
    Сообщения:
    97
    Не размера массива, а числа элементов, я это хотел написать.
     
  11. CurryHowardIsomorphism

    CurryHowardIsomorphism Member

    Публикаций:
    0
    Регистрация:
    13 май 2017
    Сообщения:
    97
    То, что они хранятся непрерывно, не разрешает к ним обращаться по одномерному индексу.
     
  12. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Компилятор может сделать все что хочет, например распределить массив на регистры. Главное, чтобы наблюдаемое поведение не изменилось. Т.е., если вопрос в том, можно ли к нему обращаться как к одномерному, то да, можно.
     
    Последнее редактирование: 17 апр 2018
  13. CurryHowardIsomorphism

    CurryHowardIsomorphism Member

    Публикаций:
    0
    Регистрация:
    13 май 2017
    Сообщения:
    97
    Как?
     
    Последнее редактирование: 17 апр 2018
  14. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.087
    зависит от компиля, но дажЬ ежель зараза тип:crazy: ЫнЪТЭЛЭКЪТЪ являет тебе, то имеется обходной вариант..
    upload_2018-4-17_12-17-37.png
    https://gcc.godbolt.org/
     
  15. CurryHowardIsomorphism

    CurryHowardIsomorphism Member

    Публикаций:
    0
    Регистрация:
    13 май 2017
    Сообщения:
    97
    Это на каком языке написано?
     
    Последнее редактирование: 17 апр 2018
  16. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.087
    однако, пахать должно практически везде :)
    вообще-то не каждый компиль поддерживает многомерные массивы, тч сий способ наиболее действенный для общего случая.
     
  17. CurryHowardIsomorphism

    CurryHowardIsomorphism Member

    Публикаций:
    0
    Регистрация:
    13 май 2017
    Сообщения:
    97
    Меня интересует не "компиль", а язык C++.
     
  18. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.087
    I$t€№¥ ГЛАГОЛИШЬ :laugh1::laugh2::laugh3::good2::rofl:
     
  19. UbIvItS

    UbIvItS Well-Known Member

    Публикаций:
    0
    Регистрация:
    5 янв 2007
    Сообщения:
    6.087
    исходя из логики "безопасного" кода, действительно акь-БЭ актуально разделять одномерные и многомерные массивы. Однако, из сией же логики нужно полностью запрещать "сырые" указатели :grin:
     
  20. Andrei

    Andrei Member

    Публикаций:
    0
    Регистрация:
    13 апр 2018
    Сообщения:
    322
    А как описать указатель на реальную память на адрес 0x0b800.
    Вот так правильно будет ?
    char far *vidmem = (char far *) 0x0B800
    А теперь дать смещение 10 и записать в ячейку памяти на которую указывает указатель 67h ...
    Пробовал вот так
    vidmem[10]=67h, не работает ....

    Компилируется без ошибок но не работает (((