Тип данных C: между Short и Int - PullRequest
2 голосов
/ 24 апреля 2011

Я читаю книгу, рассказывающую о C, для меня лучше сначала представить код, а затем вопрос.

Первый код

#include <stdio.h>

int main(void)
{
short num = 3;

printf("%hd\n" , num );

return 0;

} 


Второй код

#include <stdio.h>

int main(void)
{
short num = 3;

printf("%d\n" , num );

return 0;

}

Специальное примечание : Я использую ПК на базе Intel, поэтому размер int 32-битный.

Вопрос:

1.) В книге упоминается, что эти два кода могут работать правильно, хотя один из них использует спецификатор %hd, а другой использует спецификатор %d.

2.) Причина из книги в том, что механизм C будет автоматически преобразовывать тип short в int для более быстрого вычисления, поэтому с помощью спецификатора %d или даже %ld, который является 32-битным, также даст правильный результат.

3.) Мой вопрос: когда произошло это преобразование? Это происходит во время передачи его в качестве аргумента функции printf(), точно так же, как переменная с плавающей запятой преобразуется в double, когда она передается как выражение или аргумент, или к тому времени, когда мы инициализируем переменную со значением 3 ??

4.) На самом деле я провел небольшой эксперимент, то есть распечатал размер переменной num с помощью оператора sizeof вместе с функцией printf(), и он показывает мне 2 bytes. Но я все еще не уверен, когда произойдет конверсия.

5.) Если преобразование произошло в то время, когда мы присвоили значение короткой переменной, какой смысл создавать короткую переменную ?? (** Этот вопрос следует игнорировать, если это не так )

Ваша помощь очень ценится

Ответы [ 3 ]

4 голосов
/ 24 апреля 2011
  1. Да, %d и %hd эквивалентны в этом случае.printf() - это функция с переменным числом, поэтому правила говорят, что к аргументам применяются «целочисленные повышения».printf() вообще не видит значение short, просто видит int.
  2. %ld для long int.Это может быть больше по размеру, чем простая int, поэтому здесь книга не права.
  3. Преобразование происходит при вызове printf().Любой short int, переданный printf(), преобразуется компилятором в int.short int, конечно, не изменяется (не уверен, что это значит в любом случае!)
  4. Когда вы печатаете размер, используя sizeof, вы печатаете число, равное short int (иномер типа size_t).printf() даже не видит оператор short int, sizeof и сообщает правильный размер.
  5. Смысл создания переменной short в том, что если вам нужна переменная shortВы создаете один.Это верно для большинства переменных, конечно :-).Но если вы не думаете, что вам нужен именно short int, то можно просто использовать int.
2 голосов
/ 24 апреля 2011

Если вы вызываете функцию без прототипа или функцию с переменными аргументами, например printf (3), то C применяет нечто, называемое стандартным продвижением аргумента .

Эти преобразования приводят к удвоению числа с плавающей запятой и к чему-либо меньшему, чем int до int или unsigned int. Это приводит к гармонизации большинства типов.

Это интересная особенность, которую, возможно, C представил миру. На самом деле это происходит в некоторой степени на уровне набора команд или на уровне ABI. Параметры передаются в регистрах или в стеке, и, как правило, никто не позволяет сместить стек или оставить ненужную информацию в битах старшего разряда.

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

1 голос
/ 24 апреля 2011

Это преобразование происходит при вызове printf, потому что для функций с переменным числом все аргументы, передаваемые как часть ..., расширяются до int (или double, если аргумент является float) первый.

...