Гид по технологиям

Учимся программировать на C: «Hello, World!» и основные принципы

8 min read Программирование Обновлено 30 Dec 2025
Учимся C: Hello World и основы
Учимся C: Hello World и основы

Человек за компьютером изучает программирование на языке C

Постепенное изучение программирования включает в себя не только синтаксис выбранного языка, но и общие принципы, которые присутствуют во многих языках. Понять C полезно: он прост по синтаксису, но строг по безопасности и управлению памятью, что формирует хорошие привычки.

Ниже — пошаговая работа с минимальным проектом. Лучшее место для старта — сказать компьютеру «привет».

1. Hello, World!

Практически в каждом учебном курсе по программированию первым идёт пример «Hello, World!». Разбор этого примера показывает, чем C отличается от других языков. Откройте любой текстовый редактор или IDE и введите такой код:

#include 
/* this is a Hello World script in C */

int main(void)
{
    printf("Hello, World! \n");
    return 0;
}

Сохраните файл как hello.c. Этот фрагмент выводит строку в консоль, после чего программа завершается. Чтобы увидеть результат, нужно скомпилировать и запустить файл.

Как запустить

Обычно не требуется устанавливать дополнительное ПО: на Linux и macOS компилятор gcc часто доступен, на Windows можно использовать Visual Studio (cl) или MinGW / MSYS2 с gcc.

  • Windows (Visual Studio): откройте Developer Command Prompt и выполните cl hello.c — появится hello.exe, запустите его командой hello.
  • Windows (MinGW): в MSYS2/MinGW используйте gcc -o hello hello.c и запустите ./hello или просто hello.exe.
  • Linux/macOS: gcc -o hello hello.c и ./hello.

После запуска вы должны увидеть:

Вывод программы Hello, World! в консоли

Если что-то пошло не так: на Windows — запуск от администратора не обязателен, но убедитесь, что используете правильную среду сборки; на macOS, если отсутствует компилятор, установите Xcode Command Line Tools или Xcode.

Теперь разберём программу построчно и улучшим её.

Под капотом: элементы программы на C

Препроцессор

Первая строка файла — директива препроцессора:

#include 

Препроцессор выполняется до компиляции и подставляет содержимое заголовочных файлов. stdio.h — заголовок стандартной библиотеки ввода-вывода. В нём определены функции printf, scanf, puts и другие.

Комментарий в коде выглядит так:

/* this is a Hello World script in C */

Компилятор игнорирует всё между / и /. Комментарии помогают документировать код.

Функция main

int main(void)
{
    printf("Hello, World! \n");
    return 0;
}

Каждая программа на C имеет функцию main — точку входа. main возвращает целое число (int). Аргументы в скобках — параметры функции; void означает, что аргументов нет.

printf — функция из stdio.h, которая печатает форматированную строку в стандартный вывод. Последовательность \n означает переход на новую строку. Каждое выражение в C обычно завершается точкой с запятой ; — её пропуск вызывает синтаксические ошибки.

return 0; сообщает операционной системе, что программа завершилась успешно.

2. Создание собственных функций

Функции позволяют выделять повторяющийся код в одно место.

void print_for_me()
{
    printf("Hello, World! \n");
}

Ключевое слово void означает, что функция ничего не возвращает. Имя функции — print_for_me, пустые скобки означают отсутствие аргументов. Вызов функции из main:

int main(void)
{
    print_for_me();
    print_for_me();
    return 0;
}

Преимущество — вы пишете логику один раз и используете её многократно.

Вывод Hello World дважды через вызов пользовательской функции

3. Прототипы функций в C

В C часто объявляют прототипы функций до их определения. Прототип сообщает компилятору, какие аргументы и типы возвращаемого значения у функции.

Если вы определяете функцию после main, без прототипа компилятор может выдать предупреждение.

#include 

void print_for_me();

int main(void)
{
    print_for_me();
    print_for_me();
    return 0;
}

void print_for_me()
{
    printf("Hello, World! \n");
}

Прототип полезен: компилятор проверит соответствие вызовов функции объявлению.

4. Передача аргументов в функции — работа со строками

Как изменять скрипт

В C строка — это массив символов (char array). Объявим прототип с аргументом:

#include 

void print_for_me(char name[]);

В main создадим буфер для имени, запросим ввод и передадим его в функцию:

int main(void)
{
    char name[20];
    printf("Enter name: ");
    scanf("%19s", name);

    print_for_me(name);
    print_for_me("Everyone!");
    return 0;
}

