Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 17
  1. #1
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±

    Оператор char

    Всем привет. У вас спина белая.
    Нередко мне приходилось сталкиваться на просторах форума с фразами типа "массив char", как будто это какой-то особенный вид массивов.
    В данном уроке я постараюсь рассмотреть несколько вопросов по оператору char, по которым у новичков чаще всего возникают заблуждения:
    1. Чем массивы, объявленные с "char" в размере, отличаются от других массивов? Чем отличается их использование?
    2. Для чего предназначено слово "char"? Оно означает какой-то тип данных?
    3. Т.е. чтобы получить нужное кол-во ячеек, достаточно разделить число байт на размер ячейки в байтах (4)? Тогда зачем вообще нужен оператор char, если можно просто делить на 4?


    Итак, начнём разбор полётов:

    1. Чем массивы, объявленные с "char" в размере, отличаются от других массивов? Чем отличается их использование?

    Оператор char влияет лишь на размер массива. Массивы, в размере которых используется char, ничем принципиально не отличаются от других массивов.
    Например, можно объявить массив с указанием char в размере, а потом читать/записывать данные в его ячейки, а не в отдельные байты.
    PHP код:
    new a[12 char]; // "char" означает, что в массиве должно быть достаточно ячеек, чтобы уместить 12 байт.
    // i примет значения от 0 до 12 / 4 - 1 = 2,
    // где 4 - размер ячейки в байтах.
    for (new 0sizeof(a); ++i)
        
    a[i] = i
    Также можно объявить массив без char в размере, но записывать значения в отдельные байты массива:
    PHP код:
    new a[5]; // В массиве 5 ячеек или 5 * 4 = 20 байт
    // В стандартной константе "cellbits" находится количество бит в ячейке, в "charbits" - бит в байте.
    // Количество байт в ячейке можно получить с помощью выражения "cellbits / charbits".
    for (new 0sizeof(a) * cellbits charbits; ++i)
        
    a{i} = i
    Как видите, оператор char абсолютно не влияет на правила обращения с массивом.
    Читать и записывать значения в отдельные байты массива можно даже если в указании его размера не используется char. Главное не словить выход за пределы массива.

    2. Для чего предназначено слово "char"? Оно означает какой-то тип данных?

    Во-первых, это не тип данных, а оператор.
    Это довольно распространённое заблуждение о том, что char означает тип данных размером в 1 байт и нужно пользоваться им для экономии памяти, но в Pawn любые данные занимают 1 ячейку. Кроме того, как уже было сказано выше, char не меняет правил использования массивов.
    Во-вторых, оператор char нужен для того, чтобы узнать, сколько ячеек потребуется для того, чтобы вместить определённое количество байт.
    Например, при размере ячейки в 4 байта, чтобы вместить 12 байт, нужны 3 ячейки.
    И да, применение оператора не ограничено одними лишь массивами:
    PHP код:
    printf("Для хранения %d байт нужно %d ячеек"1212 char); 
    Ещё пример, на этот раз с константой:
    PHP код:
    const NUM_BYTES 12;
    const 
    ARRAY_SIZE NUM_BYTES char;
    new 
    a[ARRAY_SIZE]; 

    3. Т.е. чтобы получить нужное кол-во ячеек, достаточно разделить число байт на размер ячейки в байтах (4)? Тогда зачем вообще нужен оператор char, если можно просто делить на 4?

    Всё немного сложнее, чем кажется. Начнём с того, что недостаточно просто разделить на 4.
    Допустим, у нас есть не 12, а 14 байт. 14 / 4 = 3 ячейки. Но три ячейки хватит только на 3 * 4 = 12 байт, а ещё 2 байта не вместятся.
    Иными словами, при простом делении на 4 не учитывается остаток от деления.

    Оператор char работает следующим образом: перед делением к кол-ву байт добавляется максимально возможный остаток от деления (в данном случае при делении на 4 максимальный остаток - 3).
    Таким образом получаем примерную формулу:
    PHP код:
    X char = (3) / 
    Проверка: (14 + 3) / 4 = 17 / 4 = 4. Четырёх ячеек как раз хватит, чтобы сохранить 14 байт.
    Даже останется место ещё для двух байт, но мы же не можем выделить три с половиной ячейки - только целое количество.

    Кроме того, в разных вариантах Pawn размер ячейки может быть не только 4, но и 2 или 8 байт.
    А потому утвердждение "в 1 ячейке 4 байта" справедливо только для SA:MP и некоторых других приложений/игр, в которых в Pawn установлен именно четырёхбайтовый размер ячеек.
    Например, 8 байт на ячейку можно встретить в проекте VaultMP, а при 8-байтном размере ячейки будет неправильно делить кол-во байт на 4.
    Для решения подобных проблем компилятор предоставляет константы cellbits и charbits, о которых уже было написано выше.
    Разделив кол-во бит в ячейке на кол-во бит в байте можно получить кол-во байт в ячейке.
    В итоге работу оператора char можно описать следующей формулой:
    PHP код:
    X char = (cellbits charbits 1) / (cellbits charbits
    Как вы можете заметить, эта формула совершенно не похожа на простое деление на 4.

    Итак, на сегодня всё. Если у вас есть ещё вопросы по теме, буду рад их выслушать в комментариях.


    Автор: Daniel_Cortez

    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 15 пользователя(ей) сказали cпасибо:
    BadPawn (15.04.2016) DeimoS (01.04.2016) Desulaid (01.04.2016) Edwin (11.10.2016) Nurick (11.04.2016) oukibt (22.08.2020) Outsider (09.10.2017) Profyan (01.04.2016) punkochel (16.10.2022) Seregamil (01.04.2016) vovandolg (01.04.2016) VVWVV (01.04.2016) whale (05.01.2019) [ForD] (01.04.2016) _lizard (06.08.2016)
  3. #2
    Аватар для Profyan
    Пользователь

    Статус
    Оффлайн
    Регистрация
    23.12.2013
    Адрес
    Омск
    Сообщений
    196
    Репутация:
    22 ±
    Немного не про char,но про байты:
    Допустим у нас есть массив на 4 ячейки. В первую(нулевую) ячейку мы записываем число.
    В каждом байте мы можем хранить число < 2^8. И если посмотреть на первые четыре байта, то они будут заполнятся с конца. Т.е сначала 3ий байт,когда он заполнился,то 2. Почему такой порядок?

    И если простая переменная,не массив,занимает в памяти 1 ячейку,то почему мы не можем обратиться к ее байтам?Или как-то можем?



    Любой дурак может написать код, понятный компьютеру. Хороший программист пишет код, понятный человеку
    Мартин Фаулер


    Skype
    profan99
    VK
    click




  4. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от Profyan Посмотреть сообщение
    Немного не про char,но про байты:
    Допустим у нас есть массив на 4 ячейки. В первую(нулевую) ячейку мы записываем число.
    В каждом байте мы можем хранить число < 2^8. И если посмотреть на первые четыре байта, то они будут заполнятся с конца. Т.е сначала 3ий байт,когда он заполнился,то 2. Почему такой порядок?
    В AMX порядок байт от старшего к младшему, т.е. первыми идут самые старшие байты числа.


    Цитата Сообщение от Profyan Посмотреть сообщение
    И если простая переменная,не массив,занимает в памяти 1 ячейку,то почему мы не можем обратиться к ее байтам?Или как-то можем?
    Достаточно записать значение в массив из одной ячейки.
    PHP код:
    new a[] = 0xC0FFEE;
    printf("%02x %02x %02x %02x"a{0}, a{1}, a{2}, a{3}); 
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  5. Пользователь сказал cпасибо:
    Profyan (01.04.2016)
  6. #4
    Аватар для [ForD]
    Пользователь

    Статус
    Оффлайн
    Регистрация
    14.11.2013
    Адрес
    Свердловская обл.
    Сообщений
    688
    Репутация:
    103 ±
    PHP код:
    (12 =) 
    так и должно быть?
    PAWN Compiler делает то, что вы приказали ему сделать, а не то, что вы хотели, чтобы он сделал..

    25% времени в программировании уходит на размышления о том, что пользователь может сделать не так.[HR]/Брайан Хьюмс/





    #FIXSAMP

  7. #5
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Следует, наверное, показать каким образом происходит отличие (например, листинг ассемблера). Ты, возможно, забыл, что знак восклицания тоже упаковывает строку (little-endian), т.е. она записывается так же как и массив c оператором char. Так же ты забыл, что число не может быть больше, чем число 255 (0xff).

    P.S.: прошу прошения, что "тыкаю" (не очень прилично, знаю).
    Последний раз редактировалось VVWVV; 01.04.2016 в 15:02.

  8. #6
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    Следует, наверное, показать каким образом происходит отличие (например, листинг ассемблера). Ты, возможно, забыл, что знак восклицания тоже упаковывает строку (little-endian), т.е. она записывается так же как и массив c оператором char. Так же ты забыл, что число не может быть больше, чем число 255 (0xff).
    Это уже есть в моих набросках для следующего урока. Пока что только разъяснение работы char.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  9. #7
    Аватар для Prolific
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.12.2013
    Сообщений
    116
    Репутация:
    14 ±
    Немного не понял, можно простым языком, полезно ли использовать массив с оператором char или нет?

  10. #8
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от Prolific Посмотреть сообщение
    Немного не понял, можно простым языком, полезно ли использовать массив с оператором char или нет?
    Можно, но нужно знать когда использовать.

  11. #9
    Аватар для Unreal
    Пользователь

    Статус
    Оффлайн
    Регистрация
    24.09.2014
    Сообщений
    133
    Репутация:
    4 ±
    Цитата Сообщение от VVWVV Посмотреть сообщение
    Можно, но нужно знать когда использовать.
    так вопрос был "полезно ли?", а когда тогда надо использовать. Какие рекомендаций ?
    Pro-pawn.ru

  12. #10
    Аватар для VVWVV
    ?

    Статус
    Оффлайн
    Регистрация
    09.07.2015
    Сообщений
    731
    Репутация:
    353 ±
    Цитата Сообщение от Unreal Посмотреть сообщение
    так вопрос был "полезно ли?", а когда тогда надо использовать. Какие рекомендаций ?
    Эта тема связана напрямую с этой.

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •