Параметры функции
Что такое параметры функции
Параметры — это переменные, через которые функция получает данные для работы. Они определяются в скобках при объявлении функции.
int add(int a, int b) { // a и b — параметры функции
return a + b;
}
Формальные и фактические параметры
Различие между параметрами и аргументами
- Определения
- Развернутый пример
#include <stdio.h>
int multiply(int x, int y) { // x, y — формальные параметры
return x * y;
}
int main() {
int result = multiply(5, 3); // 5, 3 — фактические аргументы
printf("Результат: %d\n", result);
return 0;
}
Термины:
- Формальные параметры — переменные в определении функции (
x,y) - Фактические аргументы — конкретные значения при вызове (
5,3)
#include <stdio.h>
void printStudentInfo(char *name, int age, float gpa) { // Формальные параметры
printf("=== ИНФОРМАЦИЯ О СТУДЕНТЕ ===\n");
printf("Имя: %s\n", name);
printf("Возраст: %d лет\n", age);
printf("Средний балл: %.2f\n", gpa);
}
int main() {
// Фактические аргументы при вызовах
printStudentInfo("Анна Иванова", 20, 4.5);
printStudentInfo("Петр Сидоров", 19, 3.8);
return 0;
}
Передача параметров по значению
Копирование значений
#include <stdio.h>
void modifyValue(int param) {
printf("В функции до изменения: param = %d\n", param);
param = 100; // Изменяем копию
printf("В функции после изменения: param = %d\n", param);
}
int main() {
int original = 42;
printf("До вызова функции: original = %d\n", original);
modifyValue(original); // Передаем копию значения
printf("После вызова функции: original = %d\n", original); // Не изменился!
return 0;
}
Независимость переменных
#include <stdio.h>
int doubleNumber(int num) {
num *= 2; // Изменяем локальную копию
printf("Внутри функции: %d\n", num);
return num;
}
int main() {
int value = 15;
printf("Исходное значение: %d\n", value);
int doubled = doubleNumber(value);
printf("Возвращенное значение: %d\n", doubled);
printf("Исходная переменная: %d\n", value); // Осталась 15
return 0;
}
Передача массивов как параметров
Массивы передаются по ссылке
- Массив как параметр
- Строки как параметры
#include <stdio.h>
void printArray(int arr[], int size) { // arr — указатель на первый элемент
printf("Элементы массива: ");
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
void modifyArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
arr[i] *= 2; // Изменяем исходный массив!
}
}
int main() {
int numbers[5] = {1, 2, 3, 4, 5};
printf("До изменения:\n");
printArray(numbers, 5);
modifyArray(numbers, 5);
printf("После изменения:\n");
printArray(numbers, 5); // Массив изменился!
return 0;
}
#include <stdio.h>
void analyzeString(char str[]) { // Эквивалентно char *str
int length = 0;
int vowels = 0;
while (str[length] != '\0') {
char ch = str[length];
if (ch == 'а' || ch == 'е' || ch == 'и' || ch == 'о' || ch == 'у' ||
ch == 'А' || ch == 'Е' || ch == 'И' || ch == 'О' || ch == 'У') {
vowels++;
}
length++;
}
printf("Строка: \"%s\"\n", str);
printf("Длина: %d символов\n", length);
printf("Гласных: %d\n", vowels);
}
int main() {
char text[] = "Программирование";
analyzeString(text);
return 0;
}
Различные типы параметров
Параметры разных типов
#include <stdio.h>
float calculateDiscount(float price, int discountPercent, char customerType) {
float discount = price * discountPercent / 100.0;
// Дополнительная скидка для особых клиентов
if (customerType == 'V') { // VIP клиент
discount += price * 0.05; // Дополнительные 5%
}
return discount;
}
void processOrder(int orderId, char *customerName, float totalAmount) {
printf("=== ЗАКАЗ #%d ===\n", orderId);
printf("Клиент: %s\n", customerName);
printf("Сумма: %.2f руб.\n", totalAmount);
if (totalAmount >= 1000) {
printf("🎁 Бесплатная доставка!\n");
}
}
int main() {
float originalPrice = 1500.0;
float discount = calculateDiscount(originalPrice, 15, 'V');
float finalPrice = originalPrice - discount;
processOrder(12345, "Анна Петрова", finalPrice);
printf("Скидка составила: %.2f руб.\n", discount);
return 0;
}
Передача указателей как параметров
Изменение переменных через указатели
#include <stdio.h>
void swapValues(int *a, int *b) { // Параметры — указатели
int temp = *a;
*a = *b;
*b = temp;
}
void updateBalance(float *balance, float amount, char operation) {
if (operation == '+') {
*balance += amount;
printf("Пополнение на %.2f\n", amount);
} else if (operation == '-') {
if (*balance >= amount) {
*balance -= amount;
printf("Списание %.2f\n", amount);
} else {
printf("Недостаточно средств\n");
}
}
}
int main() {
int x = 10, y = 20;
printf("До обмена: x = %d, y = %d\n", x, y);
swapValues(&x, &y); // Передаем адреса переменных
printf("После обмена: x = %d, y = %d\n", x, y);
float account = 1000.0;
printf("\nБаланс: %.2f\n", account);
updateBalance(&account, 250.0, '+');
printf("Новый баланс: %.2f\n", account);
updateBalance(&account, 500.0, '-');
printf("Итоговый баланс: %.2f\n", account);
return 0;
}
Константные параметры
Защита от изменений
- Основное использование
- Константные строки
#include <stdio.h>
void printArrayInfo(const int arr[], int size) { // const защищает массив
int sum = 0;
int max = arr[0];
for (int i = 0; i < size; i++) {
sum += arr[i];
if (arr[i] > max) {
max = arr[i];
}
// arr[i] = 0; // Ошибка компиляции! Нельзя изменить
}
printf("Сумма: %d\n", sum);
printf("Максимум: %d\n", max);
}
int main() {
int data[6] = {10, 25, 15, 30, 20, 35};
printArrayInfo(data, 6); // Функция не может испортить данные
printf("Массив остался неизменным: ");
for (int i = 0; i < 6; i++) {
printf("%d ", data[i]);
}
printf("\n");
return 0;
}
#include <stdio.h>
int countWords(const char *text) { // Защищаем строку от изменений
int words = 0;
int inWord = 0;
while (*text != '\0') {
if (*text != ' ' && !inWord) {
words++;
inWord = 1;
} else if (*text == ' ') {
inWord = 0;
}
text++;
// *text = 'X'; // Ошибка! Нельзя изменить константную строку
}
return words;
}
int main() {
char sentence[] = "Изучаем параметры функций в языке Си";
int wordCount = countWords(sentence);
printf("Предложение: \"%s\"\n", sentence);
printf("Количество слов: %d\n", wordCount);
return 0;
}
Функции с переменным числом параметров
Перегрузка через разные имена
#include <stdio.h>
int add2(int a, int b) {
return a + b;
}
int add3(int a, int b, int c) {
return a + b + c;
}
int add4(int a, int b, int c, int d) {
return a + b + c + d;
}
int main() {
printf("2 числа: %d\n", add2(10, 20));
printf("3 числа: %d\n", add3(10, 20, 30));
printf("4 числа: %d\n", add4(10, 20, 30, 40));
return 0;
}
Частые ошибки с параметрами
Типичные проблемы
// ❌ Неправильные типы параметров
void printAge(int age) {
printf("Возраст: %d\n", age);
}
int main() {
float userAge = 25.5;
printAge(userAge); // Потеря дробной части!
return 0;
}
// ❌ Попытка изменить параметр-значение
void tryToDouble(int num) {
num *= 2; // Изменяется только копия!
}
// ❌ Забыть размер массива
void processArray(int arr[]) { // Размер неизвестен!
// for (int i = 0; i < ???; i++) // Как узнать размер?
}
// ✅ Правильно - передаем размер отдельно
void processArrayCorrect(int arr[], int size) {
for (int i = 0; i < size; i++) {
// обработка элементов
}
}
Важные правила
- Простые типы (int, float, char) передаются по значению (копируются)
- Массивы и строки передаются по ссылке (передается адрес)
- Изменение параметра-значения не влияет на исходную переменную
- Для изменения переменной передавайте её адрес (указатель)
- Всегда передавайте размер массива отдельным параметром
Рекомендации
- Используйте
constдля параметров, которые не должны изменяться - Давайте параметрам понятные имена:
calculateTax(float income)вместоcalculateTax(float x) - Проверяйте корректность переданных значений внутри функции
- Группируйте связанные параметры логически
Параметры функций — механизм передачи данных между разными частями программы, ключевой элемент модульного программирования.