Borland C / C ++ преобразуется в беззнаковое целое - PullRequest
0 голосов
/ 28 ноября 2010

Как borland приводит короткое к беззнаковому int?

#include <stdio.h>

void main() {
  short sNum = 57000;
  unsigned short usNum = sNum;
  unsigned int uiNum;

  printf("\r\nsNum = %d", sNum);
  printf("\r\nusNum = %u", usNum);

  //cast 1: short -> unsigned int
  uiNum = sNum;
  printf("\r\nuiNum = %u", uiNum);

  //cast 2: unsigned short -> unsigned int
  uiNum = (unsigned short)sNum;
  printf("\r\nuiNum = %u", uiNum);
}

дает мне вывод:

sNum = -8536
usNum = 57000
uiNum = 4294958760
uiNum = 57000

Почему я не получаю 57000 в приведении 1: short к unsigned int (нет ли неявного преобразования в unsigned short до преобразования в unsigned int?)?

Ответы [ 5 ]

3 голосов
/ 28 ноября 2010

В вашем коде есть только одно приведение:

uiNum = (unsigned short)sNum;

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

Во-вторых, строка:

short sNum = 57000;

имеет поведение, определяемое реализацией. Вам следует избегать кода, который преобразует (неявно или через приведение) значения в подписанные типы, в которые значение не помещается.

Наконец, вам не следует задавать подобный вопрос о "C / C ++". Такого языка не существует, и системы типов (даже для простых целочисленных типов) достаточно различаются в двух языках, поэтому ответы на многие вопросы будут разными в зависимости от того, какой язык вы фактически используете.

1 голос
/ 28 ноября 2010

Нет, неявное приведение к unsigned short перед приведением к unsigned int.С чего бы это?

Прежде всего, если в этой реализации шорты 16-битные, 57000 не подойдут, поэтому вы не можете хранить 57000 в своем коротком sNum.Он переполнится, что приведет к -8536.

В приведении 2 вы сначала преобразуете (используя явное приведение) из короткого (-8536) в короткое без знака (57000, так как это тот же битовый шаблон, что и -8536,но интерпретируется как число без знака), а затем из unsigned short в unsigned int (57000).

В приведении 1 вы конвертируете непосредственно из short (-8536) в unsigned int.

0 голосов
/ 28 ноября 2010

short имеет 8 * 2 = 16 бит

int имеет 8 * 4 = 32 бита

Если явно не указано, что беззнаковые и int, и short подписаны.В случае числа со знаком крайний левый бит содержит знаковый бит.

, поэтому в коротком знаке у нас осталось 16 - 1 = 15 бит.Следовательно, верхний предел короткого замыкания должен быть 2 ^ 15 32768. для любого числа больше этого он вычитается из 2 ^ 16 (= 65536 верхний предел для беззнаковой или общей емкости) и сохраняется с отрицательным знаком [это те,комплимент]

Здесь 65536 - 57000 = -8536 Отсюда и результат

0 голосов
/ 28 ноября 2010

Вы вводите в значение sNum значение за пределами короткого диапазона. Сохраняется целое число -8536, которое преобразуется в целое число, а затем в целое число без знака: 4294958760.

Вам необходимо либо объявить sNum как беззнаковое короткое слово (чтобы оно могло хранить желаемое значение), либо преобразовать его в целое число вместо целого без знака.

0 голосов
/ 28 ноября 2010

Поскольку вы попросили напечатать целое число со знаком с вашим

 printf("\r\nsNum = %d", sNum);

линия. Переменная была расширена до int и передана как int функции printf, которая интерпретировала этот параметр как int.

Если вы сделали

printf("\r\nsNum = %u", sNum);

вы получите 57000

...