Введение
В этом практическом занятии (лабораторной работе) вы научитесь создавать калькулятор факториалов на языке программирования C. В рамках практики рассматриваются важные темы, такие как понимание синтаксиса циклов for, перебор элементов массива, реализация расчета факториала, обработка крайних случаев, а также тестирование и отладка калькулятора факториалов. По завершении этого практического занятия вы получите твердое понимание этих фундаментальных концепций программирования и сможете применить их для создания функционального калькулятора факториалов.
В практическом занятии предоставлены пошаговые инструкции и примеры кода, которые помогут вам пройти процесс создания калькулятора факториалов. Вы начнете с изучения базового синтаксиса циклов for, которые являются важными для перебора элементов массива и выполнения повторяющихся задач. Затем вы узнаете, как обращаться к элементам массива и манипулировать ими, что является важным для расчета факториала. В практике также будут рассмотрены реализация расчета факториала, обработка крайних случаев, а также тестирование и отладка конечной программы.
Понять синтаксис цикла for
На этом этапе вы узнаете о базовом синтаксисе циклов for в языке программирования C, которые являются важными для перебора элементов массивов и выполнения повторяющихся задач, таких как вычисление факториалов.
Начнем с создания простой программы на языке C для демонстрации базового синтаксиса цикла for. Откройте WebIDE и создайте новый файл с именем loop_example.c в директории ~/project:
cd ~/project
touch loop_example.c
#include <stdio.h>
int main() {
// Basic for loop syntax: for (initialization; condition; increment/decrement)
for (int i = 0; i < 5; i++) {
printf("Current iteration: %d\n", i);
}
return 0;
}
Пример вывода:
Current iteration: 0
Current iteration: 1
Current iteration: 2
Current iteration: 3
Current iteration: 4
Разберем синтаксис цикла for:
int i = 0: Инициализация - устанавливает переменную-счетчик цикла в начальное значениеi < 5: Условие - цикл продолжает выполняться, пока это условие истинноi++: Инкремент - увеличивает счетчик цикла после каждой итерации
Теперь скомпилируйте и запустите программу, чтобы увидеть, как работает цикл:
gcc loop_example.c -o loop_example
./loop_example
Цикл for является мощным инструментом, так как позволяет точно контролировать процесс итерации. Вы можете изменять части инициализации, условия и инкремента/декремента, чтобы соответствовать различным программным потребностям, таким как обход массивов или выполнение вычислений.
Перебор элементов массива
На этом этапе вы научитесь перебирать элементы массива в языке C, что является важным для реализации нашего калькулятора факториалов. Исходя из знаний о цикле for, полученных на предыдущем этапе, мы рассмотрим, как обращаться к элементам массива и манипулировать ими.
Создадим новый файл с именем array_iteration.c в директории ~/project, чтобы продемонстрировать перебор массива:
cd ~/project
touch array_iteration.c
#include <stdio.h>
int main() {
// Declare and initialize an array of integers
int numbers[5] = {10, 20, 30, 40, 50};
// Iterate through the array using a for loop
for (int i = 0; i < 5; i++) {
printf("Element at index %d is: %d\n", i, numbers[i]);
}
return 0;
}
Пример вывода:
Element at index 0 is: 10
Element at index 1 is: 20
Element at index 2 is: 30
Element at index 3 is: 40
Element at index 4 is: 50
Разберем основные концепции:
int numbers[5]создает массив, который может хранить 5 целых элементов{10, 20, 30, 40, 50}инициализирует массив определенными значениямиnumbers[i]обращается к отдельным элементам массива с использованием индекса- Цикл
forиспользуетiв качестве индекса для последовательного доступа к каждому элементу
Теперь скомпилируйте и запустите программу:
gcc array_iteration.c -o array_iteration
./array_iteration
Для того чтобы перебор стал более практичным, создадим пример, который вычисляет сумму элементов массива:
#include <stdio.h>
int main() {
int numbers[5] = {10, 20, 30, 40, 50};
int sum = 0;
// Calculate sum using array iteration
for (int i = 0; i < 5; i++) {
sum += numbers[i];
}
printf("Sum of array elements: %d\n", sum);
return 0;
}
Пример вывода:
Sum of array elements: 150
Это демонстрирует, как можно использовать циклы for для выполнения операций над элементами массива, что будет важным при реализации нашего будущего калькулятора факториалов.
Реализация расчета факториала
На этом этапе вы научитесь реализовать функцию для расчета факториала на языке C, используя техники итерации цикла, которые вы изучили на предыдущих этапах. Факториал - это математическая операция, которая представляет собой произведение числа на все положительные целые числа, меньшие его.
Создадим новый файл с именем factorial_calculator.c в директории ~/project:
cd ~/project
touch factorial_calculator.c
#include <stdio.h>
// Function to calculate factorial
int calculateFactorial(int n) {
// Initialize result to 1
int factorial = 1;
// Use for loop to multiply numbers from 1 to n
for (int i = 1; i <= n; i++) {
factorial *= i;
}
return factorial;
}
int main() {
// Test factorial calculation for different numbers
int numbers[] = {0, 1, 5, 7};
// Iterate through the numbers and calculate their factorials
for (int j = 0; j < 4; j++) {
int num = numbers[j];
int result = calculateFactorial(num);
printf("Factorial of %d is: %d\n", num, result);
}
return 0;
}
Пример вывода:
Factorial of 0 is: 1
Factorial of 1 is: 1
Factorial of 5 is: 120
Factorial of 7 is: 5040
Разберем расчет факториала:
- Факториал 0 и 1 равен 1
- Факториал числа n (n!) = 1 2 3 ... n
- Функция
calculateFactorial()использует циклforдля умножения чисел - Мы начинаем расчет факториала с 1 и умножаем на каждое число до n
Скомпилируйте и запустите программу:
gcc factorial_calculator.c -o factorial_calculator
./factorial_calculator
Для того чтобы калькулятор стал более интерактивным, изменим программу так, чтобы она принимала ввод от пользователя:
#include <stdio.h>
int calculateFactorial(int n) {
int factorial = 1;
for (int i = 1; i <= n; i++) {
factorial *= i;
}
return factorial;
}
int main() {
int number;
// Prompt user for input
printf("Enter a number to calculate its factorial: ");
scanf("%d", &number);
// Calculate and display factorial
int result = calculateFactorial(number);
printf("Factorial of %d is: %d\n", number, result);
return 0;
}
Пример взаимодействия:
Enter a number to calculate its factorial: 6
Factorial of 6 is: 720
Обработка крайних случаев
На этом этапе вы научитесь обрабатывать крайние случаи в вашем калькуляторе факториалов, таких как отрицательные числа и большие входные значения, которые могут привести к переполнению целого числа. Прочная обработка ошибок является важной для создания надежного программного обеспечения.
Давайте модифицируем наш калькулятор факториалов для обработки этих крайних случаев. Создайте новый файл с именем factorial_edge_cases.c в директории ~/project:
cd ~/project
touch factorial_edge_cases.c
#include <stdio.h>
#include <limits.h>
// Function to calculate factorial with error handling
int calculateFactorial(int n) {
// Check for negative numbers
if (n < 0) {
printf("Error: Factorial is not defined for negative numbers.\n");
return -1;
}
// Initialize result to 1
int factorial = 1;
// Check for potential integer overflow
for (int i = 1; i <= n; i++) {
// Check if multiplication will cause overflow
if (factorial > INT_MAX / i) {
printf("Error: Factorial result exceeds integer limit.\n");
return -1;
}
factorial *= i;
}
return factorial;
}
int main() {
// Test various edge cases
int test_cases[] = {-5, 0, 1, 12, 13};
for (int i = 0; i < 5; i++) {
int number = test_cases[i];
int result = calculateFactorial(number);
// Only print result if calculation was successful
if (result!= -1) {
printf("Factorial of %d is: %d\n", number, result);
}
}
return 0;
}
Пример вывода:
Error: Factorial is not defined for negative numbers.
Factorial of 0 is: 1
Factorial of 1 is: 1
Factorial of 12 is: 479001600
Error: Factorial result exceeds integer limit.
Основные техники обработки ошибок:
- Проверка на отрицательные числа перед расчетом
- Использование
INT_MAXдля предотвращения переполнения целого числа - Возвращение
-1для указания ошибки в расчете - Предоставление информативных сообщений об ошибках
Скомпилируйте и запустите программу:
gcc factorial_edge_cases.c -o factorial_edge_cases
./factorial_edge_cases
Давайте улучшим программу с помощью более удобной для пользователя обработки ввода:
#include <stdio.h>
#include <limits.h>
int calculateFactorial(int n) {
if (n < 0) {
printf("Error: Factorial is not defined for negative numbers.\n");
return -1;
}
int factorial = 1;
for (int i = 1; i <= n; i++) {
if (factorial > INT_MAX / i) {
printf("Error: Factorial result exceeds integer limit.\n");
return -1;
}
factorial *= i;
}
return factorial;
}
int main() {
int number;
while (1) {
printf("Enter a non-negative integer (or negative to exit): ");
// Check if input is valid
if (scanf("%d", &number)!= 1) {
printf("Invalid input. Please enter an integer.\n");
// Clear input buffer
while (getchar()!= '\n');
continue;
}
// Exit condition
if (number < 0) {
printf("Exiting factorial calculator.\n");
break;
}
// Calculate and display factorial
int result = calculateFactorial(number);
if (result!= -1) {
printf("Factorial of %d is: %d\n", number, result);
}
}
return 0;
}
Пример взаимодействия:
Enter a non-negative integer (or negative to exit): 10
Factorial of 10 is: 3628800
Enter a non-negative integer (or negative to exit): -1
Exiting factorial calculator.
Тестирование и отладка калькулятора факториала
На этом последнем этапе вы научитесь тщательно тестировать и отлаживать свой калькулятор факториалов, используя различные методы тестирования и стратегии отладки.
Создадим комплексную программу для тестирования, которая включает несколько тестовых случаев и функции отладки. Создайте файл с именем factorial_test.c в директории ~/project:
cd ~/project
touch factorial_test.c
#include <stdio.h>
#include <assert.h>
#include <limits.h>
// Factorial calculation function with detailed error checking
int calculateFactorial(int n) {
// Debug print to track function calls
printf("DEBUG: Calculating factorial for %d\n", n);
// Validate input range
if (n < 0) {
fprintf(stderr, "ERROR: Factorial undefined for negative numbers\n");
return -1;
}
// Handle special cases
if (n == 0 || n == 1) return 1;
// Factorial calculation with overflow protection
long long factorial = 1;
for (int i = 2; i <= n; i++) {
factorial *= i;
// Overflow check
if (factorial > INT_MAX) {
fprintf(stderr, "ERROR: Factorial exceeds integer limit\n");
return -1;
}
}
return (int)factorial;
}
// Test function to verify factorial calculations
void runTests() {
// Test cases with expected results
struct TestCase {
int input;
int expected;
} tests[] = {
{0, 1}, // Edge case: 0!
{1, 1}, // Edge case: 1!
{5, 120}, // Normal case: 5!
{10, 3628800} // Larger number
};
int numTests = sizeof(tests) / sizeof(tests[0]);
printf("Running %d test cases...\n", numTests);
// Iterate through test cases
for (int i = 0; i < numTests; i++) {
int result = calculateFactorial(tests[i].input);
// Assertion-style testing
if (result == tests[i].expected) {
printf("Test case %d PASSED: factorial(%d) = %d\n",
i+1, tests[i].input, result);
} else {
printf("Test case %d FAILED: Expected %d, Got %d\n",
i+1, tests[i].expected, result);
}
}
}
int main() {
// Run comprehensive test suite
runTests();
// Interactive testing mode
int number;
printf("\nEnter a number to calculate its factorial (or negative to exit): ");
while (scanf("%d", &number) == 1 && number >= 0) {
int result = calculateFactorial(number);
if (result!= -1) {
printf("Factorial of %d is: %d\n", number, result);
}
printf("\nEnter another number (or negative to exit): ");
}
return 0;
}
Скомпилируйте и запустите программу:
gcc factorial_test.c -o factorial_test
./factorial_test
Пример вывода будет выглядеть так:
Running 4 test cases...
DEBUG: Calculating factorial for 0
Test case 1 PASSED: factorial(0) = 1
DEBUG: Calculating factorial for 1
Test case 2 PASSED: factorial(1) = 1
DEBUG: Calculating factorial for 5
Test case 3 PASSED: factorial(5) = 120
DEBUG: Calculating factorial for 10
Test case 4 PASSED: factorial(10) = 3628800
Enter a number to calculate its factorial (or negative to exit):
Показанные ключевые методы отладки и тестирования:
- Вывод отладочной информации для отслеживания выполнения функций
- Комплексные тестовые случаи, охватывающие крайние ситуации
- Обработка ошибок для недопустимых входных данных
- Защита от переполнения
- Тестирование в стиле утверждений (assertion-style testing)
- Интерактивный режим тестирования
Советы по отладке:
- Используйте
printf()для логирования и отслеживания вызовов функций - Явно обрабатывайте крайние случаи
- Реализуйте валидацию входных данных
- Используйте
long longдля вычислений с большими числами - Создайте набор тестов для проверки различных сценариев
Резюме
В этом практическом занятии вы изучили основную синтаксис циклов for в программировании на языке C, которые являются важными для перебора элементов массивов и выполнения повторяющихся задач, таких как расчет факториалов. Вы также рассмотрели, как перебирать элементы массива, что является важным для реализации калькулятора факториалов.
Вы начали с создания простой программы на языке C для демонстрации базового синтаксиса цикла for, поняли части цикла: инициализацию, условие и инкремент/декремент. Затем вы научились перебирать массив целых чисел с использованием цикла for, обращаться к элементам массива и манипулировать ими.



