Задачи по языку С

       

Пояснения:


Основные типы 1.1



PRINT(d,"5") Формат %d указывает printf, что аргумент нужно напечатать как десятичное число. Аргумент "5" представляет собой ссылку на массив символов, т.е. адрес массива из двух символов '5' и '\0'.
PRINT(d,'5') %d требует напечатать десятичное значение символа '5'1.
PRINT(d,5) Целое число 5 печатается в десятичном виде.
PRINT(s,"5") Формат %s указывает printf, что аргумент является ссылкой на массив символов. Так как "5" - ссылка на массив символов, то печатается содержимое этого массива, т.е. число 5.
PRINT(c,'5') Формат %c указывает printf, что аргумент нужно рассматривать как значение некоторого символа (его код) и что этот символ нужно напечатать. Так как '5' как раз и есть значение символа, то напечатан будет символ 5.
PRINT(c,53) Десятичное число 53 - это код символа 5 в кодировке ASCII.
PRINT(d,('5'>5) Последней будет напечатана 1, так как '5' имеет большее значение (53), чем целое 5.

1 Значение, которое используется здесь есть значение символа в кодировке ASCII (приложение 3). Кодировка ASCII - одна из возможных кодировок для представления символов там, где необходимо значение символа.

Основные типы 1.2

вначале ax=-8, ux=-8
PRINT(o,sx) %o указывает printf, что аргумент следует напечатать как восьмеричное число.
PRINT(o,ux) Значение -8 представляется как строка из 0 и 1, что верно как для переменных без знака, так и для переменных со знаком.
PRINT(o,sx>>3) С этой трудностью мы сталкивались уже и раньше. В некоторых версиях языка С сдвиг целого со знаком вправо приводит к тому, что знаковый разряд копируется в свободные старшие разряды слова, т.е. знак сохраняется. Однако, внимание, - это свойство зависит от транслятора!
PRINT(o,ux>>3) Когда происходит сдвиг целого без знака вправо, то освободившиеся старшие разряды всегда заполняются нулями.
PRINT(d,sx>>3) Сдвиг на 3 разряда вправо целого со знаком -8 дает ожидаемый результат -1 при условии, что знак сохраняется, и 8191 в противном случае (на 16-разрядной машине с дополнительным кодом).
PRINT(o,ux>>3) Для переменной типа unsigned со значением -8 результат всегда равен 8191 (на 16-разрядной машине).


Основные типы 2.1

i = l = f = d = 100/3
(i=(l=(f=(d=(100/3))))) Вычисляем выражение справа налево.
(i=(l=(f=(d=33)))) Так как оба числа 100 и 3 - целые, то операция деления есть деление целых, поэтому у частного отбрасывается дробная часть.
(i=(l=(f=(double)33))) и d=33 Напоминаем, что значение, вырабатываемое операцией присваивания, есть значение правой части, преобразованное к типу, задаваемому левой частью.
(i=(l=(float)33)) и f=33 (i=(long)33) и l=33 (integer)33 и i=33 33 целое

Основные типы 2.2

d = f = l = i = 100/3 (d=(f=(l=(i=(100/3))))) (d=(f=(l=(integer)33))) и i=33 (d=(f=(long)33)) и l=33 (d=(float)33) и f=33 (double)33 и f=33 33 двойной точности

Основные типы 2.3

i = l = f = d = 100/3. (i=(l=(f=(d=(100/3.)))))
(i=(l=(f=(double)33.333333))) и d=33.333333 Число 3. двойной точности, поэтому и частное будет двойной точности.
(i=(l=(float)33.333333)) и f=33.33333x В этой программе в printf используется формат %.8g, который задает печать числа с точностью до 8 значащих цифр. Но на самом деле на машинах PDP-1 и VAX максимальная точность для чисел с плавающей точкой не более 7 значащих цифр, так что точность до 8 цифр недостижима. Конечно, количество значащих цифр в числе зависит от машины.
(i=(long)33.33333x))и l=33 Преобразование чисел с плавающей точкой в длинные целые происходит с помощью отбрасывания дробной части.
(integer)33 и i=33 33 целое