Важно: в scanf лучше указывать максимальную ширину %19s, чтобы избежать переполнения буфера (одно место оставляем для нуль-терминатора ‘\0’).

Модификация функции

void print_for_me(char name[])
{
    printf("Hello, ");
    puts(name);
}

puts печатает строку и автоматически добавляет перевод строки.

Скомпилируйте и запустите, вы увидите, что введённое имя используется при вызове функции, а затем функция вызывается со значением “Everyone!”.

Завершённая программа на C с вводом имени

Практические советы и распространённые ошибки

  • Никогда не доверяйте вводу пользователя — всегда контролируйте длину строк.
  • scanf с %s читает до первого пробела. Для чтения строк с пробелами используйте fgets.
  • Не забывайте оставлять место для терминатора ‘\0’.
  • Проверяйте возвращаемые значения функций ввода/вывода.
  • Используйте опции компилятора для выявления ошибок: -Wall -Wextra -pedantic -std=c11.

Пример с fgets (безопаснее для строк с пробелами)

#include 
#include 

void print_for_me(char name[]);

int main(void)
{
    char name[100];
    printf("Enter name: ");
    if (fgets(name, sizeof(name), stdin) != NULL) {
        name[strcspn(name, "\n")] = '\0'; // удаляем символ новой строки
    }
    print_for_me(name);
    return 0;
}

void print_for_me(char name[])
{
    printf("Hello, %s\n", name);
}

fgets защищает от переполнения, но включает символ новой строки — его часто нужно удалить.

Безопасность: буферные переполнения и уязвимости

C даёт прямой доступ к памяти. Неправильная работа со строками и буферами приводит к аварийным завершениям и уязвимостям (например, переполнение буфера на стеке). Практические рекомендации:

  • Избегайте небезопасных функций strcpy и strcat; используйте strncpy/strncat или безопасные аналоги, но помните об их нюансах.
  • Предпочитайте snprintf вместо sprintf.
  • Всегда проверяйте границы буферов.
  • Включайте ASLR/DEP на платформе и используйте современные компиляторные защиты (например, -fstack-protector-strong).

Важно: strncpy не всегда добавляет ‘\0’ — проверяйте результат.

Инструменты отладки и компиляции

  • Компилятор: gcc, clang, cl (Visual Studio).
  • Включите предупреждения: -Wall -Wextra.
  • Используйте -g для отладочной информации и gdb или lldb для анализа.
  • Valgrind или Sanitizers (ASan, UBSan) помогут найти утечки памяти и неопределённое поведение.

Пример команд:

  • gcc -std=c11 -Wall -Wextra -O0 -g -o hello hello.c
  • gcc -std=c11 -Wall -Wextra -O2 -o hello hello.c
  • Для sanitizers: gcc -fsanitize=address,undefined -g -O1 -o hello hello.c

Makefile: простая автоматизация сборки

CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -g
TARGET = hello
SRC = hello.c

all: $(TARGET)

$(TARGET): $(SRC)
    $(CC) $(CFLAGS) -o $(TARGET) $(SRC)

clean:
    rm -f $(TARGET)

Makefile упрощает сборку и добавляет единый интерфейс команд для проекта.

Расширения: аргументы командной строки и возврат кода

main может принимать аргументы: int main(int argc, char *argv[]). argc — количество аргументов, argv — массив строк. Так программа может принимать параметры при запуске.

Возврат из main: возвращаемое значение информирует вызывающую среду о статусе: 0 обычно означает успех, любое ненулевое значение — ошибку.

Советы по обучению и лучшие практики

  • Пишите маленькими шагами и часто компилируйте.
  • Читайте предупреждения компилятора и исправляйте их, не игнорируйте.
  • Комментируйте нестандартное поведение кода.
  • Пишите тесты на примерах ввода/вывода.
  • Используйте контроль версий (git) даже в учебных проектах.

Когда C не подходит (контрпримеры)

  • Для быстрого прототипирования с богатой стандартной библиотекой и минимальным управлением памятью лучше подходят Python или JavaScript.
  • Для безопасного низкоуровневого кодирования с современными гарантиями памяти рассмотрите Rust.
  • Для проектов с интенсивной объектно-ориентированной архитектурой и многими библиотеками удобнее C++.

