Студопедия — ПРАКТИЧЕСКАЯ ЧАСТЬ. Пример 1. Написать программу с использованием макро-функции по определению числа, введенного пользователем
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

ПРАКТИЧЕСКАЯ ЧАСТЬ. Пример 1. Написать программу с использованием макро-функции по определению числа, введенного пользователем






 

Пример 1. Написать программу с использованием макро-функции по определению числа, введенного пользователем, на предмет его простоты. Предусмотрите также вывод на консоль времени компиляции программы и сообщения о реализации языка С.

Программный код решения примера

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> // Макрос с формальными параметрами #define SIMPLE(x, d, b) for(d = 2; d < x; d++) \ if (!(x%d)) b = 0; \ if (b) puts("\n It is the simple number"); \ else puts("\n It is not the simple number"); int main (void) { int b = 1, d = 0, x = 13; printf("\n Enter the natural number: "); scanf("%d", &x); // Макрос с действительными параметрами SIMPLE(x, d, b); printf("\n %5sTime: %c\n Version C: %d \n", "", \ __TIME__, __STDC__); printf("\n... Press any key: "); getch(); return 0; }

В первой строке программы включена символическая константа для исключения вывода предупреждения относительно функции scanf() в среде MS Visual Studio 2010. В программе показано применение макроса функции с тремя формальными параметрами и несколькими строками программного кода.

Результат выполнения программы приведен на рис. 19.1.


Рис. 19.1. Проверка введенного числа на простоту


 

Результат Version C: 1 означает, что компилятор поддерживает стандарт ANSI С.

Задание 1

  1. Сделайте так, чтобы признак простого или непростого числа передавался из макроса. Этот признак должен использоваться в функции main() для вывода соответствующего сообщения на консоль.
  2. В программе предусмотрите вывод на консоль общего количества строк программного кода.
  3. В программе предусмотрите вывод на консоль даты компиляции и имени компилируемого файла.
  4. Напишите макрос с формальными параметрами для проверки на четность целого числа, введенного с клавиатуры.
  5. Напишите макрос с формальными параметрами для обмена значениями двух переменных (типа функции swap).
  6. Напишите макрос с формальными параметрами по вычислению площади круга по известному радиусу (вводимого с клавиатуры). Значение числа p задайте с 15 знаками после десятичной точки при использовании директивы #define.
  7. Введите в программу вычисление случайных чисел, равномерно распределенных в интервале [0, Х], где Х – номер компьютера, на котором выполняется лабораторная работа. Количество случайных чисел должно соответствовать числу секунд (не равных нулю), определяемых с помощью символической константы __TIME__.

Пример 2. Выполнить проверку подключаемого тестового файла и вывести на консоль его содержимого. Содержимое файла – стихотворный пример бесконечной рекурсии: у попа была собака¼.

Программный код решения примера

// Файл с главной функцией main() #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <locale.h> // Подключение текстового файла #ifndef AZA #define AZA #include "dog.txt" #endif int main (void) { short i, j, n, in; i = j = 0; setlocale (LC_ALL, "rus"); printf("\n Введите количество стихотворных строф: "); in = scanf("%hd", &n); if (in!= 1 || n < 1) { printf("\n Ошибка ввода данных. Нажмите любую клавишу: "); getch(); exit(1); } // Условие распечатки текстового файла #ifdef AZA puts(""); for (j = 0; j < n; j++) { i = 0; if (d[i]!= NULL) { printf(" "); puts(d[i]); i++; } } #endif printf("\n... Нажмите любую клавишу: "); getch(); return 0; }

Содержимое текстового файла dog.txt:

char**d[] = { "У попа была собака,", \ "Он её любил,", \ "Она съела кусок мяса,", \ "Он её убил...",\ "Вырыл ямку, закопал,", \ "На дощечке написал:\n" };

Решение примера выполнено в виде двухфайлового проекта. Инициализация переменных в главной функции сделана на случай, если не будет определена директива #define AZA, чтобы не было предупреждений компилятора о неиспользованных переменных i и j.

Пример выполнения программы показан на рис. 19.2.


Рис. 19.2. Пример распечатки текстового файла

Задание 2

  1. Стихотворение запишите в текстовый файл с именем compX.txt, где Х – номер компьютера, на котором выполняется лабораторная работа.
  2. Вместо препроцессорной директивы #ifdef примените другую директиву условной компиляции.
  3. В программу включите директиву #else.
  4. Подключите препроцессорную директиву для исключения из программы именованной константы AZA.
  5. Создайте файл dog.h с содержимым файла dog.txt и подключите его к проекту вместо файла dog.txt.
  6. Напишите «чистую» рекурсивную функцию для распечатки стихотворения о попе и его собаке. В качестве аргумента функции включите количество стихотворных строф. Подсчитайте количество рекурсивных вызовов.

