Практическое занятие Ввод-вывод информации Преподаватель: Доцент Кафедры ВС, к.т.н. Поляков Артем Юрьевич © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» ФГОБУ ВПО "СибГУТИ" Кафедра вычислительных систем Дисциплины "ЯЗЫКИ ПРОГРАММИРОВАНИЯ" "ПРОГРАММИРОВАНИЕ"
Шаблон документа © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 2 Общий для всех писем текст В котором изменяются только персональные данные
Вывод данных © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 3 printf (PRINT Formatted) – функция, обеспечивающая вывод информации на экран компьютера (стандартный вывод). Функции printf необходимо передать следующие аргументы: 1.Строку, содержащую шаблон текста, выводимого на экран. Шаблон содержит константные элементы, которые выводятся без изменения, а также спецификаторы, которые заменяются значениями переменных, которые следуют за строкой. 2. Список переменных (разделитель – запятая), значения которых будут использоваться для замены спецификаторов форматной строки. Переменные сопоставляются спецификаторам в том порядке, в котором они указаны в списке. int x; float y; printf("Check: x = %d, y = %f", xvar, var2);
Форматные спецификаторы © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 4 %d – целый знаковый параметр (int / signed int) %u – целый беззнаковый параметр (unsigned int) %f – вещественный параметр одинарной точности (float) Для параметров других типов используются флаги, которые добавляются к одному из трех типов, указанных выше: %hhd – тип char %hd – тип short %ld – тип long %hhu – тип unsigned char %hu – тип unsigned short %lu – тип unsigned long %lf – тип double %Lf – тип long double
Вывод данных (демонстрационная программа) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 5 #include // Output demo program int main() { int i = 10; char c = 19; unsigned int ui = 250; float f = 120.5; double d = ; // Output variables: printf("Integers: i = %d, c = %hhi, ui = %u\n", i, c, iu); printf("Reals: f = %f, d = %lf\n", f, d); return 0; } output1.c
Переход на новую строку © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 6 Символ перехода на новую строку в языке Си обозначается как '\n' и может быть использован в любом месте форматной строки: #include // Output demo program int main() { int i = 10; char c = 19; float f = 120.5; // Output variables: printf("Integers: i = %d, c = %hhi\nReals: f = %f\n", i, c, f); return 0; } output2.c
Ограничение точности для вещественных типов данных © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 7 Вещественные спецификаторы позволяют указать количество знаков после запятой, которое следует выводить: #include // Output demo program int main() { float f = ; double d = ; // Output variables: printf("Original: f = %f, d = %lf\n" "Rounded: f = %.2f, d = %.4lf\n", f, d, f, d); return 0; } output3. c $./output3 Original: f = , d = Rounded: f = , d =
Ограничение точности для вещественных типов данных © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 8 Вещественные спецификаторы позволяют указать количество знаков после запятой, которое следует выводить: #include // Output demo program int main() { float f = ; double d = ; // Output variables: printf("Original: f = %f, d = %lf\n" "Rounded: f = %.2f, d = %.4lf\n", f, d, f, d); return 0; } output3. c $./output3 Original: f = , d = Rounded: f = , d = Почему не ?
Преобразования между системами счисления средствами printf © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 9 #include // Convert demo program int main() { int i = 58, j = 126, k = -15; // Output variables: printf("i: %d %u %x %o\n", i, i, i, i); printf("j: %d %u %x %o\n", j, j, j, j); printf("k: %d %u %x %o\n", k, k, k, k); return 0; } convert1. c Функция printf имеет спецификаторы %x (hexadecimal) и %o (octal), которые позволяют выводить числа в шестнадцатеричной и восьмеричной системах счисления: $./convert1 i: a 72 j: e 176 k: fffffff
Преобразования между системами счисления средствами printf © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 10 #include // Convert demo program int main() { int i = 58, j = 126, k = -15; // Output variables: printf("i: %d %u %x %o\n", i, i, i, i); printf("j: %d %u %x %o\n", j, j, j, j); printf("k: %d %u %x %o\n", k, k, k, k); return 0; } convert1. c Функция printf имеет спецификаторы %x (hexadecimal) и %o (octal), которые позволяют выводить числа в шестнадцатеричной и восьмеричной системах счисления: $./convert1 i: a 72 j: e 176 k: fffffff Откуда эти числа?
Внутреннее представление знаковых целых (1) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» Для представления знаковых целых требуется хранить знак. Один бит способен хранить только 2 значения: 0 и 1, третьего значения для обозначения знака " – " не предусмотрено. В таких ситуациях в вычислительной технике осуществляется "кодирование". Т.е. определяется набор правил, согласно которым по содержимому ячейки можно понять – отрицательное в ней значение или нет. Для кодирования знака в процессорах архитектуры Intel x86 и x86_64 используется "дополнительный код".
Дополнительный код (десятичная система счисления) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 12 Для применения дополнительного кода должно выполняться следующее условие: доступно ограниченное количество D разрядов. Рассмотрим дополнительный код для 4-разрядных десятичных чисел (D=4). Дополнительный код x' для числа x строится следующим образом: Обратное преобразование выполняется по правилу: Положительные Отрицательные
© Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 13 Дополнительный код (арифметические действия) Особенностью дополнительного кода является то, что сложение и вычитание положительных и отрицательных чисел можно выполнять одинаково. Рассмотрим пример: x = 25, x' = 25 y = -15, y' = – 15 = 9985 x + y = 10 x' + y' = = = 10 x – y = 40 x' – y' = 25 – 9985 = – 9985 = 40 y + x = 10 y' + x' = = = 10 y – x = -40 z' = y' – x' = 9985 – 25 = 9960 |z| = – z' = 9960 = 40, z' > => z < 0
© Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 14 Дополнительный код (Самостоятельно) x = 3840, x' = ? y = -1056, y' = ? x + y = 2784 x' + y' = ? x – y = 4896 x' – y' = ? y + x = 2784 y' + x' = ? y – x = z' = y' – x' = ? |z| = ? знак z - ? Что будет, если y = ?
Дополнительный код (двоичная система счисления) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 15 В десятичной системе 10 разрядов, поэтому число отрицательно, если его D-й разряд > 5. В двоичной системе разрядов всего два, поэтому число отрицательно, если его D-й разряд = 1 и положительно, если D-й разряд = 0. Получим представление десятичных чисел, рассмотренных ранее в двоичном дополнительном коде: D = 8 (один байт) x = 25 > 0 => x' = = y = -15, |y| = = , y' = – = x' + y' = = = = 10 2 z' = y' – x' = – = |z| = – = = z' => z < 0
Интерпретация значения ячеек памяти © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» a 2 = x 1 x 2 x 3 x 4 x 5 (a 2 = ) a 10 = x x x x x (a 10 = = 21) a 10 = ?
Ввод данных © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 17 scanf (SCAN Formatted) – функция, обеспечивающая ввод информации с клавиатуры компьютера (стандартный ввод). Функции scanf необходимо передать следующие аргументы: 1. Строку, содержащую шаблон текста, выводимого на экран. Шаблон может содержать: символы разделители: пробел (' '), табуляция ('\t'), новая строка ('\n'), такой элемент соответствует любому количеству любых разделителей во входном тексте. обычные символы (не разделители и не %): выполняется точное сопоставление со входным текстом спецификаторы: такие же как для функции printf. 2. Список указателей на переменные в которые осуществляется ввод (разделитель – запятая). Для получения указателя на переменную используется операция '&', например &x – указатель на переменную x.
Ввод данных (ввод целой знаковой переменной) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 18 #include int main() { int i; printf("Input i value: "); scanf("%d",&i); printf("Your input was %d\n",i); printf("i + 5 = %d\n",i+5); return 0; } input1. c $./input1 Input i value: 10 Your input was 10 i + 5 = 15
Ввод данных (ввод двух целых переменных, разделители) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 19 #include int main() { int i, j, k; printf("Input i & j value: "); scanf("%d %d", &i,&j); printf("Your input was i=%d, j=%d\nInput i & j again: ",i,j); scanf("%d %d",&i,&j); printf("Your input was i=%d, j=%d\n",i,j); printf("i + j = %d\n",i + j); return 0; } input2. c $./input2 Input i & j value: 4 5 Your input was i=4, j=5 Input i & j again: 2 3 Your input was i=2, j=3 i + j = 5
Ввод данных (обычные символы в форматной строке) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 20 #include int main() { int i = 0, j = 0, k; printf("Input i & j value: "); scanf("i=%d j=%d",&i,&j); printf("Your input was i=%d, j=%d\nInput i & j again: ",i,j); scanf("%d, %d",&i,&j); printf("Your input was i=%d, j=%d\n",i,j); printf("i + j = %d\n",i+j); return 0; } input3. c $./input3 Input i & j value: i=2 j=10 Your input was i=2, j=10 Input i & j again: 10, 11 Your input was i=10, j=11 i + j = 21 $./input3 Input i & j value: 10, 11 Your input was i=0, j=0 Input i & j again: Your input was i=10, j=11 i + j = 21 $./input3 Input i & j value: Your input was i=0, j=0 Input i & j again: Your input was i=10, j=0 i + j = 10
Конвертация из десятичной в восьмеричную систему счисления © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 21 #include // Convert demo program int main() { int i; printf("Input i: "); scanf("%d", &i); printf("Octal representation of i: %o\n",i); return 0; } $./convert2 Input i: 10 Octal representation of i: 12 convert2.c
Распространенные ошибки при использовании scanf (передача переменной, а не указателя) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 22 #include // Convert demo program int main() { int i = 0; printf("Input i: "); scanf("%d", i); printf("Octal representation of i: %o\n",i); return 0; } $ gcc -Wall -o convert2 convert2. c convert2.c: In function main: convert2.c:7: warning: format %d expects type int *, but argument 2 has type int Компилятор способен обнаруживать подобные ошибки и сообщать о них: При выполнении такой программы она аварийно завершается, не выводя на экран ожидаемую информацию!
Распространенные ошибки при использовании scanf (разделитель в конце форматной строки) © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 23 #include // Convert demo program int main() { int i = 0; printf("Input i: "); scanf("%d\n", &i); printf("Octal representation of i: %o\n",i); return 0; } При выполнении такой программы она запрашивает значение i, а потом "зависает"! На самом деле, согласно описанию функции scanf: … символы разделители: пробел (' '), табуляция ('\t'), новая строка ('\n'), такой элемент соответствует любому количеству любых разделителей во входном тексте…. Таким образом нажатие "Enter" совпадает с шаблоном и scanf продолжает считывать данные. Прервать работу scanf можно только введя "обычный символ".
Задачи для самостоятельного решения © Кафедра вычислительных систем ФГОБУ ВПО «СибГУТИ» 24 Форма отчетности: исходные коды и тестовые данные (не менее 10 наборов для каждой задачи, если это допускается должны быть как отрицательные, так и положительные числа) для приведенных ниже задач. 1. Модифицировать программу convert2 так, чтобы она выполняла перевод из десятичной в шестнадцатеричную систему счисления. 2. Модифицировать программу convert2 так, чтобы она выполняла перевод из шестнадцатеричной в десятичную систему счисления. 3. Разработать программу, вычисляющую результат сложения целых чисел a и b, значения которых вводятся с клавиатуры. 4. Разработать программу, вычисляющую разность вещественных чисел a и b, значения которых вводятся с клавиатуры.