Приведение символа к беззнаковому короткому тексту:что происходит за кулисами?

StackOverflow https://stackoverflow.com/questions/402616

  •  03-07-2019
  •  | 
  •  

Вопрос

Учитывая это поле:

char lookup_ext[8192] = {0}; // Gets filled later

И это заявление:

unsigned short *slt = (unsigned short*) lookup_ext;

Что происходит за кулисами?

Lookup_ext[1669] возвращает 67 = 0100 0011 (C), Lookup_ext[1670] возвращает 78 = 0100 1110 (N), а Lookup_ext[1671] возвращает 68 = 0100 0100 (D);однако slt[1670] возвращает 18273 = 0100 0111 0110 0001.

Я пытаюсь перенести это на C#, поэтому помимо простого выхода из этой ситуации мне также интересно, что здесь происходит на самом деле.Давненько я регулярно не использовал C++.

Спасибо!

Это было полезно?

Решение

Утверждение, которое вы показываете, не приводит к беззнаковому короткому символу, оно приводит к указатель к символу к указатель на неподписанное короткое замыкание.Это означает, что обычные арифметические преобразования указываемых данных не будут происходить и что базовые данные char будут просто интерпретироваться как беззнаковые короткие данные при доступе через slt переменная.

Обратите внимание, что sizeof(unsigned short) вряд ли будет один, так что slt[1670] не обязательно будет соответствовать lookup_ext[1670].Это более вероятно, если, скажем, sizeof(unsigned short) два - соответствовать lookup_ext[3340] и lookup_ext[3341].

Знаете ли вы, почему исходный код использует этот псевдоним?Если в этом нет необходимости, возможно, стоит попытаться очистить код C++ и убедиться, что поведение не изменилось, прежде чем его портировать.

Другие советы

Если я правильно понимаю, преобразование типов будет конвертировать массив символов размером 8192 в короткий массив int размером в половину этого размера, то есть 4096.

Поэтому я не понимаю, что вы сравниваете в своем вопросе.slt[1670] должен соответствовать Lookup_ext[1670*2] и Lookup_ext[1670*2+1].

Ну, это заявление

char lookup_ext[8192] = {0}; // Gets filled later

Создает массив локально или нелокально, в зависимости от того, где находится определение.Инициализируя его таким образом, агрегатный инициализатор инициализирует все его элементы нулями (первый явно, остальные неявно).Поэтому мне интересно, почему ваша программа выводит ненулевые значения.Если заполнение не происходит до чтения, это имеет смысл.

unsigned short *slt = (unsigned short*) lookup_ext;

Это будет интерпретировать байты, составляющие массив, как короткие беззнаковые объекты при чтении из цели этого указателя.Строго говоря, приведенное выше поведение является неопределенным, поскольку вы не можете быть уверены, что массив выровнен подходящим образом, и вы будете читать из указателя, который не указывает на тип исходного указываемого типа (unsigned char <-> unsigned short).В C++ единственный переносимый способ прочитать значение из какого-либо другого модуля (простые старые данные.все структуры и простые типы, которые возможны и в C (например, short), вообще говоря) — это использование таких библиотечных функций, как memcpy или memmove.

Итак, если вы читаете *slt выше, вы бы интерпретировали первый sizeof(*slt) байт массива и попробуйте прочитать его как беззнаковый короткий (это называется type pun).

Когда вы делаете «беззнаковое короткое slt = (беззнаковое короткое) Lookup_ext;", номер нет.байтов, эквивалентных размеру (unsigned short), берутся из местоположения, заданного параметром Lookup_ext, и сохраняются в месте, указанном параметром slt.Поскольку беззнаковое короткое значение будет составлять 2 байта, первые два байта из Lookup_ext будут сохранены в месте, указанном slt.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top