Пример 3. С помощью директив условной компиляции и символической константы _DEBUG написать программу ввода слов с клавиатуры с проверкой возможности компиляции программного кода.

Программный код решения примера

#include <stdio.h> #include <conio.h> int main (void) { char str[80]; // Начало проверки компилируемого кода #ifdef _DEBUG printf("\n Start debugging\n"); #endif do { printf("\n Enter a word or \"z\" to exit: "); gets_s(str, 79); #if _DEBUG printf("\n The word is \"%c\"\n", str); #else #error This version is not to the C Run-Time Library. \ Break to debugging. #endif } if (str[0]!= 'z' && str[0]!= 'Z'); printf("\n\n... Press any key: "); getch(); return 0; }

Символическая константа _DEBUG будет определяться (существовать) в режиме Debug, который находится в списке главного меню интегрированной системы MS Visual Studio 2010. На рис. 19.3 представлен выбор режима отладки Debug.


Рис. 19.3. Выбор режима отладки Debug


 


Пример выполнения программы показан на рис. 19.4.

Рис. 19.4. Пример выполнения режима отладки программы

Задание 3

1. Внесите изменения в программу, чтобы условие о невозможности компиляции было реализовано без директивы #error.

2. Вместо специализированной константы _DEBUG введите собственную символическую константу COMP_X, где Х – номер компьютера, на котором выполняется лабораторная работа.

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

Пример 4. С помощью директивы #define и оператора препроцессора # написать программу определения кода вводимого символа.

Программный код решения примера

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> #include <locale.h> #define CHAR_COD(c) ""#c"" int main (void) { char ch; setlocale (LC_ALL, "rus"); printf("\n Введите символ: "); scanf("%c", &ch); printf("\n %c \"%c\", его код %d", CHAR_COD(Символ), ch, ch); printf("\n\n... Нажмите любую клавишу: "); getch(); return 0; }

Оператор # должен использоваться в макросах с аргументами, поскольку операнд ссылается на аргумент макроса [5]. В данном случае строка «Символ» подставляется в заменяющий текст вместо #c.


Пример выполнения программы показан на рис. 19.5.

Рис. 19.5. Пример определения кода вводимого символа

Задание 4

1. Напишите программу повторного ввода символов с клавиатуры до тех пор, пока не будет введен символ z.

2. Выполните макроподстановку со строкой «compX» и присоединяемой строкой «Х» с помощью функции printf(), где Х – номер компьютера, на котором выполняется лабораторная работа.

Пример 5. С помощью директивы #define и оператора препроцессора ## классифицировать четность или нечетность кода вводимого символа.

Программный код решения примера

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <conio.h> #include <locale.h> // LEXEME - лексема #define TWO_LEXEME(a,b) a ## b #define CHAR_COD(c) ""#c"" int main (void) { char ch; setlocale (LC_ALL, "rus"); printf("\n Введите символ: "); scanf("%c", &ch); if (!(ch % 2)) printf("\n %c \"%c\", его код %d %c", \ CHAR_COD(Символ), ch, ch, TWO_LEXEME(" - четный","!")); else printf("\n %c \"%c\", его код %d %c", \ CHAR_COD(Символ), ch, ch, TWO_LEXEME(" - не ", "четный.")); printf("\n\n... Нажмите любую клавишу: "); getch(); return 0; }

Данная программа – некоторое расширение предыдущей программы. Операция конкатенации строк ## осуществляется с помощью макроса TWO_LEXEME() с двумя аргументами.


Результат выполнения программы приведен на рис. 19.6.

Рис. 19.6. Пример классификации четности символа

Задание 5

1. В программе примените только буквы латинского алфавита.

2. Для записи четности или нечетности введенного символа предусмотрите массив символов str1 и str2.

3. Произведите конкатенацию двух строк «comp» и «Х» с помощью операции ##, где Х – номер компьютера, на котором выполняется лабораторная работа.

Пример 6. Написать программу формирования структуры с информацией о студенте (об учащемся) и с помощью директивы #pragma осуществить оптимизацию использования памяти, выделяемой под структуру.

Для решения примера используем справку системы Visual Studio 2010 (выберем Help®Index®Look for; впишем pragma, затем в правой части панели обратиимся к опции pack). Опция pack определяет, как компилятор выравнивает данные при сохранении в памяти.

Программный код решения примера