Основные типы 2.4

d = f = l = i = (double)100/3
(d=(f=(l=(i=((double)100)/3))))) Заметьте, что операция приведения имеет более высокий приоритет, чем операция /.
(d=(f=(l=(i=(100./3))))) (d=(f=(l=(integer)33.333333))) и i=33 (d=(f=(long)33)) и l=33 (d=(float)33) и f=33 (double)33 33 двойной точности

Основные типы 2.5

i = l = f = d = (double)(100000/3) (i=(l=(f=(d=((double)(100000/3))))))
(i=(l=(f=(d=(double)33333)))) Операндом для операции приведения служит частное от деления 100000 на 3.
(i=(l=(f=(double)33333))) и d=33333 (i=(l=(float)33333)) и f=33333 (i=(long)33333) и l=33333 (integer)33333 и i=33333 или переполнение Число 33333 нельзя представить в виде 16-разрядного целого со знаком. Многие реализации языка спокойно допускают и переполнение, и потерю значимости числа. Если ваши вычисления могут в принципе превзойти границы, присущие данной машине, то будет разумным вставить явные проверки на попадание чисел в отводимый диапазон.
33333 целое или переполнение
<


Основные типы 3.1

вначале d=3.2, i=2 x = (y=d/i)*2 (x=(y=3.2/2)*2)
(x=(y=1.6)*2) 3.2 - число двойной точности, этот тип выше типа int, типа числа 2, поэтому частное тоже будет двойной точности. Так как y - целое, то у значения 1.6 будет отброшена дробная часть
(x=1*2) и y=1

(x=2) 2 и y=1

Основные типы 3.2

вначале d=3.2, i=2 y = (x=d/i)*2 (y=(x=1.6)*2)
(y=1.6*2) и x=1.6 Так как x - типа double, то и результат присваивания будет типа double.
(y=3.2) Тип 1.6 - double определяет и тип произведения.
3 и y=3 Так как y типа int, то у 3.2 должна быть отброшена дробная часть

Основные типы 3.3

вначале d=3.2, i=2 y = d * (x=2.5/d) (y=(d*(x=2.5/d))
(y=d*2.5/d) и x=2.5/d Тип x - double, так что у 2.5/d точность сохраняется.
(y=2.5) 2 и y=2 Тип y заставляет отбросить дробную часть у 2.5

Основные типы 3.4

вначале d=3.2, i=2 x = d * (y = ((int)2.9+1.1)/d)
(x=d*(y=(2+1.1)/d)) Операция приведения более высокого порядка, чем операция +.
(x=d*(y=3.1/d)) (x=d*(y=нечто))
(x=d*0) и y=0 y получит значение 0 независимо от величины "нечто", поскольку "нечто" находится между 0 и 1.
0 и x=0

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




Основные типы 2.6

d = f = l = i = 100000/3 (d=(f=(l=(i=(100000/3))))
(d=(f=(l=(integer)33333))) и i=33333 или переполнение Как мы уже видели раньше, 33333 - значение, переполняющее 16-разрядное целое со знаком. Если для представления целых использовать больше разрядов, то i так же, как l, f и d, получат значение 33333. Ниже мы ориентируемся на 16-разрядные целые.
(d=(f=(long)-32203)) и l=-32203 Результат операции, приведшей к переполнению, - это обычное число, но не то, которое ожидалось. Значение 33333 будет потеряно независимо от дальнейших приведений типов.
(d=(float)-32203) и f=-32203 (double)-32203 и d=-32203 32203 двойной точности
О числах. Работа с числами не самая сильная сторона языка С. Язык не дает способа выявить арифметические ошибки, даже если аппаратура и имеет такие средства. Диапазон представления чисел фиксируется при написании транслятора, и в языке нет средств, чтобы задать этот диапазон. Лучшее, что можно сделать для проверки попадания числа в диапазон, - это явный контроль значений переменных в критических точках вычисления.


Содержание раздела