Введение
В этом лабораторном занятии вы научитесь реализовывать условные циклы в программировании на языке C. Вы начнете с понимания основ циклов while, а затем изучите использование директив break и continue для управления выполнением циклов. Кроме того, вы научитесь фильтровать элементы массива с использованием условных операторов и оптимизировать эффективность циклов различными директивами. К концу этого лабораторного занятия вы будете иметь твердое понимание условных циклов и их практических применений в программировании на языке C.
Понять циклы while
На этом этапе вы узнаете основы циклов while в программировании на языке C. Циклы while — это мощные управляющие структуры, которые позволяют повторять блок кода, пока определенное условие остается истинным.
Создадим простую программу на языке C, чтобы продемонстрировать базовый синтаксис цикла while. Откройте редактор VSCode и создайте новый файл с именем while_loop_example.c в директории ~/project.
cd ~/project
touch while_loop_example.c
#include <stdio.h>
int main() {
int count = 1;
while (count <= 5) {
printf("Current count: %d\n", count);
count++;
}
return 0;
}
Разберем код на части:
int count = 1;инициализирует переменную-счетчик.while (count <= 5)создает цикл, который продолжается, пока значениеcountменьше или равно 5.printf()выводит текущее значениеcount.count++увеличивает счетчик на каждой итерации.
Скомпилируйте и запустите программу:
gcc while_loop_example.c -o while_loop_example
./while_loop_example
Пример вывода:
Current count: 1
Current count: 2
Current count: 3
Current count: 4
Current count: 5
Вот еще один пример, демонстрирующий цикл while с вводом данных от пользователя:
#include <stdio.h>
int main() {
int number;
printf("Enter numbers (enter 0 to stop):\n");
number = 1; // Initialize to non-zero value
while (number!= 0) {
printf("Enter a number: ");
scanf("%d", &number);
if (number!= 0) {
printf("You entered: %d\n", number);
}
}
printf("Loop ended. Goodbye!\n");
return 0;
}
В этом примере показано, как циклы while можно использовать для интерактивного ввода данных, продолжая выполнение до тех пор, пока не будет выполнено определенное условие (ввод 0).
Применить директиву break в циклах while
На этом этапе вы узнаете о директиве break в программировании на языке C, которая позволяет досрочно выйти из цикла, когда выполняется определенное условие. Оператор break предоставляет способ немедленно завершить текущий цикл и продолжить выполнение программы с оператора, следующего за циклом.
Создадим новый файл с именем break_loop_example.c в директории ~/project, чтобы продемонстрировать использование директивы break:
cd ~/project
touch break_loop_example.c
#include <stdio.h>
int main() {
int number;
printf("Enter numbers to find the first multiple of 10:\n");
while (1) { // Infinite loop
printf("Enter a number: ");
scanf("%d", &number);
if (number % 10 == 0) {
printf("Found a multiple of 10: %d\n", number);
break; // Exit the loop when a multiple of 10 is found
}
printf("Not a multiple of 10. Try again.\n");
}
printf("Loop terminated after finding a multiple of 10.\n");
return 0;
}
Разберем код на части:
while (1)создает бесконечный цикл, который будет продолжаться до тех пор, пока не встретится операторbreak.- Когда пользователь вводит число, делящееся на 10, оператор
breakнемедленно завершает цикл. - Если число не делится на 10, цикл продолжает запрашивать ввод.
Вот еще один пример, демонстрирующий использование break в более сложной ситуации:
#include <stdio.h>
int main() {
int sum = 0;
int count = 0;
int input;
printf("Enter numbers (enter a negative number to stop):\n");
while (1) {
printf("Enter a number: ");
scanf("%d", &input);
if (input < 0) {
break; // Exit the loop if a negative number is entered
}
sum += input;
count++;
}
if (count > 0) {
printf("Average of entered numbers: %.2f\n", (float)sum / count);
} else {
printf("No numbers were entered.\n");
}
return 0;
}
В этом примере показано, как можно использовать директиву break для:
- Прекращения сбора ввода, когда выполняется определенное условие.
- Вычисления среднего значения введенных чисел.
- Предоставления гибкости при завершении цикла.
Скомпилируйте и запустите программы, чтобы увидеть, как работает директива break:
gcc break_loop_example.c -o break_loop_example
./break_loop_example
Использовать директиву continue в циклах while
На этом этапе вы узнаете о директиве continue в программировании на языке C, которая позволяет пропустить текущую итерацию цикла и перейти к следующей. Оператор continue предоставляет способ выборочно выполнять или пропускать части цикла на основе определенных условий.
Создадим новый файл с именем continue_loop_example.c в директории ~/project, чтобы продемонстрировать использование директивы continue:
cd ~/project
touch continue_loop_example.c
#include <stdio.h>
int main() {
int number;
int sum_even = 0;
int count_even = 0;
printf("Enter 10 numbers to calculate the sum and count of even numbers:\n");
int i = 0;
while (i < 10) {
printf("Enter number %d: ", i + 1);
scanf("%d", &number);
// Skip odd numbers
if (number % 2!= 0) {
printf("Skipping odd number: %d\n", number);
continue; // Move to the next iteration
}
sum_even += number;
count_even++;
i++;
}
if (count_even > 0) {
printf("Sum of even numbers: %d\n", sum_even);
printf("Count of even numbers: %d\n", count_even);
printf("Average of even numbers: %.2f\n", (float)sum_even / count_even);
} else {
printf("No even numbers were entered.\n");
}
return 0;
}
Разберем код на части:
- Программа запрашивает у пользователя ввод 10 чисел.
if (number % 2!= 0)проверяет, является ли число нечетным.continueпропускает остаток текущей итерации для нечетных чисел.- Только четные числа суммируются и подсчитываются.
Вот еще один пример, демонстрирующий использование continue с более сложными условиями:
#include <stdio.h>
int main() {
int number;
int positive_count = 0;
int negative_count = 0;
printf("Enter numbers (enter 0 to stop):\n");
while (1) {
printf("Enter a number: ");
scanf("%d", &number);
// Exit the loop if 0 is entered
if (number == 0) {
break;
}
// Skip zero
if (number == 0) {
continue;
}
// Count positive and negative numbers
if (number > 0) {
positive_count++;
} else {
negative_count++;
}
}
printf("Positive numbers count: %d\n", positive_count);
printf("Negative numbers count: %d\n", negative_count);
return 0;
}
В этом примере показано, как можно использовать директиву continue для:
- Пропуска определенных значений.
- Выборочной обработки чисел на основе условий.
- Предоставления более гибкого управления циклом.
Скомпилируйте и запустите программы, чтобы увидеть, как работает директива continue:
gcc continue_loop_example.c -o continue_loop_example
./continue_loop_example
Фильтрация элементов массива с использованием условных операторов
На этом этапе вы узнаете, как фильтровать элементы массива с использованием условных операторов и циклов в программировании на языке C. Фильтрация позволяет выбирать определенные элементы из массива на основе определенных условий.
Создадим новый файл с именем array_filtering.c в директории ~/project, чтобы продемонстрировать фильтрацию элементов массива:
cd ~/project
touch array_filtering.c
#include <stdio.h>
#define MAX_SIZE 10
int main() {
int numbers[MAX_SIZE];
int filtered_even[MAX_SIZE];
int filtered_count = 0;
// Input array elements
printf("Enter %d numbers:\n", MAX_SIZE);
for (int i = 0; i < MAX_SIZE; i++) {
printf("Enter number %d: ", i + 1);
scanf("%d", &numbers[i]);
}
// Filter even numbers
printf("\nFiltered Even Numbers:\n");
for (int i = 0; i < MAX_SIZE; i++) {
if (numbers[i] % 2 == 0) {
filtered_even[filtered_count] = numbers[i];
filtered_count++;
printf("%d ", numbers[i]);
}
}
printf("\n\nTotal even numbers: %d\n", filtered_count);
return 0;
}
Разберем процесс фильтрации:
- Мы создаем два массива:
numbersдля хранения введенных данных иfiltered_evenдля хранения отфильтрованных элементов. - Первый цикл считывает 10 чисел от пользователя.
- Второй цикл использует условный оператор для фильтрации четных чисел.
if (numbers[i] % 2 == 0)проверяет, является ли число четным.- Соответствующие элементы сохраняются в массиве
filtered_even.
Вот более сложный пример с несколькими условиями фильтрации:
#include <stdio.h>
#define MAX_SIZE 10
int main() {
int numbers[MAX_SIZE];
int prime_numbers[MAX_SIZE];
int prime_count = 0;
// Input array elements
printf("Enter %d numbers:\n", MAX_SIZE);
for (int i = 0; i < MAX_SIZE; i++) {
printf("Enter number %d: ", i + 1);
scanf("%d", &numbers[i]);
}
// Filter prime numbers
printf("\nFiltered Prime Numbers:\n");
for (int i = 0; i < MAX_SIZE; i++) {
// Skip numbers less than 2
if (numbers[i] < 2) continue;
int is_prime = 1;
for (int j = 2; j * j <= numbers[i]; j++) {
if (numbers[i] % j == 0) {
is_prime = 0;
break;
}
}
// Add prime numbers to filtered array
if (is_prime) {
prime_numbers[prime_count] = numbers[i];
prime_count++;
printf("%d ", numbers[i]);
}
}
printf("\n\nTotal prime numbers: %d\n", prime_count);
return 0;
}
В этом примере показано:
- Фильтрация простых чисел из входного массива.
- Использование вложенных циклов для проверки простоты числа.
- Сохранение отфильтрованных элементов в отдельном массиве.
Скомпилируйте и запустите программы:
gcc array_filtering.c -o array_filtering
./array_filtering
Пример ввода и вывода:
Enter 10 numbers:
Enter number 1: 5
Enter number 2: 12
Enter number 3: 7
Enter number 4: 15
...
Filtered Prime Numbers:
5 7
Total prime numbers: 2
Оптимизировать эффективность циклов с использованием директив
На этом этапе вы узнаете техники по оптимизации эффективности циклов в программировании на языке C с использованием различных директив и стратегий. Мы рассмотрим различные подходы для улучшения производительности и читаемости циклов.
Создадим файл с именем loop_optimization.c в директории ~/project, чтобы продемонстрировать техники оптимизации:
cd ~/project
touch loop_optimization.c
#include <stdio.h>
#include <time.h>
#define ARRAY_SIZE 10000
// Function to calculate sum using traditional loop
int traditional_sum(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
// Function to calculate sum using optimized loop
int optimized_sum(int arr[], int size) {
int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
// Loop unrolling technique
int i;
for (i = 0; i + 4 < size; i += 4) {
sum1 += arr[i];
sum2 += arr[i + 1];
sum3 += arr[i + 2];
sum4 += arr[i + 3];
}
// Handle remaining elements
for (; i < size; i++) {
sum1 += arr[i];
}
return sum1 + sum2 + sum3 + sum4;
}
int main() {
int arr[ARRAY_SIZE];
clock_t start, end;
double cpu_time_used;
// Initialize array
for (int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = i + 1;
}
// Traditional sum
start = clock();
int traditional_result = traditional_sum(arr, ARRAY_SIZE);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("Traditional Sum: %d\n", traditional_result);
printf("Traditional Loop Time: %f seconds\n", cpu_time_used);
// Optimized sum
start = clock();
int optimized_result = optimized_sum(arr, ARRAY_SIZE);
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
printf("Optimized Sum: %d\n", optimized_result);
printf("Optimized Loop Time: %f seconds\n", cpu_time_used);
return 0;
}
Вот еще один пример, демонстрирующий несколько техник оптимизации:
#include <stdio.h>
#define MAX_SIZE 1000
int main() {
int numbers[MAX_SIZE];
int even_sum = 0, odd_sum = 0;
// Efficient initialization and summation
for (int i = 0; i < MAX_SIZE; i++) {
numbers[i] = i + 1;
// Conditional sum with minimal branching
even_sum += (numbers[i] % 2 == 0) * numbers[i];
odd_sum += (numbers[i] % 2!= 0) * numbers[i];
}
printf("Sum of Even Numbers: %d\n", even_sum);
printf("Sum of Odd Numbers: %d\n", odd_sum);
return 0;
}
Основные демонстрируемые техники оптимизации:
- Развертывание цикла (loop unrolling) для уменьшения накладных расходов цикла.
- Минимизация предсказаний ветвлений.
- Комбинирование инициализации и обработки.
- Использование умножения для условного суммирования.
Скомпилируйте и запустите программы с флагами оптимизации:
## Compile with basic optimization
gcc -O2 loop_optimization.c -o loop_optimization
./loop_optimization
## Compile with advanced optimization
gcc -O3 loop_optimization.c -o loop_optimization
./loop_optimization
Дополнительные советы по оптимизации:
- Используйте флаги компилятора
-O2или-O3. - Минимизируйте вызовы функций внутри циклов.
- Используйте подходящие типы данных.
- Избегайте ненужных вычислений.
- Рассмотрите возможность перемещения инвариантного кода цикла.
Резюме
В этом практическом занятии вы узнаете основы циклов while в программировании на языке C, в том числе, как использовать директивы break и continue для управления потоком выполнения цикла. Вы также изучите техники фильтрации элементов массива с использованием условных операторов и оптимизации эффективности циклов с помощью различных директив. К концу этого практического занятия вы получите твердую базу знаний о том, как реализовывать условные циклы на языке C для решения различных задач программирования.