#include <stdio.h> #include <conio.h> #pragma pack (show) struct Student { char name[21]; // имя, фамилия int age; // возраст, полных лет char gender; // пол, мужской, женский double mean; // средний балл успеваемости } st1; #pragma pack (push) #pragma pack (1) #pragma pack (show) struct Student_pack { char name[21]; // имя, фамилия int age; // возраст, полных лет char gender; // пол, мужской, женский double mean; // средний балл успеваемости } st2; #pragma pack (pop) #pragma pack (show) int main (void) { puts(""); printf (" sizeof (struct st1) = %d\n", sizeof (st1)); printf (" sizeof (struct st2) = %d\n", sizeof (st2)); printf("\n... Press any key: "); getch(); return 0; }

В программе опция pack(show) используется для диагностики текущей упаковки полей структуры, pack(1) – используется для выравнивания областей памяти полей структуры, кратных единице, pack(push) – для «вталкивания» параметров. Опция pack(pop) используется для «выталкивания» параметров.

После компиляции программы можно видеть сообщения, представленные на рис. 19.7.


Рис. 19.7. Сообщения об упаковке полей структуры

Предупреждения (warning) уведомляют о размере упаковки. Сначала область памяти выделяется под размер в байтах, кратных 8, затем, кратных 1. После выталкивания параметров снова область памяти становится кратной 8 – наибольшему типу данных double элемента mean структуры.

Результат выполнения программы показан на рис. 19.8.



Рис. 19.8. Пример определения месяца года

Как видно, размер первой структуры равен 40 байтам (кратных 8), размер второй структуры, для которой произведена упаковка, – 34, что соответствует сумме размеров полей структуры: 34 = 21 + 4 + 1 + 8.


Примечание. Выравнивание полей структуры можно выполнить при настройке компилятора в MS Visual Studio 2010 (рис. 19.9).

Рис. 19.9. Настройка компилятора (Code Generation ® Struct Alignment)

Задание 6

  1. Запишите в двоичные файлы созданные структуры, проведя их инициализацию. Определите и сравните размеры созданных бинарных файлов. Произведите также чтение данных из бинарных файлов с выводом результата на консоль.
  2. В программе для аргумента pack() примите знаяения 1, 2, 4, 8, 16. Объясните результаты выполнения программы.

 

  1. Размер массива типа char примите равным 31, т. е. char name[31]. Объясните результат выполнения программы.
  2. В качестве элементов структуры используйте следующие типы данных: float, short int. Объясните результат выполнения программы.
  3. Используя меню Project ® Properties (Alt + F7), произведите установку параметров закладки Struct Alignment для всех возможных значений (1 Byte, 2 Bytes, 4 Bytes, 8 Bytes, 16 Bytes). Определите также значение выравнивания полей структуры по умолчанию (Default).

 

 

Контрольные вопросы

  1. Каково назначение препроцессора языка С?
  2. Что такое условная компиляция, осуществляемая препроцессором? В каких целях она производится?
  3. Какие Вы знаете операторы препроцессора? Для чего они используются?
  4. Какие директивы препроцессора наиболее часто используются в программах, написанных на языке С?
  5. Что такое макроопределение препроцессора? Как оно реализуется?

 







Дата добавления: 2015-09-06; просмотров: 1038. Нарушение авторских прав; Мы поможем в написании вашей работы!



Шрифт зодчего Шрифт зодчего состоит из прописных (заглавных), строчных букв и цифр...

Картограммы и картодиаграммы Картограммы и картодиаграммы применяются для изображения географической характеристики изучаемых явлений...

Практические расчеты на срез и смятие При изучении темы обратите внимание на основные расчетные предпосылки и условности расчета...

Функция спроса населения на данный товар Функция спроса населения на данный товар: Qd=7-Р. Функция предложения: Qs= -5+2Р,где...

Задержки и неисправности пистолета Макарова 1.Что может произойти при стрельбе из пистолета, если загрязнятся пазы на рамке...

Вопрос. Отличие деятельности человека от поведения животных главные отличия деятельности человека от активности животных сводятся к следующему: 1...

Расчет концентрации титрованных растворов с помощью поправочного коэффициента При выполнении серийных анализов ГОСТ или ведомственная инструкция обычно предусматривают применение раствора заданной концентрации или заданного титра...

Методика обучения письму и письменной речи на иностранном языке в средней школе. Различают письмо и письменную речь. Письмо – объект овладения графической и орфографической системами иностранного языка для фиксации языкового и речевого материала...

Классификация холодных блюд и закусок. Урок №2 Тема: Холодные блюда и закуски. Значение холодных блюд и закусок. Классификация холодных блюд и закусок. Кулинарная обработка продуктов...

ТЕРМОДИНАМИКА БИОЛОГИЧЕСКИХ СИСТЕМ. 1. Особенности термодинамического метода изучения биологических систем. Основные понятия термодинамики. Термодинамикой называется раздел физики...

Studopedia.info - Студопедия - 2014-2024 год . (0.008 сек.) русская версия | украинская версия