Сравнение с популярными альтернативами (кратко)

  • Python: выше уровень абстракции, удобнее ввод-вывода, но меньше контроля над памятью.
  • C++: расширение C с объектно-ориентированными возможностями и стандартной библиотекой.
  • Rust: современная альтернатива с безопасностью на этапе компиляции.

Чек-листы (роли)

Студент:

  • Скомпилировал и запустил hello.c.
  • Понял каждую строку программы.
  • Написал функцию и вызвал её несколько раз.
  • Добавил ввод имени и защитил буфер.

Преподаватель:

  • Подготовил примеры с fgets и scanf.
  • Показал использование компилятора с флагами предупреждений.
  • Дал задание на обработку ошибок ввода.

Инженер сборки:

  • Подготовил Makefile.
  • Включил статические и динамические проверки.
  • Настроил CI с анализаторами и sanitizers.

Критерии приёмки

  • Программа компилируется без ошибок.
  • Сообщений об опасных операциях (без указания предупреждений) не осталось.
  • Ввод пользователя ограничен безопасным размером буфера.
  • Тестовые случаи с пустой строкой и длинной строкой обрабатываются корректно.

Тестовые примеры и сценарии проверки

  • Ввод: “Alice” → вывод: “Hello, Alice”.
  • Ввод: пустая строка (нажать Enter) → либо пустой вывод, либо обработка как “(empty)” в зависимости от задания.
  • Ввод длинной строки (>буфер) → не должно происходить переполнения; fgets должна обрезать ввод.

Мини‑методология: как разрабатывать учебную программу на C

  1. Определите минимальный рабочий пример.
  2. Добавьте ввод/вывод и проверку ошибок.
  3. Добавьте модульные функции и прототипы.
  4. Защитите ввод и проверяйте границы.
  5. Напишите тесты и автоматизируйте сборку.

Факты и заметки

  • puts — удобна для простого вывода строк: она автоматически добавляет новую строку.
  • printf поддерживает форматирование; используйте %s для строк, %d для целых чисел.
  • Функции работы со строками из string.h часто являются источником ошибок, поэтому применяйте их осторожно.

Быстрый справочник (cheat sheet)

  • Компиляция: gcc -std=c11 -Wall -Wextra -O2 -o prog prog.c
  • Отладка: gcc -g -O0 -o prog prog.c; затем gdb ./prog
  • Проверка сегментаций: gcc -fsanitize=address,undefined -g -O1 -o prog prog.c
  • Безопасный ввод: fgets(buf, sizeof(buf), stdin); buf[strcspn(buf, “\n”)]=’\0’;

Decision flowchart: scanf или fgets?

flowchart TD
    A[Нужно читать строку от пользователя?] --> B{В строке будут пробелы?}
    B -- Да --> C[fgets]
    B -- Нет --> D[Можно scanf с шириной %Ns]
    C --> E[Удалить '\n' и обработать]
    D --> E
    E --> F[Проверить границы буфера]

Глоссарий (1‑строчные определения)

  • Препроцессор: шаг перед компиляцией, который вставляет заголовки и макросы.
  • Прототип функции: объявление функции с типами аргументов и возвращаемого значения.
  • Буфер: область памяти для временного хранения данных.
  • Переполнение буфера: запись за пределы выделенной области памяти.

Короткое резюме

Этот материал показал: как написать и запустить простую программу на C, как выделять повторы в функции, зачем нужны прототипы, как безопасно читать ввод пользователя и какие инструменты использовать для отладки и защиты. C — отличный язык для формирования понимания работы памяти и компиляции.

ВАЖНО: проверяйте ввод, используйте безопасные функции и компиляторные флаги, и постепенно усложняйте примеры по мере роста навыков.

Дополнительные материалы и предложения по практике:

  • Попробуйте расширить программу: принимайте аргументы командной строки и выводите приветствие несколько раз.
  • Напишите тесты, которые автоматизируют проверки для длинной строки и пустой строки.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Отслеживание резолюций в Google Календаре
Продуктивность

Отслеживание резолюций в Google Календаре

Как учить язык с Kindle Paperwhite
Обучение

Как учить язык с Kindle Paperwhite

Прозрачная панель задач Windows — как сделать
Windows

Прозрачная панель задач Windows — как сделать

Как продать технику на Craigslist безопасно
Продажа техники

Как продать технику на Craigslist безопасно

Как очистить историю поиска в Facebook
Приватность

Как очистить историю поиска в Facebook

Умный дом: как гаджеты помогают спать лучше
Здоровье

Умный дом: как гаджеты помогают спать лучше